2011-04-25 115 views
4

根據文檔,CreateProcess可以傳遞一個可執行文件名稱 作爲第一個參數,或命令行作爲第二個參數(從中提取可執行文件名稱 )。CreateProcess如何找到可執行文件?

如果您傳遞一個可執行文件的名稱,文檔說PATH將不會被搜索。

如果您傳遞命令行,而第一個標記被提取爲 作爲可執行文件名,PATH應被搜索。

在我的情況下,雖然我的電話號碼是CreateProcess ---只帶有一個命令行,而 帶有一個修改過的環境---沒有找到所需的可執行文件。它只有 成功,如果我在命令行前cmd.exe /c(我明白爲什麼 它這樣工作)。

爲了完整起見,我實際上並沒有直接使用Windows API,但在Python subprocess.Popen,但我想我已經縮小的問題 上述情況。用shell = True,正確的環境是 拿起;與shell = False(我想要的方式創建子進程), 該調用未能找到我的可執行文件。該可執行文件是一個獨立的exe文件,而不是cmd.exe的內部命令。

有人可以告訴我我在做什麼錯在這裏或我的誤解在哪裏?

示例代碼:

from subprocess import Popen 
import os, sys 

exe = "wc.exe" # No other wc.exe on the PATH 
env = os.environ.copy() 
new_path = os.path.expandvars(r"%HOMEDRIVE%%HOMEPATH%\SmallApps\GnuWin32\bin;%PATH%") 
env["PATH"] = os.path.expandvars(new_path).encode(sys.getfilesystemencoding()) 

Popen(
    args=[exe, "*.*"], 
    env=env, 
    # shell=True # Works if you uncomment this line. 
) 
+0

由於CreateProcess和cmd/c對傳遞給它們的特定字節都非常敏感,所以如果包含用於嘗試啓動此過程的確切字符串,可能會有所幫助。 – 2011-04-25 12:19:27

+0

添加了與實際代碼類似的示例代碼。 – guillermooo 2011-04-25 13:04:59

回答

3

您需要修改當前過程的環境,如果你想CreateProcess看到它。目前,子shell(無論是包含在命令行中還是通過shell=True請求)正在看到您的修改環境,但直接調用CreateProcess不是。

+2

(我的原始答案相當錯誤,並且在我仔細檢查http://hg.python.org/cpython/file/default/PC/_subprocess.c和http://hg.python中的代碼後已得到更正.org/cpython/file/default/Lib/subprocess.py) – ncoghlan 2011-04-25 17:11:02

+0

我沒有檢查''subprocess.py'',但沒有'_subprocess.c''。太好了,謝謝! – guillermooo 2011-04-25 17:46:17

-1

檢查MSDN的思想? CreateProcess文檔。

引述它的一個部分:

從其中加載應用程序的目錄。 父進程的當前目錄。 32位Windows系統目錄。使用GetSystemDirectory函數獲取此目錄的路徑。 16位Windows系統目錄。沒有獲得該目錄路徑的函數,但它被搜索。這個目錄的名字是System。 Windows目錄。使用GetWindowsDirectory函數獲取此目錄的路徑。 PATH環境變量中列出的目錄。請注意,此函數不會搜索App Paths註冊表項指定的每個應用程序路徑。要將這個每個應用程序路徑包含在搜索順序中,請使用ShellExecute函數。

0

如果我正在閱讀您的問題,聽起來好像在%HOMEDRIVE%%HOMEPATH%\SmallApps\GnuWin32\bin映射到的文件夾中有一個名爲wc.exe的應用程序。如果是這樣的話,你最好將exe設置爲%HOMEDRIVE%%HOMEPATH%\SmallApps\GnuWin32\bin\wc.exe的擴展版本。由於這個路徑和可執行文件名最終可能包含空格,所以將它換成引號也不會有什麼壞處。

總之,不要依賴路徑搜索。它不僅容易出錯,而且還是一個潛在的安全漏洞。

相關問題