This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eryksun
Recipients eryksun, paul.moore, phbarnacle, steve.dower, tim.golden, zach.ware
Date 2015-08-05.11:54:59
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1438775712.8.0.874737364394.issue24793@psf.upfronthosting.co.za>
In-reply-to
Content
Popen calls Windows [CreateProcess][1]. If the Popen "executable" argument isn't used or if the file from the command line doesn't include a directory path, then CreateProcess searches for it in the following directories:

    1. The directory from which the application loaded.
    2. The current directory for the parent process.
       * This step is skipped if the parent defines
         %NoDefaultCurrentDirectoryInExePath%.
    3. The 32-bit Windows system directory.
    4. The 16-bit Windows system directory. 
    5. The Windows directory. 
    6. The directories that are listed in the PATH 
       environment variable. 

Also note that the PATH searched is that of the *parent* process; the "env" parameter doesn't affect this. 

Call the SearchPath function if you need a custom search for the fully qualified path. 

    import ctypes
    from ctypes import wintypes

    kernel32 = ctypes.WinDLL('kernel32')

    kernel32.SearchPathW.argtypes = (
        wintypes.LPCWSTR,                   # _In_opt_  lpPath
        wintypes.LPCWSTR,                   # _In_      lpFileName
        wintypes.LPCWSTR,                   # _In_opt_  lpExtension
        wintypes.DWORD,                     # _In_      nBufferLength
        wintypes.LPWSTR,                    # _Out_     lpBuffer
        ctypes.POINTER(wintypes.LPWSTR))    # _Out_opt_ lpFilePart
                                            
    def search_path(filename, path=None, ext='.exe'):
        length, new_length = 0, 260
        while new_length > length:
            length = new_length
            filepath = (ctypes.c_wchar * length)()
            new_length = kernel32.SearchPathW(path, filename, ext,
                                              length, filepath, None)
        return filepath.value

For example:

    >>> search_path('python')
    u'C:\\Program Files\\Python27\\python.exe'
    >>> import os            
    >>> search_path('python', os.environ['PATH'])
    u''

    >>> search_path('more.com', os.environ['PATH'])
    u'C:\\Windows\\System32\\more.com'
    >>> search_path('more', ext='.com')            
    u'C:\\Windows\\system32\\more.com'

[1]: https://msdn.microsoft.com/en-us/library/ms682425
History
Date User Action Args
2015-08-05 11:55:15eryksunsetrecipients: + eryksun, paul.moore, tim.golden, zach.ware, steve.dower, phbarnacle
2015-08-05 11:55:12eryksunsetmessageid: <1438775712.8.0.874737364394.issue24793@psf.upfronthosting.co.za>
2015-08-05 11:55:12eryksunlinkissue24793 messages
2015-08-05 11:55:00eryksuncreate