禁止“程序无法启动因为X.dll丢失”错误弹出

时间:2013-04-25 19:30:14

标签: python windows cmd

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

在Windows上,有时命令会引用异常目录中的DLL,因此我得到臭名昭着的“程序无法启动,因为缺少X.dll”错误弹出。

Windows error popup with title "cl.exe - System Error" and text "The program can't start because mspdb80.dll is missing from your computer. Try reinstalling the program to fix this problem."

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

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

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

1 个答案:

答案 0 :(得分:8)

可以使用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报告详细信息的设置。