OVH Cloud OVH Cloud

Obtenir le process en cours

9 réponses
Avatar
PurL
Bonjour,

Je veux faire un exe qui ne peut avoir qu'une seule instance. La o=F9
d'habitude dans ce genre de situation, la nouvelle instance recherche
une =E9ventuelle pr=E9sence d'une autre instance et l'active puis ce
termine. Moi je veux que la nouvelle tue l'ancienne et continue son
execution.

Au lancement, je balaie la liste des process en m=E9moire :

HANDLE hSS =3D CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
bool moreProcs =3D Process32First(hSS, &info);
while (moreProcs)
{
if (strcmp(info.szExeFile,
ExtractFileName(Application->ExeName).c_str()) =3D=3D 0)
{
HANDLE hProcess =3D OpenProcess(PROCESS_ALL_ACCESS, true,
info.th32ProcessID);
if (hProcess !=3D NULL) TerminateProcess(hProcess,0);

}
moreProcs =3D Process32Next(hSS, &info);
}
CloseHandle(hSS);

et quand je retrouve le nom de l'exe je le kill.
Le probleme c'est que je trouve le nom de l'instance qui est en train
de se cr=E9er. Et donc je me kill moi meme. Pour =E9viter ce pb,
j'aimerais rajouter dans le if (hProcess !=3D NULL) une condition du type
if ((hProcess !=3D NULL) && (hProcess !=3D hCurrentProcess))

Mais comment r=E9cup=E9rer le current process ?

Merci,

PurL.

9 réponses

Avatar
Christian ASTOR
PurL a écrit :

Mais comment récupérer le current process ?



Et GetCurrentProcess() ?
Avatar
Arnaud Debaene
PurL wrote:
Bonjour,

Je veux faire un exe qui ne peut avoir qu'une seule instance. La où
d'habitude dans ce genre de situation, la nouvelle instance recherche
une éventuelle présence d'une autre instance et l'active puis ce
termine. Moi je veux que la nouvelle tue l'ancienne et continue son
execution.

Au lancement, je balaie la liste des process en mémoire :

HANDLE hSS = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
bool moreProcs = Process32First(hSS, &info);
while (moreProcs)
{
if (strcmp(info.szExeFile,
ExtractFileName(Application->ExeName).c_str()) == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, true,
info.th32ProcessID);
if (hProcess != NULL) TerminateProcess(hProcess,0);

}
moreProcs = Process32Next(hSS, &info);
}
CloseHandle(hSS);

et quand je retrouve le nom de l'exe je le kill.
Le probleme c'est que je trouve le nom de l'instance qui est en train
de se créer. Et donc je me kill moi meme. Pour éviter ce pb,
j'aimerais rajouter dans le if (hProcess != NULL) une condition du
type if ((hProcess != NULL) && (hProcess != hCurrentProcess))



Chrsitian t'a dèjà répondu pour GetCurrentProcess. Ceci-dit, ta solution
n'est pas la bonne pour plusieurs raisons :

- Quid si un autre programme a le même nom que le tien ou bien si
l'utilisateur renomme ton exe?
- Quid si 2 instances de ton programme sont lancées en même temps, ou
quasiment en même temps? Il y a un risque de race-condition....
- C'est toujours une très mauvaise idée de tuer un processus, ca ne doit
être que une solution en cas de problème, pas le fonctionnement normal de
l'application (risque de données corrompues, etc...).

La bonne solution serait plutôt :
- Au démarrage, tu tentes de créer un Event manual-reset nommé avec un nom
vraiement unique (un GUID par exemple).
- Si la création réussit et GetLastError renvoie 0, tu es la 1ère instance
de ton programme, et tu peux continuer tranquillement ta vie. Prend juste le
soin de démarrer un thread dont le seul but est d'attendre sur ton event
nommé.
- Si la création réussit mais que GetLastError renvoie ERROR_ALREADY_EXISTS,
il y a déjà une auter instance du programme qui tourne. Dans ce cas, tu fais
un SetEvent sur l'Event nommé, ce qui laisse une chance à la 1ère instance
de se terminer proprement sans être tuée (c'est pour çà qu'il y a un thread
en attente sur l'Event).

Avec cette méthode, tu n'est plus dépendant du nom de l'exécutable et tu
t'affranchis de tout risque de race-condition.

Arnaud
MVP - VC
Avatar
PurL
Cette fonction renvoie -1.
Avatar
PurL
>- Quid si un autre programme a le même nom que le tien ou bien si
l'utilisateur renomme ton exe?



Impossible

- Quid si 2 instances de ton programme sont lancées en même temps, ou
quasiment en même temps? Il y a un risque de race-condition....



Ce .exe est lancé par un autre programme (programme principal) et ne
peut etre executé de manière autonome. Mais le programme principal
peut planter et le .exe dépendant n'a pu lieu d'etre et à sa
prochaine execution doit killer l'instance existante.
Je ne veux pas que ce soit le programme principale qui fasse le ménage

- C'est toujours une très mauvaise idée de tuer un processus, ca ne d oit
être que une solution en cas de problème, pas le fonctionnement normal de
l'application (risque de données corrompues, etc...).



C'est effectivement uniquement en cas de pb
Avatar
Christian ASTOR
PurL a écrit :

Cette fonction renvoie -1.



GetCurrentProcessId()
Avatar
Arnaud Debaene
PurL wrote:
- Quid si un autre programme a le même nom que le tien ou bien si
l'utilisateur renomme ton exe?



Impossible


Ah bon? Pourquoi?

- Quid si 2 instances de ton programme sont lancées en même temps, ou
quasiment en même temps? Il y a un risque de race-condition....



Ce .exe est lancé par un autre programme (programme principal) et ne
peut etre executé de manière autonome. Mais le programme principal
peut planter et le .exe dépendant n'a pu lieu d'etre et à sa
prochaine execution doit killer l'instance existante.
Je ne veux pas que ce soit le programme principale qui fasse le ménage



Et qu'est ce qui empêche l'utilisateur de lancer à la main l'exe?

Arnaud
MVP - VC
Avatar
Arnold McDonald \(AMcD\)
PurL wrote:

Au lancement, je balaie la liste des process en mémoire :



Très mauvaise idée. Personne ne peut être sûr qu'une autre
application/processus n'ait pas le même nom que le tien...

Tu devrais plutôt passer par un mutex ou un event (voir réponse de Debaene)
et, par exemple, gerer une liste commune en mémoire des dates de création
des divers processus de ton application. Dès qu'une entrée est crée et est
plus récente que les autres (en théorie, seules 2 entrées suffisent), la
plus ancienne envoie un message à son processus parent pour se tuer et le
nouveau prend la main.

--
Arnold McDonald (AMcD) - Help #28/2006

http://arnold.mcdonald.free.fr/
Avatar
Aurelien Regat-Barrel
PurL a écrit :

- Quid si 2 instances de ton programme sont lancées en même temps, ou
quasiment en même temps? Il y a un risque de race-condition....




Ce .exe est lancé par un autre programme (programme principal) et ne
peut etre executé de manière autonome. Mais le programme principal
peut planter et le .exe dépendant n'a pu lieu d'etre et à sa
prochaine execution doit killer l'instance existante.
Je ne veux pas que ce soit le programme principale qui fasse le ménage



Ton exe fils ne peut pas s'auto-terminer si son papa meurt ? (passage du
pid du père en ligne de commande...)

--
Aurélien Regat-Barrel
Avatar
John Deuf
PurL :

Ce .exe est lancé par un autre programme (programme principal)



Une DLL ne conviendrait pas mieux ?

--
John Deuf