2013-04-25 2 views
6

Mam program w języku Python, który używa os.system do wykonywania różnych poleceń. (Nie może używać subprocess, ponieważ musi być kompatybilny wstecz aż z Pythonem 2.0).Wyłącz "Program nie może się uruchomić, ponieważ brakuje X.dll" popup popup

W systemie Windows czasami polecenie odwołuje się do bibliotek DLL w nietypowym katalogu, więc otrzymuję niesławny "Program może" t start, ponieważ X.dll brakuje "popup błędu.

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

Moje pytanie brzmi nie o tym, jak sprawić, że komenda znaleźć wszystkie swoje pliki DLL. Już wiem, jak to zrobić. Co chcę wiedzieć, jak mogę powiedzieć Windows , aby nie wyświetlać tego okna dialogowego, gdy brakuje biblioteki DLL? Zamiast tego proces potomny powinien wydrukować komunikat o błędzie na stderr (który został przekierowany do pliku w ramach inwokacji os.system) i zakończyć niepowodzeniem (powodując, że os.system zwróci kod błędu). W ten sposób mój program może uchwycić błąd i zgłosić go na swój własny sposób, zamiast wieszać, dopóki ktoś nie przyjdzie, aby kliknąć OK.

MSDN jest zwykle moim przyjacielem, ale tym razem otrzymuję tylko rady, jak radzić sobie z konkretnymi brakującymi bibliotekami DLL, co jest miłe i wszystko, ale nie tym, czego potrzebuję tym razem.

Podkreślam, że jest to sytuacja ekstremalnie kompatybilna: potrzebuję rozwiązania, które działa z Pythonem 2.7 lub starszą wersją z powrotem do wersji 2.0. Musi również działać na wszystkich wciąż popularnych wersjach systemu Windows (XP, Vista, 7, 8). Praca z nawet starszymi Windows jest wysoce pożądana, ale nie jest wymagana w 100%. Ponadto, moduły stron trzecich i programy pomocnicze napisane w jakimkolwiek innym języku nie są opcją. (Przypuszczam, że plik .BAT byłby w porządku, jeśli jest to jedyny sposób, aby to zrobić.)

+0

Czy możesz trochę wyjaśnić? Jeśli miałbyś wykonać cl.exe na tym komputerze bez udziału Pythona, czy pojawiłby się ten sam błąd? – Krets

+0

Może, ale nie musi, w zależności od tego, które z wybranych ustawień "PATH" wybrałem. * Ale nie o to pytam. * Już wiem, jak dostosować "PATH". Pytanie brzmi, w jaki sposób uzyskać zgłoszenie * błędu * do mojego programu zamiast przez to pozapasmowe okno dialogowe. – zwol

Odpowiedz

7

Okno dialogowe można wyłączyć dla wywołującego procesu z SetErrorMode. Jednak musisz przeczytać dokumentację LoadLibrary, aby odkryć, że "brakująca biblioteka DLL w czasie ładowania" kwalifikuje się jako jeden z "krytycznych błędów" objętych przez SEM_FAILCRITICALERRORS.

Tryb błędu dziedziczy procesy potomne, o ile nie są one tworzone z CREATE_DEFAULT_ERROR_MODE i wydaje się, że CMD.EXE nie ustawia tej flagi podczas tworzenia podprocesów. Więc ustawienie trybu błędu na starcie w moim skrypt Pythona ma w rzeczywistości pominąć okno dialogowe, w sytuacji dbam o ...

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

Nie jest to optymalne rozwiązanie: podproces kończy z kodem szczególności błędu (0xC0000135 - faktycznie nie udokumentowana jako "brakująca biblioteka DLL", ale ewidentnie wynikająca z tego, co pojawia się podczas wyszukiwania na tym numerze), ale szczegóły - takie jak brak biblioteki DLL - są upuszczane na podłogę. Nadal mam nadzieję znaleźć jakieś miejsce, które sprawi, że program ładujący zgłosi szczegóły do ​​stderr.