CreateProcess détaché

CreateProcess détaché - C++ - Programmation

Marsh Posté le 29-04-2010 à 15:23:56    

Bonjour à tous,
 
Je développe un service windows qui gère différentes choses au niveau du réseau, mais peu importe sa fonction ; je souhaite le mettre à jour automatiquement par le réseau.
 
Je fais donc une fonction qui va vérifier si une nouvelle version est en ligne, si oui je la télécharge grâce à la lib urlmon et URLDownloadToFile(). Le problème maintenant, c'est que je voudrais mettre à jour le service... depuis le service.
 
J'ai imaginé la solution suivante : le service lance un petit programme externe, s'arrête, le programme remplace l'exe du service et le relance.
Je précise que ce ne peut être l'updater qui stoppe le service, parce que celui-ci effectue des tâches différentes selon s'il est arrêté par un net stop par exemple ou si il s'arrête de lui-même.
 
Ma question est donc la suivante : comment puis-je faire en sorte que le service lance le processus de mise à jour de façon détachée, c'est-à-dire sans attendre sa mort pour s'arrêter ou sans le tuer en s'arrêtant ?
 
Je pensais pouvoir utiliser le flag DETACHED_PROCESS de CreateProcess(), mais je n'obtiens pas l'effet escompté ; apparemment ça ne fonctionne que pour les programmes console (?).
 
J'imagine que ce problème est assez commun mais je n'ai trouvé de solution nulle part... Merci de m'éclairer !

Reply

Marsh Posté le 29-04-2010 à 15:23:56   

Reply

Marsh Posté le 29-04-2010 à 16:50:34    

Ollijokinen a écrit :

Bonjour à tous,
Ma question est donc la suivante : comment puis-je faire en sorte que le service lance le processus de mise à jour de façon détachée, c'est-à-dire sans attendre sa mort pour s'arrêter ou sans le tuer en s'arrêtant ?
 


Tu es sur que quand le service s'arrête, cela tue le processus de mise a jour des fichiers? (me semble pas que c'est écrit dans la doc de createprocess!)


Message édité par breizhbugs le 29-04-2010 à 16:52:15
Reply

Marsh Posté le 30-04-2010 à 09:36:06    

En fait ce qui se passe, c'est plutôt que le service ne s'arrête jamais : je lance le processus d'update mais il n'est pas détaché, le service attend son interruption avant de continuer à exécuter son code qui lui demande de s'arrêter.
Et comme le fils s'arrête quand le service est éteint...
 
Si comme tu le dis, tuer le service n'arrête pas le fils alors il me suffit de savoir comment faire pour vraiment détacher le processus !

Reply

Marsh Posté le 30-04-2010 à 14:06:37    

Le processus d'update c'est quoi? un programme ou un thread?
Tu n'est pas clair aussi: tu dis que le service (A) attends que le processus d'update (B) ait fini de remplacer les fichiers de A pour le relancer, B attendant que A se termine pour pouvoir mettre ses fichiers a jours... (y a interblocage la si c'est comme ca!)

Reply

Marsh Posté le 30-04-2010 à 20:11:09    

Non non il ne doit pas y avoir d'interblocage. B est bien un programme indépendant. Ce qui doit se passer, c'est ça :
- Le service A lance le programme B puis s'arrête.
- Le programme B attend que A soit arrêté, remplace son exécutable, le relance et s'éteint.
 
Ce que je n'arrive pas à faire, c'est à faire s'arrêter A après qu'il ait lancé B ; il attend la fin de son exécution et là, effectivement, je suis bloqué.

Reply

Marsh Posté le 30-04-2010 à 20:44:41    

Ollijokinen a écrit :

Non non il ne doit pas y avoir d'interblocage. B est bien un programme indépendant. Ce qui doit se passer, c'est ça :
- Le service A lance le programme B puis s'arrête.
- Le programme B attend que A soit arrêté, remplace son exécutable, le relance et s'éteint.
 
Ce que je n'arrive pas à faire, c'est à faire s'arrêter A après qu'il ait lancé B ; il attend la fin de son exécution et là, effectivement, je suis bloqué.


"il" c'est A?

Reply

Marsh Posté le 30-04-2010 à 22:39:36    

Hmm, je ne sais pas comment tu te démerde, mais normallement CreateProcess n'attend pas la fin du processus pour retourner à l'appelant. Perso j'utilise une fonction du genre :

Code :
  1. int Execute(STRPTR cmd, int timeout)
  2. {
  3.     /* Quoted from MinGW runtime library */
  4.     STARTUPINFO sa;
  5.     PROCESS_INFORMATION pi;
  6.     DWORD ec = 1;
  7.     memset(&sa, 0, sizeof(sa));
  8.     memset(&pi, 0, sizeof(pi));
  9.     if (!CreateProcess(0, cmd, 0, 0, 1, 0, 0, 0, &sa, &pi))
  10.     {
  11.         return -1;
  12.     }
  13.     if (timeout >= -1)
  14.     {
  15.         if (WaitForSingleObject(pi.hProcess, timeout == -1 ? INFINITE : timeout) == WAIT_TIMEOUT)
  16.         {
  17.             TerminateProcess(pi.hProcess, 0xbad);
  18.             LOG_Info("Command '%s' has been killed after %ds.\n", cmd, timeout / 1000);
  19.         }
  20.         GetExitCodeProcess(pi.hProcess, &ec);
  21.     }
  22.     else ec = 0;
  23.     CloseHandle(pi.hProcess);
  24.     CloseHandle(pi.hThread);
  25.     return ec;
  26. }


 
Fonctionne très bien même dans un service (lancé en tant que LOCAL_SYSTEM).

Reply

Marsh Posté le 02-05-2010 à 19:40:08    

Oui, "il" c'est A, pardon.
 
tpierron, j'ai pas mon code sous les yeux, je regarderai demain, mais mon code ressemble pour ou moins à ça ; après ça vient peut-être des flags que j'utilise, parce que j'ai une fonction qui me permet de récupérer la sortie standard du processus par un pipe ; ce que normalement je ne fais pas dans ce cas précis.

Reply

Marsh Posté le 03-05-2010 à 23:29:27    

Ollijokinen a écrit :


Ce que je n'arrive pas à faire, c'est à faire s'arrêter A après qu'il ait lancé B ; il attend la fin de son exécution et là, effectivement, je suis bloqué.
Oui, "il" c'est A, pardon.


Bon, je reformule:
Ce que je n'arrive pas à faire, c'est à faire s'arrêter A après qu'il ait lancé B ; A attend la fin de l'exécution de B et là, effectivement, je suis bloqué.

 

Question:
1- Comment A peut il attendre la fin de B alors que A est censé s'arrêter après avoir créer B?
2- Comment B fait il pour mettre a jour les fichier de A si A tourne et attend la fin de B?

 

Il y a inter-blocage la!


Message édité par breizhbugs le 03-05-2010 à 23:29:59
Reply

Marsh Posté le 04-05-2010 à 09:58:37    

Non justement, A ne doit pas attendre la fin de l'exécution de B ; il doit lancer B et s'arrêter. B, une fois qu'il constate qu'A est effectivement arrêté (par un tasklist par exemple), remplace le fichier, relance A et s'éteint.

Reply

Marsh Posté le 04-05-2010 à 09:58:37   

Reply

Marsh Posté le 04-05-2010 à 12:06:27    

Mets le code de tes 2 programmes pour voir comment tu t'y prends et puis on verra ce qui cloche...

Reply

Marsh Posté le 04-05-2010 à 16:09:01    

Il faut que je teste la fonction de tpierron avant ; le code de la mienne est assez long et la plupart de ses fonctionnalités sont inutiles, concernant ce problème.

Reply

Marsh Posté le 08-05-2010 à 13:58:04    

Bon j'ai pu tester seulement maintenant, et ça marche :) En fait, dans ma fonction d'exécution, j'ai pas mal de paramètres qui me permettent de cacher la fenêtre éventuellement créée, d'encoder le résultat, de le récupérer ou non... et dans tous les cas de figure je passais par un WaitForSingleObject(). Merci pour votre aide en tout cas !
 
--Edit--
Précision : dans mon code j'utilisais le flag DETACHED_PROCESS à tort ; d'une manière générale en testant, ça ne marche visiblement qu'avec un creationFlags à 0...

Message cité 1 fois
Message édité par Ollijokinen le 08-05-2010 à 14:08:57
Reply

Marsh Posté le 08-05-2010 à 18:24:42    

Ollijokinen a écrit :

Bon j'ai pu tester seulement maintenant, et ça marche :) En fait, dans ma fonction d'exécution, j'ai pas mal de paramètres qui me permettent de cacher la fenêtre éventuellement créée, d'encoder le résultat, de le récupérer ou non... et dans tous les cas de figure je passais par un WaitForSingleObject(). Merci pour votre aide en tout cas !
 
--Edit--
Précision : dans mon code j'utilisais le flag DETACHED_PROCESS à tort ; d'une manière générale en testant, ça ne marche visiblement qu'avec un creationFlags à 0...


Bonjour et content pour toi que ça marche.
Enfin comme indiqué dans la doc ( http://msdn.microsoft.com/en-us/li [...] 85%29.aspx ), le DETACHED_PROCESS indique que l'on veut que le nouveau programme n'utilise pas la console de son créateur, ce qui n'avait donc rien a voir avec ce que tu souhaitais...

Reply

Marsh Posté le 10-05-2010 à 09:27:59    

Effectivement oui, j'avais lu trop vite :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed