Message262399
As is documented for CreateProcess [1], the search path always includes the following directories:
* The directory from which the application loaded.
* The current directory for the parent process.
* The Windows system directory. Use the
GetSystemDirectory function to get the path of
this directory.
* The 16-bit Windows system directory. There is no
function that obtains the path of this directory,
but it is searched. The name of this directory is
System.
* The Windows directory. Use the GetWindowsDirectory
function to get the path of this directory.
* The directories that are listed in the PATH
environment variable.
The value of PATH comes from the calling process environment, not from the environment passed in the lpEnvironment parameter. If you need to search some other list of paths, you can use shutil.which to find the fully qualified path of the target executable.
Note that in Vista+ you can remove the current directory from the search list by defining the environment variable "NoDefaultCurrentDirectoryInExePath" [2].
The following examples show the minimum search path that CreateProcess uses when PATH isn't defined.
>>> 'PATH' in os.environ
False
>>> subprocess.call('python -Sc "import sys; print(sys.prefix)"')
Breakpoint 0 hit
KERNELBASE!SearchPathW:
00007ff9`cf4b5860 488bc4 mov rax,rsp
0:000> du @rcx
0000006c`a7074410 "C:\Program Files\Python35;.;C:\W"
0000006c`a7074450 "indows\SYSTEM32\;C:\Windows\syst"
0000006c`a7074490 "em;C:\Windows"
0:000> g
C:\Program Files\Python35
0
>>> os.environ['NoDefaultCurrentDirectoryInExePath'] = '1'
>>> subprocess.call('python -Sc "import sys; print(sys.prefix)"')
Breakpoint 0 hit
KERNELBASE!SearchPathW:
00007ff9`cf4b5860 488bc4 mov rax,rsp
0:000> du @rcx
0000006c`a6560710 "C:\Program Files\Python35;C:\Win"
0000006c`a6560750 "dows\SYSTEM32\;C:\Windows\system"
0000006c`a6560790 ";C:\Windows"
0:000> g
C:\Program Files\Python35
0
Note that in the 2nd case the current directory ('.') is no longer present between the application directory ("C:\Program Files\Python35") and the system directory ("C:\Windows\SYSTEM32\").
CreateProcess executes PE executables and batch files (run via the %ComSpec% interpreter). It automatically appends the .exe extension when searching for an executable. It does this via the lpExtension parameter of SearchPath [3].
Some .com files are PE executables (e.g. chcp.com). Otherwise it's not really usefully to loop over the PATHEXT extensions unless you're using shell=True, since most are filetypes that CreateProcess doesn't support [4].
[1]: https://msdn.microsoft.com/en-us/library/ms682425
[2]: https://msdn.microsoft.com/en-us/library/ms684269
[3]: https://msdn.microsoft.com/en-us/library/aa365527
[4]: If Microsoft's Windows team cared at all about cross-platform
idioms they'd add shebang support to CreateProcess, which
would make all scripts, not just batch files, directly
executable without requiring ShellExecuteEx and registered
filetypes. ShellExecuteEx doesn't support a lot of useful
creation flags that are only available by calling
CreateProcess directly, and it also doesn't check ACLs to
prevent executing a file. So scripts are second class
citizens in Windows, which is why Python has to embed
scripts in .exe wrappers. |
|
Date |
User |
Action |
Args |
2016-03-25 04:43:26 | eryksun | set | recipients:
+ eryksun, mark, r.david.murray, brian.curtin, docs@python, dabrahams, RubyTuesdayDONO, Anthony Sottile |
2016-03-25 04:43:25 | eryksun | set | messageid: <1458881005.98.0.961092238191.issue8557@psf.upfronthosting.co.za> |
2016-03-25 04:43:25 | eryksun | link | issue8557 messages |
2016-03-25 04:43:23 | eryksun | create | |
|