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,并运行正确的可执行文件?

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

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

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

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

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

你可以尝试从os.environ['PATH']删除system32目录,它可能会抑制检查: Popen(cmd, env=no_system32_environ)但它是脆弱的(比显式path差)。

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


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

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

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

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

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

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

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

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