Comment puis-je savoir si un prog n'est pas déjà lancé?
Comment puis-je savoir si un prog n'est pas déjà lancé?
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!
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é?
de la part de NicoRV 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!

#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
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.
(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
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
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 !
Deplus je ne vois vraiment pas la simplicité apportée !
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
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

Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
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.
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.
Désolé mais je ne crois pas, les deux codes utilisent des API Windows.Le code donné par Jacobus est portable par rapport à celui de Dobro
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
- Kwai chang caine
- Messages : 6989
- Inscription : sam. 23/sept./2006 18:32
- Localisation : Isere
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.
Si ça peut servir à quelqu'un ???
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
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 ^^.
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 ^^.

-
- Messages : 510
- Inscription : dim. 25/mars/2007 13:44
- Localisation : Toulouse, France
- Contact :
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 ^^ ):
Compilez un executable et lancez-le 2 fois, vouz verrez ca marche très bien 
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()
