Page 1 sur 1

Trouver un process par son "nom du produit"

Publié : mar. 20/déc./2011 15:29
par blendman
salut

savez-vous s'il est possible de trouver un processus actif par son "nom du produit" ?
Quand on clique droit sur un exe, que l'on fait propriétés, on peut avoir dans "version" :
"le nom du produit".

J’aimerai récupérer ce nom ou un des autres paramètres si c'est possible lorsque l'exe est lancé ou en cours d'éxécution. Savez-vous comment on peut faire ça ?

Merci.

Re: Trouver un process par son "nom du produit"

Publié : mar. 20/déc./2011 19:37
par Ar-S
Pas du tout mais je suis aussi preneur pour récupérer ces différentes infos. :mrgreen:

Re: Trouver un process par son "nom du produit"

Publié : mer. 21/déc./2011 0:05
par PAPIPP
Bonjour Blendman
Dans le forum http://www.purebasic.fr/french/viewtopi ... 33#p136033
J'ai traité ce PB
Voici un exemple des infos que l'on peut trouver avec les API windows

Code : Tout sélectionner

Structure inf_wnd
  pid.l
  hwnd.l
  NOM_EXE.s{#MAX_PATH}
  nom_WND.s{#MAX_PATH}
  ind.w
EndStructure
NewMap info_wdn.inf_wnd()
ProcedureDLL KillProces(Pid) ; Kill a process by specifying it's Pid
  phandle = OpenProcess_ (#PROCESS_TERMINATE, #False, Pid) 
  If phandle <> #Null 
    If TerminateProcess_ (phandle, 1) 
      Result = #True 
    EndIf 
    CloseHandle_ (phandle) 
  EndIf 
  ProcedureReturn Result 
EndProcedure 

Procedure.s GetPIDExePath(hWnd.l)
  pid.l=0
  GetWindowThreadProcessId_(hWnd,@pid)
  hProcess.l=OpenProcess_(#PROCESS_ALL_ACCESS,0,pid);
  Name.s=Space(256)
  
  If OpenLibrary(0,"PSAPI.DLL")
    *F=GetFunction(0,"GetModuleFileNameExA")
    If *F
      CallFunctionFast(*F,hProcess,0,@Name,#MAX_PATH)
    Else
      MessageRequester ("Erreur PSAPI.DLL" ,"Fonction GetModuleFileNameExA non trouvé",0)
      CloseLibrary(0)
      End
    EndIf
  Else
    MessageRequester ("Erreur PSAPI.DLL" ,"Library non ouverte",0)
    End
  EndIf
  ProcedureReturn Str(pid)+"@"+Name
EndProcedure

Procedure find_collision(PID.l,hWnd.l,NOM_exe_path.s,NOM_WND.s,Map INFO_W.inf_wnd(),TYP.s="T")
  Protected indi.l, indi$, type_c.s, NOM_EXE.s
  ;code pour la cle dans map afin d'éviter les collisions
  ; "H"+str(ind)+str(hwnd)
  ; "P"+str(ind)+str(pid)
  ; "E'+str(ind)+Nom_EXE
  ; "W"+str(ind)+NOm_Wnd
  ;*************** Pas de  collision sur handle c'est impossible qu'il puisse y avoir 2 handles  identiques donc info_w()\ind=1
  ;*************** Sur PID j'ai 1 PID double sur Purebasic !!!!
  ;*************** NOM_exe et NOM_WND peuvent être présent en plusieurs occurrences.
  Macro _cherc_coll(_typ,_types)
    indi=0
    Repeat
      indi+1
      indi$=_typ+Str(indi)+" "+_types     ; Blanc ou space sépare le type et son occurrence du nom de la clé. On peut placer ici un autre caractère alpha ou rien
      ;     res_find=FindMapElement(info_w(),indi$)
    Until FindMapElement(info_w(),indi$)=0
    info_w(indi$)\hwnd=hwnd
    info_w()\pid=PID
    info_w()\nom_WND=NOM_WND
    info_w()\NOM_EXE=NOM_EXE_PATH
    info_w()\ind=indi
    If indi>1
      indiM.l=indi
      indi=1
      indi$=_typ+Str(indi)+" "+_types  ; Blanc ou space sépare le type et son occurrence du nom de la clé. On peut placer ici un autre caractère alpha ou rien
      info_w(indi$)\ind=indiM
    EndIf
  EndMacro
  ;code pour la clé dans map afin d'éviter les collisions
  ; "H"+str(ind)+str(hwnd)
  ; "P"+str(ind)+str(pid)
  ; "E'+str(ind)+Nom_EXE
  ; "W"+str(ind)+NOm_Wnd
  ; "T" toutes les clés précédentes
  
  NOM_EXE.s=GetFilePart(NOM_EXE_PATH)
  
  If typ="E" Or typ="T" :type_c="E":  _cherc_coll(type_c,NOM_EXE)   :EndIf
  If typ="P" Or typ="T" :type_c="P":  _cherc_coll(type_c,Str(PID))  :EndIf
  If typ="H" Or typ="T" :type_c="H":  _cherc_coll(type_c,Str(hWnd)) :EndIf
  If typ="W" Or typ="T" :type_c="W":  _cherc_coll(type_c,Nom_Wnd)   :EndIf
  
EndProcedure 
Procedure FindWindowExeName(Map INFO_W.inf_wnd(),TYP.s="T")
  Static  hWnd.l
  ClearMap(info_w()) 
  ;code pour la cle dans map afin d'éviter les collisions sur PID , NOM_EXE et NOM_WND
  ; "H"+str(ind)+str(hwnd)
  ; "P"+str(ind)+str(pid)
  ; "E'+str(ind)+Nom_EXE
  ; "W"+str(ind)+NOm_Wnd
  ; "T" toutes les clés précédentes
  hWnd=FindWindow_(0,0)
  While hWnd<>0
    If GetWindowLong_(hWnd,#GWL_STYLE) & #WS_VISIBLE=#WS_VISIBLE
      If GetWindowLong_(hWnd,#GWL_EXSTYLE) & #WS_EX_TOOLWINDOW<>#WS_EX_TOOLWINDOW
        NOM_WND.s=Space(#MAX_PATH)
        GetWindowText_(hWnd,@NOM_WND,#MAX_PATH)
        hwndp.l=GetParent_(hWnd)
        If NOM_WND<>""
          PID_NOM_EXE_PATH.s=GetPIDExePath(hWnd)
          PID = Val(StringField(PID_NOM_EXE_PATH, 1, "@"))
          NOM_EXE_PATH.s =StringField(PID_NOM_EXE_PATH, 2, "@")
          nom_exe.s=GetFilePart(NOM_EXE_PATH)
          ;************** recherche de collision ***************************	
          find_collision (PID,hWnd,nom_exe_path,NOM_WND, INFO_W(),typ)
        EndIf
      EndIf
    EndIf
    hWnd=GetWindow_(hWnd,#GW_HWNDNEXT)
  Wend
EndProcedure
; ******************* Fin des Procedures de création d'une map avec les principales caractéristiques de chaque fenêtre ********************

RunProgram("calc.exe","","")
RunProgram("calc.exe","","")
Delay(500)
FindWindowExeName(info_wdn(),"T"); Demande de toutes les clés 
Debug "******************************************************************************"
; ForEach info_wdn()
;   Debug _n(info_wdn()\ind) +_n(info_wdn()\hwnd)+" "+_n(info_wdn()\pid)+" "+_s(info_wdn()\nom_WND)+" "+_s(info_wdn()\NOM_EXE)+_s(MapKey(info_wdn()))
; Next
ForEach info_wdn()
  mapkey$=Left(MapKey(info_wdn()),1)
  ;   texte$=MapKey(info_wdn())+Chr(10)+Str(info_wdn()\hwnd)+Chr(10)+Str(info_wdn()\pid)+Chr(10)+GetFilePart(info_wdn()\NOM_EXE)+Chr(10)+info_wdn()\NOM_WND
  texte$="clé="+MapKey(info_wdn())+" hWnd="+Str(info_wdn()\hwnd)+" PID="+Str(info_wdn()\pid)+" NOM_EXE="+GetFilePart(info_wdn()\NOM_EXE)+" NOM_WND="+info_wdn()\NOM_WND+" Occurrence="+Str(info_wdn()\ind)
  Debug texte$
Next
Debug "************************  recherche calc.exe à partir de la clé E1 calc.exe **************************"
clef$="E1 calc.exe"
Resultat = FindMapElement(info_wdn(), clef$)
Define el1.inf_wnd=info_wdn()
If resultat <>0
  ind_max.l=info_wdn()\ind
  For j=1 To ind_max
    clef$="E"+Str(j)+" calc.exe"
    FindMapElement(info_wdn(), clef$)
    texte$="clé="+MapKey(info_wdn())+" hWnd="+Str(info_wdn()\hwnd)+" PID="+Str(info_wdn()\pid)+" NOM_EXE="+GetFilePart(info_wdn()\NOM_EXE)+" NOM_WND="+info_wdn()\NOM_WND+" Occurrence="+Str(info_wdn()\ind)
    Debug texte$+ "  resultat="+Str(resultat)
    ;   Delay(2000) ; temps de 2s pour avoir le temps de situer la calculatrice
      KillProces(info_wdn()\pid) ; suppression de la calculatrice
  Next
Else
  Debug clef$ + " pas touvée"
EndIf
Tout ce que tu cherche se trouve dans la procédure "FindWindowExeName"
@+

Re: Trouver un process par son "nom du produit"

Publié : mer. 21/déc./2011 9:16
par blendman
Papipp : un immense merci !! C'est exactement ce que je cherchais :).

C'est super, ça va me servir pour plusieurs choses (mes updates, vérifier si on a déjà le jeu par exemple pour le mettre à jour automatiquement).
Tiens, à ce propos, j'ai une autre question :
- est-il possible de trouver le "nom du produit" d'un executable (ou un autre élément) sans que celui-ci soit lancé. Ce serait pour vérifier si on a déjà installé mon jeu, pour la mise à jour, mais sans devoir charger le jeu (et au cas où le nom change entre plusieurs versions par exemple).

En tout cas, un très grand merci :).

Re: Trouver un process par son "nom du produit"

Publié : mer. 21/déc./2011 10:26
par PAPIPP
Bonjour Blendman

Pour répondre à ta deuxième question.
Il faut lors de installation de ton Prg :
1) d’une part vérifier qu’il existe bien une clé dans le registre Win propre à to Prg.
2) Vérifier que c’est une version obsolète ou pas avant la MAJ.
3) Sinon créer une clé dans le registre avec tous les éléments que tu désires contrôler.
Voir dans la Droopy.lib
RegCreateKeyValue("HKEY_LOCAL_MACHINE\SOFTWARE\Test\SubKeyAuto","SZ Value","SZ",#REG_SZ,".")
et d'autres fonctions.
@+

Re: Trouver un process par son "nom du produit"

Publié : mer. 21/déc./2011 11:36
par Ar-S
Merci PAPPIP, excellent. :P