Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Détecter un process dans un service

13 réponses
Avatar
jean-michel bain-cornu
Bonjour,

J'ai un petit problème avec une application python qui tourne sur un
serveur windows 2k3.
L'appli est un service généré avec py2exe (python 2.4.4). C'est un
process qui est démarré par le gestionnaire de service de Windows, et
dont le but est simplement de lancer une autre tâche (exécutable généré
lui aussi avec py2exe). Cette autre tâche se charge d'un certain nombre
de corvées sur le serveur, puis se termine au bout de quelques secondes
maxi.
Le premier exécutable voit alors que la tâche est terminée, attends 1
seconde, et la relance.
Le but de ça, c'est d'avoir un service robuste qui ne se plantera jamais
pour des raisons fonctionnelles, qui ne sera jamais modifié, et qui
s'assurera impertubablement que la tâche sera lancée à intervalles
périodiques.
Le problème majeur, c'est comment voir si la tâche est terminée, afin de
pouvoir en relancer une autre.
J'ai d'abord commencé avec WMI (voir code ci-après), mais ça ne
fonctionne pas dans un service. Pas de symptômes visibles : ça ne marche
pas.
Je m'en suis tiré avec un fichier qui contient le PID et qui est détruit
par la tâche quand son job est fini, mais du coup ça n'est plus robuste
du tout, si la tâche se plante, le fichier PID n'est jamais détruit, et
une nouvelle tâche n'est jamais relancée.
Ma question, c'est comment faire marcher ce *!@"* de WMIService quand il
est utilisé dans un service, ou alors trouver un autre moyen de détecter
si un process tourne ou pas.
Et je sais, c'est plus facile sous Linux, mais je n'ai pas de serveur
Linux sur ce site :-(

A+
jm

# -*- coding: cp1252 -*-
def wprocess(lstProc=[]):
import win32com,win32com.client
WMIService=win32com.client.GetObject(r'winmgmts:{impersonationLevel=impersonate}!//.\root\cimv2')
listProcess = WMIService.ExecQuery('Select * from Win32_Process')
for item in listProcess:
if item.Name in lstProc:
return True
if wprocess(['notepad.exe']):
print 'ok' # le print est là pour l'exemple

3 réponses

1 2
Avatar
Laurent Pointal
jean-michel bain-cornu wrote:

<zip>

Après plein d'essais, finalement, un bête "os.spawnv(os.P_WAIT,etc..."
convient tout à fait comme solution à mon problème.
Avant ça, j'utilisais P_NOWAIT, et c'est ça qui m'obligeait à me
préoccuper de la fin du process...
Avec P_WAIT, ça se fait tout seul, que le process se termine normalement
ou pas. Kiss, comme qui dirait...


C'est ok si tu es sûr que ton process ne rentre jamais dans un traitement
foireux qui le bloque sans le planter (ex. une acquisition de ressource qui
le met en attente, un bug avec une boucle sans fin, etc...).

L'idée du watchdog c'est de pouvoir traiter aussi ces cas là, détecter le
manque d'activité "normale" de ton process pour le tuer et le relancer.

Mais si ça fait l'affaire, KISS

A+

Laurent.

Avatar
jean-michel bain-cornu
Après plein d'essais, finalement, un bête "os.spawnv(os.P_WAIT,etc..."
convient tout à fait comme solution à mon problème.
Avant ça, j'utilisais P_NOWAIT, et c'est ça qui m'obligeait à me
préoccuper de la fin du process...
Avec P_WAIT, ça se fait tout seul, que le process se termine normalement
ou pas. Kiss, comme qui dirait...


C'est ok si tu es sûr que ton process ne rentre jamais dans un traitement
foireux qui le bloque sans le planter (ex. une acquisition de ressource qui
le met en attente, un bug avec une boucle sans fin, etc...).

L'idée du watchdog c'est de pouvoir traiter aussi ces cas là, détecter le
manque d'activité "normale" de ton process pour le tuer et le relancer.


Ouaip. L'idée est que le process est assez robuste pour ne pas se
planter ni boucler. Si c'est le cas, c'est qu'on est vraiment dans un
coup tordu, et c'est à l'admin de tuer le process, ce qui provoque son
redémarrage, et probablement à terme un nouveau plantage...
Ceci arrive parfois avec la partie serveur de wxQueries, qui met à jour
des contacts et des plannings par le Outlook Web Access, et fait aussi
du smtp et de l'imap. Si l'admin a fait une erreur dans le paramétrage
(code user, pw, ou nom du serveur par exemple), on obtient alors des
blocages apparents qui durent parfois plusieurs dizaines de secondes, ce
qui rend difficile une détection automatique de plantage.
Ceci peut être résolu, mais il faut le programmer. Pour la prochaine
version, peut-être...
Merci pour les idées en tout cas.
jm


Avatar
jean-michel bain-cornu
Bonjour,
Pour le même genre de problème. Sauf que je ne m'intéresse qu'aux
processus(1), et que mes délais sont différents : je teste toutes les
3 minutes.

Au début, j'ai fait, comme toi, un programme en tâche de fond.

Ensuite, j'ai opté pour un simple batch, lancé par une tache
planifiée. Ce choix, pour avoir une solution non-Python (pour
contourner certains blocages Python).

(1) trop de limitation avec les services, je préfère utiliser des
programmes (ou des .pyw) qui tournent en tâche de fond.



Je ne connaissais pas la possibilité de lancer une tâche planifiée au
démarrage de la machine, qui semble convenir à mon besoin. Le seul
problème que je vois, c'est qu'il faut que je fasse un utilitaire pour
contrôler la tâche (un peu comme le fait la console des services) ; ça
ne devrait pas être bien méchant, et ça peut même être fait en mode web
:-).


Voilà, j'ai fait mon utilitaire qui permet de lancer et tuer mes tâches
comme j'en ai besoin, un peu à la manière de la console des services.

Tout ça marche nickel, sauf que quand je ferme ma session utilisateur,
toutes les tâches lancées se terminent (GRR...).
Sous linux, j'utiliserais nohup, mais comment faire sous Windows ? J'ai
essayé d'utiliser P_DETACH avec le os.spawnv, mais rien à faire.

Comment dois-je faire pour qu'un process lancé dans une session
utilisateur reste actif lors de la fermeture de cette session ?
Avant de me lancer dans des essais avec win32process.CreateProcess,
j'aimerais bien quelques avis si possible...

jm

Note: Windows XP et W2K3 server, Python 2.4


1 2