Supprimer le message d’erreur “Le programme ne peut pas démarrer car X.dll est manquant”

J’ai un programme Python qui utilise os.system pour exécuter diverses commandes. (Il ne peut pas utiliser de subprocesssubprocess car il doit être rétrocompatible jusqu’à Python 2.0.)

Sous Windows, il arrive que la commande référence des DLL dans un répertoire inhabituel et que je reçois la fameuse erreur “Le programme ne peut pas démarrer car X.dll est manquant”.

Ma question n’est pas sur la façon de faire la commande trouver toutes ses DLL. Je sais déjà comment faire ça. Ce que je veux savoir, c’est comment puis-je dire à Windows de ne pas afficher cette boîte de dialog lorsqu’une DLL est manquante? Au lieu de cela, le processus enfant doit imprimer le message d’erreur à stderr (qui a été redirigé vers un fichier dans l’invocation os.system ) et quitter sans succès (ce os.system pour effet que os.system renvoie un code d’erreur). De cette façon, mon programme pourrait capturer l’erreur et la signaler à sa manière, plutôt que de restr en attente jusqu’à ce que quelqu’un clique sur OK.

MSDN est normalement mon ami, mais cette fois-ci, je ne reçois que des conseils sur la manière de gérer les DLL manquantes spécifiques, ce qui est bien, mais pas ce dont j’ai besoin cette fois-ci.

Pour rappel, il s’agit d’une situation de compatibilité extrême: j’ai besoin d’une solution qui fonctionne avec Python 2.7 ou toute version antérieure depuis la version 2.0. Il doit également fonctionner sur toutes les versions encore populaires de Windows (XP, Vista, 7, 8). Travailler avec des Windows encore plus anciens est hautement souhaitable, mais pas à 100%. De plus, les modules tiers et les programmes d’aide écrits dans un autre langage ne sont pas une option. (Je suppose qu’un fichier .BAT serait correct, si c’est le seul moyen de le faire.)

La boîte de dialog peut être désactivée pour le processus appelant avec SetErrorMode . Cependant, vous devez lire la documentation LoadLibrary pour découvrir que “la DLL manquante au moment du chargement” est considérée comme l’une des “erreurs critiques” couvertes par SEM_FAILCRITICALERRORS .

Le mode d’erreur hérite des processus enfants, tant qu’ils ne sont pas créés avec CREATE_DEFAULT_ERROR_MODE , et il apparaît que CMD.EXE ne définit pas cet indicateur lorsqu’il crée des sous-processus. Donc, définir le mode d’erreur au démarrage dans mon script Python supprime en fait la boîte de dialog dans la situation qui m’intéresse…

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

Ce n’est pas une solution optimale: le sous-processus se termine par un code d’erreur particulier (0xC0000135 – pas réellement documenté en tant que “DLL manquante”, mais évidemment par ce qui apparaît lorsque vous effectuez une recherche sur ce numéro) – sont tombés sur le sol. J’espère toujours trouver un paramètre quelque part qui fait que le chargeur rapporte les détails à stderr.