Page 1 sur 3
[Résolu] Empêcher un exécutable de se lancer plus d'une fois
Publié : jeu. 24/oct./2019 9:42
par Micoute
Bonjour à tous,
ce n'est pas que ce soit embêtant, mais j'aimerais que me programmes compilés ne puissent pas être relancés s'ils sont déjà en exécution.
Il y a certainement une méthode, mais je ne la connais pas, alors si vous la connaissez, voulez-vous s'il vous plaît m'en faire profiter ?
Je vous en remercie d'avance.
Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : jeu. 24/oct./2019 10:45
par Ar-S
J'utilisais ça il y a un moment.
A voir s'il marche encore.
Code : Tout sélectionner
;Autor: ts-soft
EnableExplicit
Procedure CheckRunningPureBasic(Name.s)
Protected result.l, Snapshot.l, ProcessFound.l, PN$, Process.PROCESSENTRY32
Process\dwSize = SizeOf(PROCESSENTRY32)
Snapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, 0)
If Snapshot
ProcessFound = Process32First_(Snapshot, Process)
While ProcessFound
PN$ = UCase(PeekS(@Process\szExeFile, #PB_Any, #PB_Ascii))
If UCase(Name) = GetFilePart(PN$) : result = #True : Break : EndIf
ProcessFound = Process32Next_(Snapshot, Process)
Wend
CloseHandle_(Snapshot)
EndIf
ProcedureReturn result
EndProcedure
If CheckRunningPureBasic("PureBasic.exe")
MessageRequester("","Programme est en cours d'exécution.",0)
Else
MessageRequester("","Rien lancé.",0)
EndIf
Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : jeu. 24/oct./2019 12:55
par Micoute
Merci beaucoup Ar-s, mais hélas apparemment il ne fonctionne pas chez moi, peut-être que c'est dû au fait que j'utilise la version x64.
Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : jeu. 24/oct./2019 13:50
par Marc56
Sans API
Code : Tout sélectionner
; Vérification de la présence d'un programme en mémoire
; Marc56 - 24/10/19 - PureBasic toutes versions - Windows >= 2000
; Utilisation de la commande Windows tasklist.exe
; Ligne de commande qui est envoyée:
; tasklist /FI "IMAGENAME eq PureBasic.exe"
; tasklist /? pour voir les autres possibilités
EnableExplicit
Define MyProgram$ = "PureBasic.exe"
Define Parameter$ = "/FI "+ Chr(34) + "IMAGENAME eq " + MyProgram$ + Chr(34) + " /NH"
Debug Parameter$
Define Run = RunProgram("tasklist", Parameter$, "", #PB_Program_Open | #PB_Program_Read)
If Run
Define Line$, Running$
Debug "-----------------------------------"
While ProgramRunning(Run)
If AvailableProgramOutput(Run)
Define Line$ = ReadProgramString(Run)
Debug Line$
Running$ + Line$
EndIf
Wend
Debug "-----------------------------------"
CloseProgram(Run)
Else
Running$ = "Rien"
EndIf
If StringField(Running$, 1, " ") = MyProgram$
MessageRequester("Désolé.",
MyProgram$ + " est déjà en fonctionnement.",
#PB_MessageRequester_Warning)
Else
MessageRequester("Information",
"OK, la place est libre",
#PB_MessageRequester_Info)
EndIf
End
Mais ceci marche pour un autre programme que celui en cours.
Pour que le programme se teste lui-même il faut compter la présence de plus d'une fois le même nom.

Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : jeu. 24/oct./2019 14:07
par Zorro
comme ça , ça fonctionne bien
Code : Tout sélectionner
; Code de Nico :o)
; verifie si le prg en cours est deja lancé
; Lancez ce code 2 fois
; vous verrez que la deuxieme fois il est fermé
Declare deja_lance(Application.s)
Application.s= "Mon application" ; nom de l'application a empecher de se lancer 2 fois
;Le Programme de test :
deja_lance(Application.s) ; on test si le prg est deja lancé
If OpenWindow (0, 431, 186, 325, 214, Application,#PB_Window_SystemMenu) ; ici on a bien mis le meme NOM c'est important !!
Repeat
Event= WaitWindowEvent ()
Until Event = #PB_Event_CloseWindow
EndIf
CloseHandle_(Hmutex)
End
; **************** Procedure Zone ***************************
Procedure deja_lance(Application.s)
#MUTEX_ALL_ACCESS = $1F0001
Hmutex = OpenMutex_( #MUTEX_ALL_ACCESS , #False ,Application)
If Hmutex=0
Hmutex = CreateMutex_( #Null , #True , Application)
If Hmutex=0
End
EndIf
Else
Handle= FindWindow_( #Null , Application)
ShowWindow_(Handle, #SW_HIDE )
ShowWindow_(Handle, #SW_MINIMIZE )
ShowWindow_(Handle, #SW_RESTORE )
End
EndIf
EndProcedure
Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : jeu. 24/oct./2019 15:43
par Marc56
@Zorro: chapeau!

Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : jeu. 24/oct./2019 19:54
par Ollivier
Une méthode sans API et multi-plateforme.
1) Vérifie si "AlreadyExecuted.TXT" existe.
2) Si oui, terminer le programme
3) Si non, créée un fichier vide "AlreadyExecuted.TXT"
4) Exécution normale du programme.
5) Destruction du fichier "AlreadyExecuted.TXT"
6) Fin de programme
Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : jeu. 24/oct./2019 20:40
par Ar-S
Pas con cette idée Ollivier.
Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : jeu. 24/oct./2019 22:30
par Naheulf
L'idée d'Olivier est une fausse bonne idée.
En occurrence cela pose problème si le programme est interrompu de manière brutale:
1) Vérifie si "AlreadyExecuted.TXT" existe.
2) Si oui, terminer le programme
3) Si non, créée un fichier vide "AlreadyExecuted.TXT"
4) Exécution normale du programme.
5) Fermeture anticipée du programme (crash, perte d'alimentation de l'ordinateur, mise à jour windows, ...)
1) Vérifie si "AlreadyExecuted.TXT" existe.
2) Si oui, terminer le programme
1) Vérifie si "AlreadyExecuted.TXT" existe.
2) Si oui, terminer le programme
Sans compter qu'en l'état ça ne fonctionne pas si le programme est lancé rapidement plusieurs d'fois d'affilé...
Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : ven. 25/oct./2019 7:18
par GallyHC
Bonjour,
Pour l'idée d'Ollivier, oui comme le dit "Naheulf" c'est une fausse bonne idée vu comme cela. Mais si on "lock" le fichier (on l'ouvre mais on ne le ferme pas), celui-ci ne peut être écrit par un autre instance d'un programme. Donc on test si on peut écrire dans ce fichier et si oui c'est que le programme et non actif normalement (PB et bien fait a ce sujet de mémoire, il ferme les fichiers même en cas de plantage et au pire on gère le plantage avec un "OnErrorCall").
Cordialement,
GallyHC
Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : ven. 25/oct./2019 9:45
par Zorro
ben le plus simple reste la methode du mutex ...
Reedit
j'ajoute que le code que j'ai posté est un code de Nico ...
j'ai mis un moment a retrouver l'auteur ... sorry
ce code n'etait pas Taggé ....ce qui est étonnant dans mes archives...
mais ça me chatouillais de ne pas savoir qui etait l'auteur a qui j'ai piqué ce code ..
j'aurai du le savoir, car a Nico, je lui ai piqué pleins de trucs
topic original :
https://www.purebasic.fr/french/viewtop ... emier+plan.
voila, rendons a César
Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : ven. 25/oct./2019 10:30
par GallyHC
@Zorro > le plus simple pour windows oui, d’ailleurs c'est la solution que j'utilise moi aussi.
Par contre pour du multiOS c'est peut-être une solution viable et je ne répondais que sur le fait de rendre la solution plus viable ^^.
Cordialement,
GallyHC
Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : ven. 25/oct./2019 10:35
par Marc56
Une version avec utilisation des Semaphores et API (par netmaestro)
http://forums.purebasic.com/english/vie ... 061#p95061
Code : Tout sélectionner
; Basé sur un code de netmaestro
; http://forums.purebasic.com/english/viewtopic.php?p=95061#p95061
*a = CreateSemaphore_(null,0,1,"PreviewModeSemaphore")
If *a <> 0 And GetLastError_()= #ERROR_ALREADY_EXISTS
MessageRequester("Erreur", "Le programme est déjà lancé")
; CloseHandle_(*a)
; End
Else
MessageRequester("", "Running...")
EndIf
Peut-on faire la même chose avec les fonctions Semaphore (ou Mutex) de PB ?
Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : ven. 25/oct./2019 13:19
par Ar-S
Excellent ce code de netmaestro.
Merci pour la trouvaille.
Re: Empêcher un exécutable de se lancer plus d'une fois
Publié : ven. 25/oct./2019 13:52
par cage
Bonjour a tous,
Une façon de faire en utilisant les Mutex
Si l'application est déjà lancée, il est possible de
- ne rien faire
- lancer une nouvelle instance
- réactiver la première instance
Dans l'exemple si dessous, je réactive la première instance de l'application si lancée.
cage
Code : Tout sélectionner
EnableExplicit
OnErrorGoto(?ErrorHandler)
Global Mutex
#appname = "Mon application"
#runonce = #True ; une seule instance autorisée.
;;; https://msdn.microsoft.com/en-us/library/windows/desktop/cc144179%28v=vs.85%29.aspx
Global TB_Message = RegisterWindowMessage_("TaskbarCreated")
CompilerIf #PB_Compiler_Debugger ; choisir une valeur pour Mutex
;; On est dans l'IDE
;; Valeur utilisée uniquement dans l'IDE
;; Utilisez une valeur inférieure a 1000 (mille).
#winMain = 999
CompilerElse
;; L'application est compilée.
;; Valeur utilisée par Mutex si besoin.
;; Utiliser une valeur unique par application.
;; Valeur du Mutex = "WindowClass_1111"
#winMain = 1111
CompilerEndIf
CompilerIf #PB_Compiler_Debugger
;; On est dans l'IDE
CompilerElse
;; L'application est compilée.
If TB_Message
Mutex = CreateMutex_(#Null, #False, #appname)
If GetLastError_() = #ERROR_ALREADY_EXISTS And #runonce ; une seule instance autorisée
;;;
;;; Same Mutex in memory, that same app is running ???
;;;
Define hWnd = FindWindow_("WindowClass_"+Str(#winMain), #NUL)
If hWnd
;;;
;;; Same Mutex in memory and same ClassName, no doubt, is the same app.
;;;
SendMessage_(hWnd,#WM_SYSCOMMAND, #SC_RESTORE,0)
SetForegroundWindow_(hWnd)
End
Else
;;;
EndIf
EndIf
Else
;; Desktop is not activated, then no TaskBar (TB)
End
EndIf
CompilerEndIf
; Form
ExamineDesktops()
#appWidth = 550
#appHeight = 170
Define X = (DesktopWidth(0)-#appWidth)/2
Define Y = (DesktopHeight(0)-#appHeight)/2
Define Flags = #PB_Window_TitleBar|#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget
If OpenWindow(#winMain, X, Y, #appWidth, #appHeight, #appname, Flags)
Define Event, indexMenu, indexGadget, indexGadgetType
Repeat
Event = WaitWindowEvent(20)
Select Event
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
EndIf
ErrorHandler:
Define lHwd = FindWindow_("Progman", #NUL)
ShowWindow_(lHwd, 8)
ReleaseMutex_(Mutex)
End