Popen与可执行文件/路径冲突 [英] Popen with conflicting executable/path

查看:133
本文介绍了Popen与可执行文件/路径冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Popen从我的Python脚本中调用ImageMagick的转换"实用程序,如下所示:

I'd like to call the "convert" utility from ImageMagick from my Python script using Popen, like so:

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

(上面的示例只是简单地水平翻转图像)

(The above example simply reverses the image horizontally)

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

The problem is that when I run the script in Windows, it mistakenly calls the convert.exe utility that ships with Windows to convert FAT partitions to NTFS! (located in \Windows\system32)

现在,如果我在system32以外的任何目录中随机打开命令提示符,然后键入"convert",则它将正确运行ImageMagick可执行文件.因此,这意味着Popen会自动在system32中查找.如何使它在system32中不可见,并运行正确的可执行文件?

Now, if I randomly open a command prompt at any directory other than system32, and type "convert", it correctly runs the ImageMagick executable. So, this implies that Popen is automatically looking in system32. How can I make it not look in system32, and run the correct executable?

推荐答案

搜索程序并非易事.我会明确指定convert.exe可执行文件的完整路径.

Search for a program is not trivial. I'd specify the full path to the convert.exe executable explicitly instead.

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

subprocess uses CreateProcess on Windows that looks in system32 directory even before any other directory in %PATH%:

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

... If the file name does not contain an extension, .exe is appended. Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period (.) with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory path, the system searches for the executable file in the following sequence:

  1. 从中加载应用程序的目录.
  2. 父进程的当前目录.
  3. 32位Windows系统目录.使用GetSystemDirectory函数获取此目录的路径.
  4. 16位Windows系统目录.没有获取该目录路径的函数,但会对其进行搜索.该目录的名称是System.
  5. Windows目录.使用GetWindowsDirectory函数获取此目录的路径.
  6. PATH环境变量中列出的目录.请注意,此功能不会搜索应用程序路径"注册表项指定的每个应用程序路径.要将每个应用程序路径包括在搜索序列中,请使用ShellExecute函数.

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

Therefore convert is equivalent to convert.exe in this case. It first looks in a directory that contains sys.executable e.g., C:\Python27. Then in the current directory: where you started the Python script from. Then in system32 where it finds convert.exe (filesystem utility, not imagemagick).

您可以尝试从os.environ['PATH']删除system32目录,它可能会取消对它的检查:Popen(cmd, env=no_system32_environ)但它很脆弱(比显式路径还差).

You could try to remove system32 directory from os.environ['PATH'] it may(?) suppress checking it: Popen(cmd, env=no_system32_environ) but it is fragile (worse than the explicit path).

Python错误跟踪器存在一个相关问题:子进程在Windows上选择了错误的可执行文件."

There is a related issue on Python bug tracker: "Subprocess picks the wrong executable on Windows."

cmd.exe(外壳)使用不同的算法.请参见 Windows如何在外壳中找到输入的文件?

cmd.exe (the shell) uses different algorithm. See How does Windows locate files input in the shell?

如果设置shell=True,则convert程序的搜索顺序:

If you set shell=True then the search sequence for convert program:

  1. convert不是内部Shell命令
  2. 没有明确的路径,因此搜索会继续
  3. 搜索当前目录
  4. 按照列出的顺序搜索PATH环境变量指定的每个目录
  1. convert is not an internal shell command
  2. there is no explicit path, so the search continues
  3. search the current directory
  4. search each directory specified by the PATH environment variable, in the order listed

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

%PATHEXT% defines which file extensions are checked and in what order e.g., convert.com, convert.exe, convert.bat, convert.cmd if %PATHEXT% is .com;.exe;.bat;.cmd.

这篇关于Popen与可执行文件/路径冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆