Surveiller le sous-processus créé à partir d’une commande shell dans Windows

J’ouvre un programme en utilisant subprocess.Popen

import subprocess

prog = subprocess.Popen(['myprog', args], shell=True)

Je veux surveiller le processus «myprog» et attendre que cela se termine avant que mon code continue.

Le problème auquel je suis confronté est que prog.pid est le PID du shell et non pas «myprog» et je ne sais pas comment obtenir le PID de «myprog». J’ai essayé d’utiliser psutil pour trouver les processus enfants de prog.pid :

parent = psutil.Process(prog.pid)
children = parent.children(recursive=True)

mais une liste vide est renvoyée.

Malheureusement, je ne peux pas démarrer «myprog» sans la shell. Lorsque je lance la commande avec shell=False le message d’erreur suivant s’affiche: FileNotFoundError: [WinError 2] The system cannot find the file specified

J’ai cherché sur le Web haut et bas mais toutes les pistes prometteuses sont pour les utilisateurs non-Windows.

Votre commande atom est probablement un fichier .cmd qui lance un exécutable, ce qui explique la nécessité de shell=True

Vous n’irez pas plus loin dans le recodage du fichier .bat en python, MAIS vous n’avez pas non plus besoin du PID exécutable.

Si l’exécutable se termine, le fichier de commandes se termine, alors oubliez de surveiller prog.pid , surveillez simplement prog utilisant poll (dans le même script python bien sûr).

La méthode de poll permet de vérifier si le processus est terminé (si c’est le cas, il renvoie le code de sortie, s’il ne l’a pas fait, il ne renvoie None ), et cela ne bloque pas.

 if prog.poll() is not None: # process has ended print("ended") 

Rappelons l’attente bloquante de le faire:

 return_code = prog.wait() 

Mais dans votre cas, la commande atom.cmd semble démarrer le processus en arrière-plan, ce qui rend impossible la surveillance sans le PID.

Une solution de contournement dans ce cas est de faire une copie de atom.cmd , supprimez le préfixe de start pour exécuter l’exécutable au premier plan et exécutez la copie à la place.

(ou puisque le cmd appelle un autre fichier atom.cmd comme vous l’avez dit, localisez le fichier app-1.13.0\resources\cli\atom.cmd du atom.cmd original d’ atom.cmd et supprimez le préfixe de start )