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 : 6992
 - 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 ^^.
- 
				lepiaf31
 - 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()