7

我有一个 Python 程序,用于os.system执行各种命令。(它不能使用subprocess,因为它必须一直向后兼容到 Python 2.0。)

在 Windows 上,有时该命令会引用异常目录中的 DLL,因此我会弹出臭名昭著的“程序无法启动,因为 X.dll 丢失”错误弹出窗口。

带有标题的 Windows 错误弹出窗口

我的问题不是关于如何让命令找到它的所有 DLL。我已经知道该怎么做。我想知道的是,当缺少 DLL 时,如何告诉 Windows不显示此对话框?相反,子进程应该将错误消息打印到 stderr(已被重定向到os.system调用中的文件)并不成功退出(导致os.system返回错误代码)。这样我的程序就可以捕获错误并以自己的方式报告它,而不是挂起直到有人来点击确定。

MSDN 通常是我的朋友,但这次我只得到关于如何处理特定缺失 DLL 的建议,这很好,但不是我这次需要的。

重申一下,这是一种极度向后兼容的情况:我需要一个可以与 Python 2.7 或任何旧版本一起使用的解决方案,一直到 2.0。它还需要在所有仍然流行的 Windows 版本(XP、Vista、7、8)上工作。使用更旧的Windows 是非常可取的,但不是 100% 需要。此外,不能选择以任何其他语言编写的第三方模块和帮助程序。(如果这是唯一的方法,我想一个.BAT文件就可以了。)

4

1 回答 1

11

可以使用 为调用进程禁用该对话框SetErrorMode。但是,您必须阅读LoadLibrary文档才能发现“加载时缺少 DLL”属于SEM_FAILCRITICALERRORS.

错误模式会继承到子进程,只要它们不是用 创建的CREATE_DEFAULT_ERROR_MODE,并且 CMD.EXE 在创建子进程时似乎没有设置该标志。因此,在我的 Python 脚本中设置启动时的错误模式实际上会在我关心的情况下抑制对话框...

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。

于 2013-04-30T16:25:25.770 回答