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);
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))
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);
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
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);
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.
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);
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.
>- 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
>- 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...).
>- 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...).
- 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
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?
- 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
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/
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.
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/
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
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...)
- 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
John Deuf
PurL :
Ce .exe est lancé par un autre programme (programme principal)
Une DLL ne conviendrait pas mieux ?
-- John Deuf
PurL :
Ce .exe est lancé par un autre programme (programme principal)