2011-04-25 114 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的扩展版本。由于这个路径和可执行文件名最终可能包含空格,所以将它换成引号也不会有什么坏处。

总之,不要依赖路径搜索。它不仅容易出错,而且还是一个潜在的安全漏洞。

相关问题