2013-04-25 16 views
6

Ho un programma Python che usa os.system per eseguire vari comandi. (Non può usare subprocess perché deve essere retrocompatibile fino a Python 2.0.)Sopprimi "Il programma non può essere avviato perché manca X.dll" popup popup

Su Windows, a volte il comando fa riferimento a DLL in una directory insolita, quindi ottengo il famigerato "Il programma può" t start perché manca X.dll "error 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."

La mia domanda non è su come rendere il comando Trova tutte le DLL. So già come farlo. Quello che voglio sapere è, come faccio a dire a Windows di non mostrare questa finestra di dialogo quando manca una DLL? Invece, il processo figlio dovrebbe stampare il messaggio di errore su stderr (che è stato reindirizzato a un file all'interno dell'invocazione os.system) e uscire senza successo (causando os.system di restituire un codice di errore). In questo modo il mio programma potrebbe catturare l'errore e riportarlo a modo suo, piuttosto che restare sospeso finché qualcuno non arriva per fare clic su OK.

MSDN è normalmente mio amico, ma questa volta non ottengo altro che consigli su come far fronte a specifiche DLL mancanti, il che è bello e tutto ma non quello di cui ho bisogno questa volta.

Per ribadire, questa è una situazione di estrema compatibilità con le versioni precedenti: ho bisogno di una soluzione che funzioni con Python 2.7 o qualsiasi versione precedente fino alla 2.0. Ha anche bisogno di lavorare su tutte le versioni ancora popolari di Windows (XP, Vista, 7, 8). Lavorare con ancora più vecchio Windows è altamente desiderabile ma non richiesto al 100%. Inoltre, i moduli di terze parti e i programmi di supporto scritti in qualsiasi altra lingua non sono un'opzione. (Suppongo che un file .BAT vada bene, se questo è l'unico modo per farlo.)

+0

Potete chiarire un po '? Se dovessi eseguire cl.exe su questa macchina senza Python coinvolto, si aprirà lo stesso errore? – Krets

+0

Potrebbe o meno, a seconda di quale delle varie impostazioni di 'PATH' che ho scelto. * Ma non è questo il punto della domanda. * So già come aggiustare il 'PATH'. La domanda riguarda come ottenere l'* errore * da riferire al mio programma invece che tramite questa finestra di dialogo fuori banda. – zwol

risposta

7

La finestra di dialogo può essere disabilitata per il processo chiamante con SetErrorMode. Tuttavia, è necessario leggere la documentazione LoadLibrary per scoprire che "DLL mancante al momento del caricamento" si qualifica come uno degli "errori critici" coperti da SEM_FAILCRITICALERRORS.

La modalità di errore eredita i processi figli, purché non vengano creati con CREATE_DEFAULT_ERROR_MODE e sembra che CMD.EXE non imposti tale contrassegno quando crea sottoprocessi. Così l'impostazione della modalità di errore all'avvio nel mio script Python in effetti eliminare la finestra di dialogo nella situazione che mi interessa ...

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

Questa non è una soluzione ottimale: il sottoprocesso termina con un particolare codice di errore (0xC0000135 - non effettivamente documentato come "DLL mancante", ma evidentemente da ciò che viene visualizzato quando si esegue la ricerca su quel numero) ma i dettagli, ad esempio la DLL mancante, vengono rilasciati sul pavimento. Spero ancora di trovare un'impostazione da qualche parte che faccia in modo che il loader riferisca i dettagli a stderr.

Problemi correlati