2013-04-25 10 views
6

Tôi có chương trình Python sử dụng os.system để thực hiện các lệnh khác nhau. (Nó không thể sử dụng subprocess vì nó phải tương thích ngược tất cả các cách để Python 2.0.)Suppress "Chương trình không thể khởi động vì X.dll bị thiếu" lỗi popup

Trên Windows, đôi khi lệnh tham chiếu DLL trong một thư mục khác thường, và vì vậy tôi nhận được khét tiếng "Chương trình có thể" t bắt đầu bởi vì X.dll là thiếu "lỗi popup.

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."

Câu hỏi của tôi là không về làm thế nào để làm cho các lệnh tìm thấy tất cả các file DLL của nó. Tôi đã biết làm thế nào để làm điều đó. Những gì tôi muốn biết là, làm cách nào để yêu cầu Windows không hiển thị hộp thoại này khi thiếu DLL? Thay vào đó, tiến trình con sẽ in thông báo lỗi thành stderr (đã được chuyển hướng đến một tệp trong lời gọi os.system) và thoát không thành công (gây ra os.system để trả lại mã lỗi). Bằng cách đó, chương trình của tôi có thể nắm bắt lỗi và báo cáo theo cách riêng của mình, thay vì treo cho đến khi có ai đó đến cùng bấm OK.

MSDN thường là bạn của tôi, nhưng lần này tôi không nhận được gì ngoài lời khuyên về cách đối phó với các DLL bị thiếu cụ thể, điều này thật tuyệt và tất cả nhưng không phải là thứ tôi cần lúc này.

Để nhắc lại, đây là tình huống tương thích ngược-lạc hậu: Tôi cần một giải pháp hoạt động với Python 2.7 hoặc bất kỳ phiên bản cũ nào trở lại 2.0. Nó cũng cần phải làm việc trên tất cả các phiên bản Windows vẫn phổ biến (XP, Vista, 7, 8). Làm việc với thậm chí cũ hơn Windows là rất mong muốn nhưng không yêu cầu 100%. Hơn nữa, các mô-đun và chương trình trợ giúp của bên thứ ba được viết bằng bất kỳ ngôn ngữ nào khác không phải là một lựa chọn. (Tôi cho rằng tệp .BAT sẽ không sao, nếu đó là cách duy nhất để làm điều đó.)

+0

Bạn có thể làm rõ một chút không? Nếu bạn đã thực hiện cl.exe trên máy tính này mà không có python tham gia, sẽ lỗi này bật lên? – Krets

+0

Nó có thể hoặc nó có thể không, tùy thuộc vào một số cài đặt 'PATH' tôi chọn. * Nhưng đó không phải là vấn đề của câu hỏi. * Tôi đã biết cách điều chỉnh 'PATH'. Câu hỏi đặt ra là làm thế nào để có được * lỗi * được báo cáo cho chương trình của tôi thay vì thông qua hộp thoại out-of-band này. – zwol

Trả lời

7

Hộp thoại có thể bị tắt cho quá trình gọi với SetErrorMode. Tuy nhiên, bạn phải đọc tài liệu LoadLibrary để phát hiện rằng "thiếu DLL trong thời gian tải" đủ điều kiện là một trong những "lỗi nghiêm trọng" được bao gồm bởi SEM_FAILCRITICALERRORS.

Chế độ lỗi kế thừa quy trình con, miễn là chúng không được tạo bằng CREATE_DEFAULT_ERROR_MODE và có vẻ như CMD.EXE không đặt cờ đó khi tạo quy trình con. Vì vậy, thiết lập các chế độ lỗi khi khởi động trong kịch bản Python của tôi không thực sự ngăn chặn các hộp thoại trong tình hình tôi quan tâm đến ...

if sys.platform == 'win32': 
    try: 
     import ctypes 
     # SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX 
     ctypes.windll.kernel32.SetErrorMode(0x0001|0x0002|0x8000) 
    except: 
     pass 

Đây không phải là một giải pháp tối ưu: các tiến trình con kết thúc với một mã lỗi đặc biệt (0xC0000135 - không thực sự được ghi là "thiếu DLL", nhưng rõ ràng là từ những gì xuất hiện khi bạn tìm kiếm số đó) nhưng các chi tiết - giống như DLL bị thiếu - bị bỏ trên sàn. Tôi vẫn hy vọng tìm thấy một thiết lập ở đâu đó mà làm cho bộ nạp báo cáo các chi tiết để stderr.