Author eryksun
Recipients Anthony Sottile, RubyTuesdayDONO, brian.curtin, dabrahams, docs@python, eryksun, mark, r.david.murray
Date 2016-03-25.04:43:23
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
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
    * 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

    >>>'python -Sc "import sys; print(sys.prefix)"')
    Breakpoint 0 hit
    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

    >>> os.environ['NoDefaultCurrentDirectoryInExePath'] = '1'

    >>>'python -Sc "import sys; print(sys.prefix)"')
    Breakpoint 0 hit
    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

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. 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]. 

[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:26eryksunsetrecipients: + eryksun, mark, r.david.murray, brian.curtin, docs@python, dabrahams, RubyTuesdayDONO, Anthony Sottile
2016-03-25 04:43:25eryksunsetmessageid: <>
2016-03-25 04:43:25eryksunlinkissue8557 messages
2016-03-25 04:43:23eryksuncreate