IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

[D6] CreateToolhelp32Snapshot sur Terminal Server


Sujet :

API, COM et SDKs Delphi

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 42
    Points : 25
    Points
    25
    Par défaut [D6] CreateToolhelp32Snapshot sur Terminal Server
    Bonjour,

    Déjà désolé si je ne suis pas sur la bonne rubrique du forum, je ne savais pas vraiment ou placer cette requête. Mais comme il s'agit d'une fonction de l'API Windows je me suis permis de mettre ce post ici.

    Nous utilisons actuellement sur notre logiciel un bout de code permettant de créer une liste des processus afin de contrôler si un programme est ouvert ou non. Pour créer la liste nous utilisons la fonction windows CreateToolhelp32Snapshot. Le problème apparaît pour les clients étant sur Terminal Server. En effet cette fonction a l'air d'afficher les processus de toutes les sessions Terminal.

    Le but final étant que j'aie une liste uniquement des processus ouverts par la session en question (Affichage standard lorsque l'utilisateur accède à son gestionnaire de tâche d'ailleurs). Je n'ai malheureusement rien trouvé sur le net, pourriez-vous m’aiguiller si il est possible de le faire via cette fonction ou faut-il chercher une autre logique que notre code actuel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    Function ExeRunning (NomApplication : Ansistring) : Cardinal;
     
    Var
       ProcListExec : TProcessentry32;
       PrhListExec : Thandle;
       Flag : boolean;
     
    begin
         Result:=0;
         ProcListExec.dwSize:=sizeof(ProcListExec);
         try
            PrhListExec:=CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
            if (PrhListExec <> INVALID_HANDLE_VALUE) then
            begin
                 Flag:=True;
                 Process32First(PrhListExec,ProcListExec);
                 while Flag = True do
                 begin
                      if (Uppercase(ExtractFileName(ProcListExec.szExeFile)) = Uppercase(ExtractFileName (NomApplication))) then
                      begin
                           Result:=ProcListExec.th32ProcessID;
                           Flag:=False;
                      end
                      else
                      Flag:=Process32Next(PrhListExec,ProcListExec);
                 end;
            end;
         finally
                CloseHandle(PrhListExec);
         end;
    end;

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 679
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 679
    Points : 13 083
    Points
    13 083
    Par défaut
    Tu as l'identificateur de processus, tu peux retrouver le numéro de session par ProcessIdToSessionId. Il te suffit ensuite de le comparer à la session de ton application (même fonction en lui passant GetCurrentProcessId)

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 42
    Points : 25
    Points
    25
    Par défaut
    Bonjour,

    Merci de votre réponse rapide. Mais d'où sortez vous cette fonction "ProcessIdToSessionId".

    Dois-je l'implémenter de moi-même ou est-ce une fonction disponible sur un de mes composants ?

    En cherchant des bouts de code sur le net, voici comme j'ai modifié mon code en conséquences de votre remarque. Merci de me dire si je suis dans la bonne voie.

    J'ai rajouté les trois fonction suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function ProcessIdToSessionId(dwProcessId: DWORD; pSessionId: DWORD): BOOL; stdcall;
    Begin
    {}
    End;
     
    function GetSessionIdfromProccessId(const processId: DWORD; var sessionId: DWORD): boolean;
    begin
        result:=ProcessIdToSessionId(processId, DWORD(@sessionId));
    end;
     
    function GetCurrentSessionId(ProcessTemp : DWORD): DWORD;
    begin
        if not GetSessionIdfromProccessId(ProcessTemp,result) then
            result:=0;
    end;
    Puis rajouté une clause dans ma boucle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     if (Uppercase(ExtractFileName(ProcListExec.szExeFile)) = Uppercase(ExtractFileName (NomApplication))) then
                      begin
                           If GetCurrentSessionId(ProcListExec.th32ProcessID) = GetCurrentSessionId(GetCurrentProcessId) Then
                           Begin
                                Result:=ProcListExec.th32ProcessID;
                                Flag:=False;
                           End;
                      end

  4. #4
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 852
    Points : 11 285
    Points
    11 285
    Billets dans le blog
    6
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function ProcessIdToSessionId(dwProcessId: DWORD; var pSessionId: DWORD): boolean; stdcall; external Kernel32.dll;
    function GetCurrentProcessId: DWORD; stdcall; external Kernel32.dll;
     
    function SameSessionProcess(processId: DWORD): Boolean;
    var
      MySession, HisSession: DWORD;
    begin
      MySession := GetCurrentProcessId;
      Result := False;
      if ProcessIdToSessionId(processId; HisSession) 
      then Result := ( HisSession = MySession ) ;
    end;
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 679
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 679
    Points : 13 083
    Points
    13 083
    Par défaut
    C'est une API qui existe depuis longtemps et incluse dans l'unité Windows.

    ps: ta fonction GetSessionIdfromProccessId fait exactement la même chose que l'originale ProcessIdToSessionId, inutile

  6. #6
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 852
    Points : 11 285
    Points
    11 285
    Billets dans le blog
    6
    Par défaut
    ProcessIdToSessionId semble apparue depuis Vista seulement alors que les autres fonctions existent depuis XP... Sous quel environnement se fait le développement ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 679
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 679
    Points : 13 083
    Points
    13 083
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    ProcessIdToSessionId semble apparue depuis Vista seulement alors que les autres fonctions existent depuis XP... Sous quel environnement se fait le développement ?
    Non, non. Elle existe depuis Win 2000 et l'apparition du TSE.

    Sinon, la fonction complète ressemblera à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    function FindProcessIdInCurrentSession(aAppName :string) :cardinal;
    var
      CurSession :dword;
      Session    :dword;
      Handle     :THandle;
      Process    :TProcessEntry32;
     
    begin
      aAppName := ExtractFileName(aAppName);
      ProcessIdToSessionId(GetCurrentProcessId, CurSession);
     
      Process.dwSize := SizeOf(Process);
      Handle         := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     
      try
        if Process32First(Handle, Process) then
        repeat
          ProcessIdToSessionId(Process.th32ProcessID, Session);
     
          if (Session = CurSession) and SameText(aAppName, Process.szExeFile) then
            Exit(Process.th32ProcessID);
     
        until not Process32Next(Handle, Process);
     
        Result := 0;
     
      finally
        CloseHandle(Handle);
      end;
    end;
    Exit supporte depuis quelques temps un paramètre correspondant au type de résultat de la fonction. Sinon c'est bien sûr :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    begin
      Result := Process.th32ProcessID;
      Exit;
    end;

  8. #8
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 852
    Points : 11 285
    Points
    11 285
    Billets dans le blog
    6
    Par défaut
    Je me suis fié à ProcessIdToSessionId sur msdn pour formuler mon hypothèse : tant mieux si ça existait avant !
    Citation Envoyé par msdn
    Requirements

    Minimum supported client Windows Vista

    Minimum supported server Windows Server 2003
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 42
    Points : 25
    Points
    25
    Par défaut
    Bonjour,

    Merci pour ce bout de code bien plus propre qui marche exactement comme mon ancien code... malheureusement ces histoire de session de marche pas encore.

    En effet même en local, sur un seul ordinateur et un seul compte mes variables Session et CurSession ne sont pas les mêmes, et du coup ne rentre jamais dans la clause. En enlevant la première clause de mon If, je retrouve le même comportement "juste" de mon programme. (Exemple : dans le cas actuel : Session = 33051388 et CurSession = 5026080 )

    Merci de m'éclairer encore sur ce point.

    Edit : on est d'accord que la fonction "ProcessIdToSessionId" je suis quand même obligé de l'implémenter avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function ProcessIdToSessionId(dwProcessId: DWORD; var pSessionId: DWORD): boolean; stdcall; external Kernel32.dll
    Ou alors justement elle est censé etre dans le uses "Windows" ?

  10. #10
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 679
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 679
    Points : 13 083
    Points
    13 083
    Par défaut
    Ton code est faux

    La numérotation des sessions utilisateurs devrait commencer à 0 en XP et 1 depuis Vista. Pour info, tu peux afficher la colonne "ID de session" dans le gestionnaire de tâches.
    Ici, tes variables ne semblent pas être initialisées, comme si ProcessIdToSessionId n'était pas appelé.

    Citation Envoyé par briaume Voir le message
    on est d'accord que la fonction "ProcessIdToSessionId" je suis quand même obligé de l'implémenter avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function ProcessIdToSessionId(dwProcessId: DWORD; var pSessionId: DWORD): boolean; stdcall; external Kernel32.dll
    Tu ne devrais pas avoir à la redéfinir (sous D6 sans certitude). Remplace tout de même boolean par bool.

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2013
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 42
    Points : 25
    Points
    25
    Par défaut
    Bonjour,

    En effet, suite à la correction de mon code et la récupération des vrais numéros de session, cela marche parfaitement.

    Merci beaucoup !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2007] Access 2007 Runtime sur Terminal Server
    Par billybob2 dans le forum Projets ADP
    Réponses: 1
    Dernier message: 28/11/2014, 07h56
  2. [WS 2003] question sur Terminal Server
    Par Lenif dans le forum Windows Serveur
    Réponses: 2
    Dernier message: 15/01/2013, 12h05
  3. [WS 2003] tuto sur terminal server pour débutant
    Par alassanediakite dans le forum Windows Serveur
    Réponses: 0
    Dernier message: 15/04/2011, 22h48
  4. [WS 2008] Terminal Server sur SBS 2008
    Par keks06 dans le forum Windows Serveur
    Réponses: 2
    Dernier message: 13/09/2009, 16h27
  5. Réponses: 3
    Dernier message: 20/10/2008, 19h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo