Popen冲突的可执行文件/path

我想使用Popen从Python脚本中调用ImageMagick中的“convert”实用程序,如下所示:

Popen(["convert", input_path, "-flop", output_file_path]) 

(上面的例简单地反转了图像水平)

问题是,当我在Windows中运行脚本时,它错误地调用Windows附带的convert.exe实用程序将FAT分区转换为NTFS! (位于\ Windows \ system32)

现在,如果我在system32以外的任何目录中随机打开一个命令提示符并键入“convert”,它就会正确运行ImageMagick可执行文件。 所以,这意味着Popen自动查找system32。 我怎样才能让它不看在system32,并运行正确的可执行文件?

搜索一个程序是不平凡的。 我会明确指定convert.exe可执行文件的完整路径

subprocess CreateProcess在Windows上使用CreateProcess ,甚至在%PATH%任何其他目录之前查找system32目录 :

…如果文件名不包含扩展名,则附加.exe 因此,如果文件扩展名为.com,则此参数必须包含.com扩展名。 如果文件名以句点(。)结尾且没有扩展名,或者文件名包含路径,则不会附加.exe。 如果文件名不包含目录路径,系统将按以下顺序搜索可执行文件:

  1. 加载应用程序的目录。
  2. 父进程的当前目录。
  3. 32位Windows系统目录。 使用GetSystemDirectory函数获取此目录的路径。
  4. 16位Windows系统目录。 没有获得这个目录的路径的函数,但它被搜索。 这个目录的名字是System。
  5. Windows目录。 使用GetWindowsDirectory函数获取此目录的路径。
  6. PATH环境变量中列出的目录。 请注意,此函数不会搜索App Paths注册表项指定的每个应用程序路径。 要将这个每个应用程序路径包含在搜索顺序中,请使用ShellExecute函数。

因此在这种情况下convert等效于convert.exe 它首先查找包含sys.executable文件的目录,例如C:\Python27 然后在当前目录中:从哪里启动Python脚本。 然后在system32找到convert.exe (文件系统工具,而不是imagemagick)。

你可以尝试从os.environ['PATH']删除system32目录,它可能会阻止检查它: Popen(cmd, env=no_system32_environ)但它是脆弱的(比显式路径更糟糕)。

Python bug跟踪器有一个相关的问题: “Subprocess在Windows上选择错误的可执行文件”。


cmd.exe (shell)使用不同的算法。 请参阅Windows如何在shell中查找输入文件?

如果你设置shell=True那么convert程序的搜索顺序是:

  1. convert不是一个内部的shell命令
  2. 没有明确的路径,搜索仍在继续
  3. 搜索当前目录
  4. 按列出的顺序搜索由PATH环境变量指定的每个目录

%PATHEXT%定义检查哪些文件扩展名以什么顺序检查,例如convert.com,convert.exe,convert.bat,convert.cmd,如果%PATHEXT%.com;.exe;.bat;.cmd

作为一种完全不同的方法,您可能需要尝试一下PythonMagick ,一个用于ImageMagick的Python包装器。 通过这种方式,你可以从Python中访问convert的函数,而且不需要产生外部进程。

刚刚碰到这个自己。 在shell中运行php脚本可以访问shell $ PATH,而在Apache中运行则不会(至少Cygwin DLL / exe不是$ PATH)。

其次,在Windows平台上,在php中使用本地Windows符号C:/ dir / subdir / pgm,你将得到你所期望的。

因此,多平台代码需要切换/处理路径,然后参考决策。