Page 1 sur 2
Comment puis-je savoir si un prog n'est pas déjà lancé?
Publié : lun. 19/févr./2007 13:11
par RV
Au lancement d'un de mes prog, je voudrais savoir s'il n'est pas déjà lancé.
En gros, peut-on vérifier q'il n'est pas présent dans le gestionnaire des tâches?
Merci pour vos réponses!
Re: Comment puis-je savoir si un prog n'est pas déjà lancé?
Publié : lun. 19/févr./2007 13:53
par Backup
RV a écrit :Au lancement d'un de mes prog, je voudrais savoir s'il n'est pas déjà lancé.
En gros, peut-on vérifier q'il n'est pas présent dans le gestionnaire des tâches?
Merci pour vos réponses!
de la part de Nico
#MUTEX_ALL_ACCESS = $1F0001
Application.s= "Mon application"
Hmutex = OpenMutex_ ( #MUTEX_ALL_ACCESS , #False ,Application)
If Hmutex=0
;Si le mutex existe alors l'application est déjà lancée.
;sinon on le crée
Hmutex = CreateMutex_ ( #Null , #True , Application)
If Hmutex=0
;Fin du programme mutex non créer
End
EndIf
Else
;On recherche l'application
;pour la mettre au premier plan.
Handle= FindWindow_ ( #Null , Application)
ShowWindow_ (Handle, #SW_HIDE )
ShowWindow_ (Handle, #SW_MINIMIZE )
ShowWindow_ (Handle, #SW_RESTORE )
End
EndIf
;Le reste du code ici
If OpenWindow (0, 431, 186, 325, 214, #PB_Window_SystemMenu , Application)
Repeat
Event= WaitWindowEvent ()
Until Event = #PB_EventCloseWindow
EndIf
CloseHandle_ (Hmutex)
End
Publié : lun. 19/févr./2007 14:19
par Jacobus
une autre façon de faire qui me paraît plus simple à gérer
(c'est un code de Julien il me semble) je l'ai commenté car il faut garder à l'esprit que c'est le nom de la fenêtre qui est recherché et pas le nom de l'exécutable. Créer un exe à partir de l'exemple pour tester.
Code : Tout sélectionner
;Vérification programme en cours
#Application = "Mon programme" ; Il faut le nom de la fenêtre et NON celui de l'exécutable!
Procedure ExeLance(nomfenetre$)
F=FindWindow_(0, nomfenetre$)
If F<>0
ProcedureReturn 1 ; retourne 1 si détecté
Else
ProcedureReturn 0 ; retourne 0 si non détecté
EndIf
EndProcedure
Enumeration
#WIN:#BtnClose
EndEnumeration
res=ExeLance(#Application);on passe le nom de la fenêtre en param
;en fonction de l'état de la fenêtre, celle-ci est restaurée au premier plan
;ou le programme est démarré s'il ne l'était pas
If res=1
Handle=FindWindow_(#Null, #Application)
ShowWindow_(Handle,#SW_HIDE)
ShowWindow_(Handle,#SW_MINIMIZE)
ShowWindow_(Handle,#SW_RESTORE)
End
EndIf
If OpenWindow(#WIN,0,0,300,200, #Application, #PB_Window_SystemMenu| #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_TitleBar)<>0 And CreateGadgetList(WindowID(#WIN))<>0
ButtonGadget(#BtnClose,20,20,260,160,"FERMER")
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget
Select EventGadget()
Case #BtnClose:Event = #PB_Event_CloseWindow
EndSelect
EndIf
Until Event = #PB_Event_CloseWindow
EndIf
End
Publié : lun. 19/févr./2007 16:24
par brossden
Le programme de Dobro me parait trés fiable, alors que celui de Jacobus sousentend que l'on connais en permance le Libellé qui est dans la fenetre, mais comment resoudre le problème des programmes qui font évoluer ce même libéllé (par exemple avec un pourcentage d'une fonction longue à effectuée, style un téléchargement....
Deplus je ne vois vraiment pas la simplicité apportée !
Publié : lun. 19/févr./2007 17:43
par Jacobus
C'est pourtant pas compliqué...
J'ai mis l'exemple avec une constante, mais initialement c'est une variable chaîne qui est passée en paramètre. Donc tu peux la faire varier, non? Pour ce qui est de la simplicité, ne pas utiliser de mutex me paraît entrer dans cet optique, mais c'est mon point de vue.
Quant à la fiabilité du code proposé par Dobro, je ne la remet pas en cause, je m'en suis déjà servi. A contrario, tu déclares, en clair, que j'aurai mieux fais de m'abstenir plutôt que de proposer ce code.
Donc si ça ne te plaît pas c'est pareil

Publié : lun. 19/févr./2007 18:04
par Sami
Voila d'un source code bien utile. Justement je cherchais une solution à ce problème pour un programme perso.
Le code donné par Jacobus est portable par rapport à celui de Dobro. Ce qui m'interesse plus dans mon cas, car mon programme doit tourner sous Windows, Linux et MacOs.
En tout ca merci à vous deux! Vous avez fait un heureux.
Publié : lun. 19/févr./2007 18:15
par Jacobus
Le code donné par Jacobus est portable par rapport à celui de Dobro
Désolé mais je ne crois pas, les deux codes utilisent des API Windows.
Publié : lun. 19/févr./2007 18:26
par nico
Il est peut être possible d'en faire un tout en Pb vu qu'il intègre maintenant les fonctions Mutex mais il manquerait apparemment IsMutex, a essayé en tout cas.
Publié : mar. 20/févr./2007 13:11
par Kwai chang caine
Bonjour à tous
Pour tester le nombre d'instances d'un programme présent dans le gestionnaire des taches, j'avais trouvé ce code.
Il marche super bien et teste bien le nom du giciel comme il apparait dans le gestionnaire des taches, car avec les fenetres c'est moins sûr comme le dit BROSSDEN.
Honte à moi je ne me rapelle plus de qui il est.
Il etait plus complet, mais j'ai gardé la partie NT.
Code : Tout sélectionner
Procedure NombreInstancesProgramme(Programme.s) ; Version pour NT seulement
Structure PROCESS_MEMORY_COUNTERS
cb.l
PageFaultCount.l
PeakWorkingSetSize.l
WorkingSetSize.l
QuotaPeakPagedPoolUsage.l
QuotaPagedPoolUsage.l
QuotaPeakNonPagedPoolUsage.l
QuotaNonPagedPoolUsage.l
PageFileUsage.l
PeakPagefileUsage.l
EndStructure
#OWNER_SECURITY_INFORMATION = $00000001
#GROUP_SECURITY_INFORMATION = $00000002
#DACL_SECURITY_INFORMATION = $00000004
#SACL_SECURITY_INFORMATION = $00000008
#PROCESS_TERMINATE = $0001
#PROCESS_CREATE_THREAD = $0002
#PROCESS_SET_SESSIONID = $0004
#PROCESS_VM_OPERATION = $0008
#PROCESS_VM_READ = $0010
#PROCESS_VM_WRITE = $0020
#PROCESS_DUP_HANDLE = $0040
#PROCESS_CREATE_PROCESS = $0080
#PROCESS_SET_QUOTA = $0100
#PROCESS_SET_INFORMATION = $0200
#PROCESS_QUERY_INFORMATION = $0400
#PROCESS_ALL_ACCESS = #STANDARD_RIGHTS_REQUIRED | #SYNCHRONIZE | $FFF
#NbProcessesMax = 10000
Global Dim ProcessesArray(#NbProcessesMax)
Global Dim ListeProceduresEnCours.s(500)
If OpenLibrary(0, "psapi.dll")
EnumProcesses = GetFunction(0, "EnumProcesses")
EnumProcessModules = GetFunction(0, "EnumProcessModules")
GetModuleBaseName = GetFunction(0, "GetModuleBaseNameA")
If EnumProcesses And EnumProcessModules And GetModuleBaseName ; Be sure we have detected all the functions
CallFunctionFast(EnumProcesses, ProcessesArray(), #NbProcessesMax, @nProcesses)
x = 0
For k = 1 To nProcesses / 4
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, ProcessesArray(k-1))
If hProcess
CallFunctionFast(EnumProcessModules, hProcess, @BaseModule, 4, @cbNeeded)
Name$ = Space(255)
CallFunctionFast(GetModuleBaseName, hProcess, BaseModule, @Name$, Len(Name$))
If FindString(Name$, Programme, 1) <> 0
NbreInstance + 1
CloseHandle_(hProcess)
EndIf
CloseHandle_(hProcess)
EndIf
Next
EndIf
CloseLibrary(0)
EndIf
ProcedureReturn NbreInstance
EndProcedure
Si ça peut servir à quelqu'un ???
Publié : mar. 20/févr./2007 17:44
par nico
Je ne vois pas ce qui vous gêne avec les mutex, il y a juste trois fonctions, ouvrir, créer et fermer, c'est assez simple, non?
Publié : mar. 20/févr./2007 19:28
par RV
Je pars sur celui de Dobro mais garde les autres sous le coude.
Merci a vous car je n'avais pas de solution et je me retrouve avec 3.
A+
Publié : mar. 18/août/2009 0:09
par gansta93
Bonjour,
Je fais remonter ce topic parce qu'une question intéressente a été pausée : est-ce possible de faire le même code que Nico mais en version portable en utilisant les mutex via les fonctions PB natives ?
Je ne voi pas comment, mais si quelqu'un a trouvé, je lui en serait reconnaissant pendant un sacré bout de temps ^^.

Publié : mar. 18/août/2009 0:51
par Ollivier
Kwai chang caine a écrit :Honte à moi je ne me rapelle plus de qui il est. Embarassed
De Chris.
Publié : mar. 18/août/2009 14:40
par lepiaf31
J'ai à peu près le même code mais au lieu de vérifier simplement le nom du processus, je vérifie le chemin complet du processus (on ne sait jamais si le nom du processus est le meme que celui d'un autre programme ^^ ):
Code : Tout sélectionner
Procedure ProgramAlreadyLaunch()
Result = 0
library = OpenLibrary(#PB_Any, "psapi.dll")
If library
;on cherche le chemin complet du processus en cours
hCurrentProcess = GetCurrentProcess_()
ProcessPathSize = 1000
ProcessPath.s = Space(ProcessPathSize)
CallFunction(library, "GetModuleFileNameExA", hCurrentProcess, 0, @ProcessPath, ProcessPathSize)
CurrentProcessPath.s = Trim(ProcessPath)
CloseHandle_(hCurrentProcess)
ArraySize = 1000
NbProcesses.l
Dim Processes(ArraySize)
CallFunction(library, "EnumProcesses", @Processes(), ArraySize, @NbProcesses)
NbProcesses = NbProcesses / 4
Found = 0
For i=1 To NbProcesses
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION|#PROCESS_VM_READ, #False, Processes(i-1))
If hProcess
ProcessPathSize = 2000
ProcessPath.s = Space(ProcessPathSize)
CallFunction(library, "GetModuleFileNameExA", hProcess, 0, @ProcessPath, ProcessPathSize) ;chemin du processus
CloseHandle_(hProcess)
;on a trouvé un processus avec le meme chemin de lancement
;/!\ il faut trouver le processus 2 fois: une fois pour le programme en cours et une pour le programme deja lancé
If Trim(ProcessPath) = CurrentProcessPath
Found+1
If Found = 2
Result = 1
Break
EndIf
EndIf
EndIf
Next
CloseLibrary(library)
EndIf
ProcedureReturn Result
EndProcedure
If ProgramAlreadyLaunch()
MessageRequester("Erreur", "Programme déjà lancé")
End
EndIf
OpenConsole()
Input()
Compilez un executable et lancez-le 2 fois, vouz verrez ca marche très bien

Publié : mar. 18/août/2009 16:54
par gansta93
Bien bien, ça en fait du code ^^... mais faut croire que Linux n'est pas très coopératif ou que les fonctions pb sont trop "limitées"... :winkk: