问题描述
我有一个Python程序,它使用 os.system
执行各种命令。 (它不能使用 subprocess
,因为它必须一直向后兼容Python 2.0。)
I have a Python program which uses os.system
to execute various commands. (It can't use subprocess
because it has to be backward compatible all the way to Python 2.0.)
在Windows上,有时该命令在一个不寻常的目录中引用DLL,因此我得到了臭名昭著的由于缺少X.dll而无法启动程序的错误弹出窗口。
On Windows, sometimes the command references DLLs in an unusual directory, and so I get the infamous "The program can't start because X.dll is missing" error popup.
我的问题不是不是使命令找到其所有DLL。我已经知道该怎么做。我想知道的是,当缺少DLL时,如何告诉Windows 不显示此对话框?相反,子进程应该将错误消息打印到stderr(已将其重定向到 os.system
调用内的文件中)并成功退出(导致 os.system
返回错误代码)。这样,我的程序就可以捕获错误并以自己的方式报告错误,而不是挂起直到有人过来单击确定。
My question is not about how to make the command find all its DLLs. I already know how to do that. What I want to know is, how do I tell Windows not to show this dialog box when a DLL is missing? Instead, the child process should print the error message to stderr (which has been redirected to a file within the os.system
invocation) and exit unsuccessfully (causing os.system
to return an error code). That way my program could capture the error and report it in its own way, rather than hanging until someone comes along to click OK.
MSDN通常是我的朋友,但这这段时间我什么也没得到,只有关于如何处理特定的缺少DLL的建议,这很好,虽然这次不是我所需要的。
MSDN is normally my friend, but this time I get nothing but advice on how to cope with specific missing DLLs, which is nice and all but not what I need this time.
重申一下,这是一个极端-backward-compatibility情况:我需要一个可以与Python 2.7或任何较旧版本一起使用直至2.0的解决方案。它还需要在所有仍然流行的Windows版本(XP,Vista,7、8)上运行。非常希望使用甚至更老的 Windows,但并非100%必需。此外,用其他任何语言编写的第三方模块和帮助程序都不是可选的。 (我想 .BAT
文件是可以的,如果那是唯一的方法。)
To reiterate, this is an extreme-backward-compatibility situation: I need a solution that works with Python 2.7 or any older version all the way back to 2.0. It also needs to work on all still-popular versions of Windows (XP, Vista, 7, 8). Working with even older Windows is highly desirable but not 100% required. Further, third-party modules and helper programs written in any other language are not an option. (I suppose a .BAT
file would be okay, if that's the only way to do it.)
推荐答案
可以使用。但是,您必须阅读文档发现在加载时丢失DLL符合 SEM_FAILCRITICALERRORS 涵盖的严重错误之一c $ c>。
The dialog box can be disabled for the calling process with
SetErrorMode
. However, you have to read the LoadLibrary
documentation to discover that "missing DLL at load time" qualifies as one of the "critical errors" covered by SEM_FAILCRITICALERRORS
.
只要不使用,它似乎CMD.EXE创建子进程时未设置该标志。因此,在我关心的情况下,在我的Python脚本中设置启动时的错误模式实际上会抑制对话框。
The error mode inherits to child processes, as long as they are not created with
CREATE_DEFAULT_ERROR_MODE
, and it appears that CMD.EXE does not set that flag when it creates subprocesses. So setting the error mode on startup in my Python script does in fact suppress the dialog box in the situation I care about...
if sys.platform == 'win32':
try:
import ctypes
# SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX
ctypes.windll.kernel32.SetErrorMode(0x0001|0x0002|0x8000)
except:
pass
这不是最佳解决方案:子流程以特定的错误代码终止(0xC0000135-实际上没有记录为缺少DLL,但是显然是从搜索该编号时出现的结果),但是细节(例如缺少DLL的细节)被丢在了地板上。我仍然希望找到一个可以使加载程序将详细信息报告给stderr的设置。
This is not an optimal solution: the subprocess terminates with a particular error code (0xC0000135 — not actually documented as "missing DLL", but evidently so from what comes up when you search on that number) but the details — like which DLL is missing — are dropped on the floor. I still hope to find a setting somewhere that makes the loader report the details to stderr.
这篇关于禁止“由于缺少X.dll而导致程序无法启动”错误弹出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!