Page 1 sur 1

Comment savoir si un exécutable est actif ?

Publié : mar. 19/févr./2019 0:15
par cage
Bonjour a tous,

Je suis a la recherche d'une solution simple pour savoir si un exe est déjà lancé.
Je met un bout de code qui fonctionne bien et que j'utilise depuis le début, mais j'aimerais savoir si vous avez une solution plus moderne a me proposer.
Merci d'avance,
CAGE

Code : Tout sélectionner

EnableExplicit

Procedure.i getNamePID(ProcessName.s,*ptrPID)
  Protected HSnap.l,Prec.processentry32,result.l=#False
  HSnap=CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS,0)
  If HSnap=#INVALID_HANDLE_VALUE
    ProcedureReturn result
  EndIf
  Prec\dwSize=SizeOf(prec)
  If Not Process32First_(HSnap,Prec)
    ProcedureReturn result
  EndIf
  Repeat
    If LCase(GetFilePart(PeekS(@Prec\szexefile)))=LCase(ProcessName)
      PokeL(*ptrPID,Prec\th32ProcessID)
      result=#True
      Break
    EndIf
  Until Not Process32Next_(HSnap,Prec)
  CloseHandle_(HSnap)
  ProcedureReturn result
EndProcedure

Repeat
  Define ptrPID = 0
  Define ExeName$ = "Notepad.exe"
  ClearDebugOutput()
  If getNamePID(ExeName$,@ptrPID)
    Debug "Notepad est lancé!"
  Else
    Debug "Notepad n'est pas lancé!"
  EndIf
  Sleep_(3000)
ForEver

Re: Comment savoir si un exécutable est actif ?

Publié : mar. 19/févr./2019 0:46
par Ar-S
Salut
Ne vaudrait-il pas mieux virer ton Sleep_() (si je puis dire :D ) et mettre ta vérif dans un timer ?

Re: Comment savoir si un exécutable est actif ?

Publié : mar. 19/févr./2019 7:04
par Marc56
Je suis a la recherche d'une solution simple pour savoir si un exe est déjà lancé.
Tasklist.exe avec runprogram()

ex: tasklist /fi "imagename eq notepad.exe"
puis ensuite un findstring sur le résultat

:wink:

Re: Comment savoir si un exécutable est actif ?

Publié : mar. 19/févr./2019 9:02
par PAPIPP
Bonjour Cage

Tu peux trouver ton bonheur dans WINAPI de RDBASIC

https://www.purebasic.fr/french/viewtop ... lit=winapi

De prg fonctionne maintenant en 4 langues dont le français.

A+

Re: Comment savoir si un exécutable est actif ?

Publié : mar. 19/févr./2019 13:35
par cage
Bonjour,

@Ar-S
Salut
Ne vaudrait-il pas mieux virer ton Sleep_() (si je puis dire :D ) et mettre ta vérif dans un timer ?
Je cherche a améliorer le programme suivant
La procédure de base:

Code : Tout sélectionner

Procedure serviceThread(idThread.l)
;Here goes the service's job...
; Modifier cette procédure pour ajouter les actions a effectuer
; Call TaskKill.exe /f /im CompatTelRunner.exe
 
  Repeat
    RunProgram("TaskKill.exe", "/f /im CompatTelRunner.exe", #Null$, #PB_Program_Hide)
    Sleep_(3000)
  ForEver
EndProcedure
Plutôt que lancer sans arrêt un TaskKill, je voudrais tester si le processus CompatTelRunner.exe est actif.
Pour mon Sleep_(), je préfererais le garder, je me sens mieux avec. :D
Surtout que la procédure est un Thread.
La procédure actuelle:

Code : Tout sélectionner

Procedure serviceThread(idThread.l)
;Here goes the service's job...
; Modifier cette procédure pour ajouter les actions a effectuer
; Call TaskKill.exe /f /im CompatTelRunner.exe
 
  Repeat
    Protected ptrPID = 0
    Protected ExeName$ = "CompatTelRunner.exe"
    If getNamePID(ExeName$,@ptrPID)
      RunProgram("TaskKill.exe", "/f /im " + ExeName$, #Null$, #PB_Program_Hide)
    EndIf
    Sleep_(3000)
  ForEver
EndProcedure
@Marc56
Tasklist.exe avec runprogram()

ex: tasklist /fi "imagename eq notepad.exe"
puis ensuite un findstring sur le résultat
Beaucoup trop lourd pour un service qui tourne en tache de fond.

@PAPIPP
Merci pour le lien.
J'ai commencé a regarder et je pense que je vais y trouver plein de choses qui vont me servir.

Si vous avez une idée pour simplifier/améliorer la procédure getNamePID(ExeName$,@ptrPID)
Merci.

Re: Comment savoir si un exécutable est actif ?

Publié : mar. 19/févr./2019 14:21
par Marc56
Pourquoi utiliser l'API Sleep_ plutôt que la commande PB Delay() ?

Si tu met une boucle dans un thread (donc sans doute une deuxième), ton programme risque de fonctionner d'une manière erratique. Je te conseillerais plutôt de mettre un timer dans la boucle principale qui appellera alors la procédure (en thread si tu veux garder la main sur le reste du programme) pour fermer le service. Un timer sur 3 secondes sera plus fiable que ton Sleep_(3000) dans la procédure.


CompatTelRunner, chez moi il ne se déclenche plus (Windows 10), sans doute depuis que j'ai désactivé presque toutes les options « d'expérience utilisateur » dans la panneau de configuration.

Paramètres > confidentialité > Diagnostics et commentaires

:wink:

Re: Comment savoir si un exécutable est actif ?

Publié : mar. 19/févr./2019 16:24
par boby

Re: Comment savoir si un exécutable est actif ?

Publié : mar. 19/févr./2019 18:00
par cage
@Marc56 :
Effectivement, Sleep_(3000) remplacé par Delay(3000)
Je vais voir pour ajouter un Timer et faire le test.
Chez moi, malheureusement, CompatTelRunner se déclenche a chaque démarrage et a chaque fois que je met à jour un logiciel.
Vu ma petite configuration Intel Celeron, cela me bloque le PC pendant 5 bonnes minutes ou plus.
Tous les paramètres sont bien positionnés pour n'envoyer que le minimum.
Je n'ai pas de compte Microsoft sur mon PC
Voila aussi a quoi me sert ce service Windows:
La procédure complète qui me permet de retrouver certains services dans l'état que je souhaite a chaque démarrage, même après un Windows Update qui a souvent tendance a réactiver les services Sysmain et WSearch
Je posterai la procédure modifiée lorsque j'aurais ajouté le Timer
CAGE

Code : Tout sélectionner

Procedure serviceThread(idThread.l) ; ; Here goes the service's job...
  ; Here goes the service's job...
  ; Modifier cette procédure pour effectuer les actions désirées
  
  ; QHActiveDefense : 360 Total Security
  
  ; RunProgram("sc.exe" , "config QHActiveDefense start= demand", #Null$, #PB_Program_Hide)
  
  ; BoxSyncUpdateService : Updater for Box Sync
  
  RunProgram("sc.exe" , "config BoxSyncUpdateService start= demand", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop BoxSyncUpdateService", #Null$, #PB_Program_Hide)
  
  ; DbxSvc : Dropbox Service
  
  RunProgram("sc.exe" , "config DbxSvc start= demand", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop DbxSvc", #Null$, #PB_Program_Hide)
  
  ; Emby : The windows background service for Emby Server.
  
  RunProgram("sc.exe" , "config Emby start= demand", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop Emby", #Null$, #PB_Program_Hide)
  
  ; MEmuSVC : 
  
  RunProgram("sc.exe" , "config MEmuSVC start= demand", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop MEmuSVC", #Null$, #PB_Program_Hide)
  
  ; SbieSvc : SandBoxie Service
  
  RunProgram("sc.exe" , "config SbieSvc start= demand", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop SbieSvc", #Null$, #PB_Program_Hide)
  
  ; gupdate : Service Google Update (gupdate)
  
  RunProgram("sc.exe" , "config gupdate start= demand", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop gupdate", #Null$, #PB_Program_Hide)
  
  ; gupdatem : Service Google Update (gupdatem)
  
  RunProgram("sc.exe" , "config gupdatem start= demand", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop gupdatem", #Null$, #PB_Program_Hide)
  
  ; dbupdate : Service Mise à jour Dropbox (dbupdate)
  
  RunProgram("sc.exe" , "config dbupdate start= demand", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop dbupdate", #Null$, #PB_Program_Hide)
  
  ; dbupdatem : Service Mise à jour Dropbox (dbupdatem)
  
  RunProgram("sc.exe" , "config dbupdatem start= demand", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop dbupdatem", #Null$, #PB_Program_Hide)
  
  ; uSHAREitSvc : SHAREit Hotspot Service
  
  RunProgram("net.exe", "stop uSHAREitSvc", #Null$, #PB_Program_Hide)
  
  ; Spooler : Spouleur d’impression
  
  RunProgram("sc.exe" , "config Spooler start= demand", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop Spooler", #Null$, #PB_Program_Hide)
  
  ; SysMain : Gère et améliore les performances du système dans le temps.
  
  RunProgram("sc.exe" , "config SysMain start= disabled", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop SysMain", #Null$, #PB_Program_Hide)
  
  ; TomTomHOMEService : TomTom Home Service for ejecting devices
  
  RunProgram("sc.exe" , "config TomTomHOMEService start= demand", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop TomTomHOMEService", #Null$, #PB_Program_Hide)
  
  ; tvmosaic_server : C:\Program Files (x86)\DVBLogic\TVMosaic\tvmosaic_server.exe
  
  RunProgram("sc.exe" , "config tvmosaic_server start= demand", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop tvmosaic_server", #Null$, #PB_Program_Hide)
  
  ; Windows Search : Fournit des fonctionnalités d’indexation de contenu, de mise en cache des propriétés,
  ;                  de résultats de recherche pour les fichiers, les messages électroniques et autres contenus.
  
  RunProgram("sc.exe" , "config WSearch start= disabled", #Null$, #PB_Program_Hide)
  
  RunProgram("net.exe", "stop WSearch", #Null$, #PB_Program_Hide)
  
  Repeat
    Protected ptrPID = 0
    Protected ExeName$ = "CompatTelRunner.exe"
    If getNamePID(ExeName$,@ptrPID)
      RunProgram("TaskKill.exe", "/f /im " + ExeName$, #Null$, #PB_Program_Hide)
    EndIf
    Delay(3000)
  ForEver
EndProcedure

Re: Comment savoir si un exécutable est actif ?

Publié : mar. 19/févr./2019 18:14
par cage
@Marc56 :
Comment faire pour ajouter un Timer dans un programme en mode console ?
Je viens de réaliser que ce n'est possible que dans une fenêtre.

Re: Comment savoir si un exécutable est actif ?

Publié : mar. 19/févr./2019 19:04
par Ulix
Salut Cage

Juste une idée en passant, comme ça !

Création une fenêtre en mode invisible, avec rien dedans ! :lol:
Un timer lié a la fenétre, mais rien a l'écran
Une fois compiler tu peu toujours l'appelé en mode console ! A Essayer :P

A+

Ulix

Re: Comment savoir si un exécutable est actif ?

Publié : mar. 19/févr./2019 22:00
par cage
@Ulix
En fait, j'ai créé un service Windows en partant des sources de Pierre Bellisle

Voir: A Windows service that can launch a GUI application in System Administrator mode.

J'ai retiré la procédure "Procedure.l RunAsSystemAdmin(sExeName.s)" que je n'utilise pas

J'ai modifié la procédure "Procedure serviceThread(idThread.l)" pour l'adapter a mon besoin.

Je cherche a améliorer cette procédure pour en tirer le meilleur.

Les 2 buts recherchés:
1) faire certaines actions une seule fois a chaque démarrage du PC
2) monitorer certains événements durant le fonctionnement du PC et interagir avec ces événements (avec ou sans Timer)

Actuellement, j'ai rajouté 3 procédures pour optimiser mon code:
Procedure.i getNamePID(ProcessName.s,*ptrPID)
Procedure netStop(sService.s)
Procedure scConfig(sService.s, sStart.s)

Les sources du service Windows modifié sont téléchargeables ici : abletaskkill_sources.7z
CAGE

Re: Comment savoir si un exécutable est actif ?

Publié : mar. 26/févr./2019 20:37
par nico
Bonjour,

J'ai retrouvé un exemple de srod qui récupère des infos sur les process avec WMI, si je devais défendre ce code qui n'est pas de moi, c'est qu'il permet de savoir aussi bien si un process est lancé ou terminé et assez simple si on omet la bibliothèque bien sûr.

Devrait fonctionner sans GUI.

Code : Tout sélectionner

; Original code from Srod
; source: https://www.purebasic.fr/english/viewtopic.php?f=13&t=47600

; Pour télécharger ComatePlus de Srod
; https://www.purebasic.fr/english/viewtopic.php?p=482355#p482355

;IncludePath "..\..\"
XIncludeFile "COMatePLUS.pbi"
DisableExplicit


Define.COMateObject objWMIService, objProcess, colProcessList
strComputer.s = "."

objWMIService = COMate_GetObject("winmgmts://./root/cimV2")
If objWMIService
  colProcessList = objWMIService\GetObjectProperty("ExecNotificationQuery('SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE TargetInstance ISA $0027Win32_Process$0027')")
  If colProcessList
    OpenWindow(0, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu)
    Repeat
      Event = WaitWindowEvent(1)
      If Event = #PB_Event_CloseWindow  ; If the user has pressed on the close button
        Break
      EndIf
      objProcess = colProcessList\GetObjectProperty("NextEvent(1)")
      If objProcess
        If objProcess\GetStringProperty("TargetInstance\Name") = "notepad.exe"
            Debug objProcess\GetStringProperty("TargetInstance\Name") + " : " + objProcess\GetStringProperty("Path_\Class")    
            Debug =  objProcess\GetStringProperty("TargetInstance\ExecutablePath")
        EndIf
        objProcess\Release()
      EndIf
    ForEver
    colProcessList\Release()
  EndIf
  objWMIService\Release()
Else
  MessageRequester("COMate - WMI demo", "Couldn't create the WMI scripting object!")
EndIf

Re: Comment savoir si un exécutable est actif ?

Publié : jeu. 28/févr./2019 14:42
par cage
Bonjour,

@nico :
Merci pour l'exemple avec ComatePlus.
Je le garde au chaud mais je trouve que cela complexifie les choses.
Surtout pour un service Windows.
Je ne connaissais pas ComatePlus, je vais donc regarder ce que l'on peut faire avec.
Merci a tous.

CAGE