CreateProcess如何定位可执行文件?

时间:2011-04-25 08:55:46

标签: python winapi subprocess

根据文档,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.
)

3 个答案:

答案 0 :(得分:3)

如果希望CreateProcess看到当前进程的环境,则需要修改该环境。目前,子shell(无论是包含在命令行中还是通过shell=True请求)都会看到您修改过的环境,但CreateProcess的直接调用不是。

答案 1 :(得分:0)

如果我正确地阅读您的问题,听起来您在wc.exe映射到的文件夹中有一个名为%HOMEDRIVE%%HOMEPATH%\SmallApps\GnuWin32\bin的应用程序。如果是这种情况,您最好将exe设置为%HOMEDRIVE%%HOMEPATH%\SmallApps\GnuWin32\bin\wc.exe的扩展版本。由于此路径和可执行文件名称最终可能包含空格,因此将它包装在引号中也不会有什么坏处。

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

答案 2 :(得分:-1)

检查MSDN的想法? CreateProcess文档。

引用其中的一部分:

  

加载应用程序的目录。   父进程的当前目录。   32位Windows系统目录。使用GetSystemDirectory函数获取此目录的路径。   16位Windows系统目录。没有函数可以获取此目录的路径,但会搜索它。该目录的名称是System。   Windows目录。使用GetWindowsDirectory函数获取此目录的路径。   PATH环境变量中列出的目录。请注意,此功能不会搜索App Paths注册表项指定的每个应用程序路径。要在搜索序列中包含此每个应用程序路径,请使用ShellExecute函数。