vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
vb@rchiv Offline-Reader - exklusiv auf der vb@rchiv CD Vol.4  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik: System/Windows · Prozesse/Tasks   |   VB-Versionen: VB4, VB5, VB614.11.02
Handle einer gestarteten EXE-Datei ermitteln II

Ist eine EXE-Datei gestartet? Und wenn ja, wie bekomme ich das Fensterhandle der Anwendung? Wir zeigen Ihnen eine Lösung.

Autor:   Dieter OtterBewertung:     [ Jetzt bewerten ]Views:  30.013 
www.tools4vb.deSystem:  Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt auf CD 

Vor einigen Wochen haben wir einen Code veröffentlicht, mit dem es möglich war zu prüfen, ob eine bestimmte EXE-Datei aktuell ausgeführt wird und wenn ja, wie man entweder die ProzessID oder das Fensterhandle ermitteln konnte. Leider funktioniert der Code jedoch nicht auf WinNT4 Systemen.

Doch damit ist jetzt Schluß Ab sofort lässt sich auch unter WinNT prüfen, ob eine bestimmte EXE-Datei ausgeführt wird.

Wir erweitern den bisherigen Code, indem wir zunächst das Betriebssystem abfragen. Wurde als System WinNT4 ermittelt, wenden wir ein klein wenig anderes Verfahren an.

Hier der vollständige Code, den Sie am besten in ein Modul packen.

Option Explicit
 
' zunächst die benötigten API-Deklarationen
Private Declare Function CreateToolhelpSnapshot Lib "kernel32" _
  Alias "CreateToolhelp32Snapshot" ( _
  ByVal lFlgas As Long, _
  ByVal lProcessID As Long) As Long
 
Private Declare Function ProcessFirst Lib "kernel32" _
  Alias "Process32First" ( _
  ByVal hSnapshot As Long, _
  uProcess As PROCESSENTRY32) As Long
 
Private Declare Function ProcessNext Lib "kernel32" _
  Alias "Process32Next" ( _
  ByVal hSnapshot As Long, _
  uProcess As PROCESSENTRY32) As Long
 
Private Declare Sub CloseHandle Lib "kernel32" ( _
  ByVal hPass As Long)
 
Private Const TH32CS_SNAPPROCESS As Long = 2&
Private Const MAX_PATH As Long = 260
 
Private Type PROCESSENTRY32
  dwSize As Long
  cntUsage As Long
  th32ProcessID As Long
  th32DefaultHeapID As Long
  th32ModuleID As Long
  cntThreads As Long
  th32ParentProcessID As Long
  pcPriClassBase As Long
  dwflags As Long
  szexeFile As String * MAX_PATH
End Type
 
Public Enum procReturnValue
  Handle = 0
  ProcessID = 1
End Enum
 
' Für WinNT4
Private Declare Function EnumProcesses Lib "psapi.dll" ( _
  ByRef lpidProcess As Long, _
  ByVal cb As Long, _
  ByRef cbNeeded As Long) As Long
 
Private Declare Function OpenProcess Lib "kernel32" ( _
  ByVal dwDesiredAccess As Long, _
  ByVal bInheritHandle As Long, _
  ByVal dwProcessId As Long) As Long
 
Private Declare Function EnumProcessModules Lib "psapi.dll" ( _
  ByVal hProcess As Long, _
  ByRef lphModule As Long, _
  ByVal cb As Long, _
  ByRef lpcbNeeded As Long) As Long
 
Private Declare Function GetModuleFileNameEx Lib "psapi.dll" _
  Alias "GetModuleFileNameExA" ( _
  ByVal hProcess As Long, _
  ByVal hModule As Long, _
  ByVal lpFilename As String, _
  ByVal nSize As Long) As Long
 
Private Const PROCESS_QUERY_INFORMATION = 1024
Private Const PROCESS_VM_READ = 16
 
' APIs, um die Windows-Version abzufragen
Private Type OSVERSIONINFO
  dwOSVersionInfoSize As Long
  dwMajorVersion As Long
  dwMinorVersion As Long
  dwBuildNumber As Long
  dwPlatformID As Long
  szCSDVersion As String * 128
End Type
 
Private Declare Function GetVersionEx Lib "kernel32" _
  Alias "GetVersionExA" ( _
  ByRef lpVersionInformation As OSVERSIONINFO) As Long
 
Private Const VER_PLATFORM_WIN32_NT = 2
Private Const VER_PLATFORM_WIN32_WINDOWS = 1
 
 
' weitere API-Deklarationen
Private Declare Function GetWindowThreadProcessId Lib "user32" ( _
  ByVal hwnd As Long, _
  lpdwProcessId As Long) As Long
 
Private Declare Function FindWindow Lib "user32" _
  Alias "FindWindowA" ( _
  ByVal lpClassName As String, _
  ByVal lpWindowName As String) As Long
 
Private Declare Function GetWindow Lib "user32" ( _
  ByVal hwnd As Long, _
  ByVal wCmd As Long) As Long
 
Private Declare Function GetParent Lib "user32" ( _
  ByVal hwnd As Long) As Long
 
Private Const GW_HWNDNEXT = 2

Die Funktion IsEXERunning gibt entweder das Handle oder die ProzessID zurück - oder 0, falls die EXE-Datei nicht gestartet ist.

' Prüft, ob eine EXE-Datei bereits ausgeführt wird
' und gibt im Erfolgsfall entweder das Fensterhandle
' oder die Process-ID zurück
Public Function IsEXERunning(ByVal sFilename As String, _
  Optional ByVal iReturn As procReturnValue = ProcessID) As Long
 
  Dim nResult As Long
 
  ' Je nach System...
  If IsWinNT() Then
    ' NT4 - Sonderbehandlung :-)
 
    Dim lCb As Long
    Dim lCbNeeded As Long
    Dim lCbNeeded2 As Long
    Dim lProcID() As Long
    Dim lModules(1 To 200) As Long
    Dim hProcess As Long
    Dim sModuleName As String
    Dim n As Long
 
    ' alle laufenden Prozesse ermitteln
    lCb = 8: lCbNeeded = 96
    Do While lCb <= lCbNeeded
       lCb = lCb * 2
       ReDim lProcID(lCb / 4) As Long
       EnumProcesses lProcID(1), lCb, lCbNeeded
    Loop
 
    For n = 1 To lCbNeeded / 4
       ' Prozess-Handle ermitteln
       hProcess = OpenProcess(PROCESS_QUERY_INFORMATION _
          Or PROCESS_VM_READ, 0, lProcID(n))
       If hProcess <> 0 Then
         nResult = EnumProcessModules(hProcess, _
           lModules(1), 200, lCbNeeded2)
           If nResult <> 0 Then
             sModuleName = Space(MAX_PATH)
             nResult = GetModuleFileNameEx(hProcess, _
               lModules(1), sModuleName, Len(sModuleName))
             sModuleName = LCase$(Left$(sModuleName, nResult))
 
             ' sModuleName beinhaltet den kompletten Pfad!
             If Right$(sModuleName, Len(sFilename) + 1) = _
               "\" + LCase$(sFilename) Then
               ' Jepp - EXE gefunden!
               If iReturn = Handle Then
                 IsEXERunning = ProcID2hWnd(lProcID(n))
               Else
                 IsEXERunning = lProcID(n)
               End If
               Exit For
             End If
           End If
       End If
       CloseHandle hProcess
    Next n
 
  Else
    ' bei allen anderen Systemen...
    Dim lSnapshot As Long
    Dim uProcess As PROCESSENTRY32
 
    ' "Snapshot" des aktuellen Prozess ermitteln
    lSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
    If lSnapshot <> 0 Then
      uProcess.dwSize = Len(uProcess)
 
      ' Ersten Prozess ermitteln
      nResult = ProcessFirst(lSnapshot, uProcess)
 
      Do Until nResult = 0
        ' Prozessliste durchlaufen
        If InStr(LCase$(uProcess.szexeFile), LCase$(sFilename)) > 0 Then
           Jepp - EXE gefunden
          If iReturn = Handle Then
            IsEXERunning = ProcID2hWnd(uProcess.th32ProcessID)
          Else
            IsEXERunning = uProcess.th32ProcessID
          End If
          Exit Do
        End If
 
        ' nächster Prozess
        nResult = ProcessNext(lSnapshot, uProcess)
      Loop
 
      ' Handle schliessen
      CloseHandle lSnapshot
    End If
  End If
End Function

Benötigte Hilfsfunktionen

' Windows NT?
Public Function IsWinNT() As Boolean
  Dim OSVersion As OSVERSIONINFO
 
  With OSVersion
    .dwOSVersionInfoSize = Len(OSVersion)
    GetVersionEx OSVersion
 
    IsWinNT = (.dwPlatformID = VER_PLATFORM_WIN32_NT) And _
      (.dwMajorVersion <= 4)
  End With
End Function
' Ermittelt das Fensterhandle anhand einer Prozess-ID
Private Function ProcID2hWnd(ByVal ProcID As Long) As Long
  ' alle Fenster durchlaufen und nach Process-ID suchen
  Dim lngHWnd As Long
  Dim lngProcTaskID As Long
 
  lngHWnd = FindWindow(vbNullString, vbNullString)
  Do While lngHWnd <> 0
 
    ' Existiert kein Eltern-Fenster, dann ProcssID
    ' ermitteln und mit TaskID vergleichen
    If GetParent(lngHWnd) = 0 Then
      GetWindowThreadProcessId lngHWnd, lngProcTaskID
 
      ' Handelt es sich um die gesuchte TaskID?
      If lngProcTaskID = ProcID Then
        ' Fenster-Handle zurückgeben und Schleife
        ' verlassen!
        ProcID2hWnd = lngHWnd
        Exit Do
      End If
 
    End If
 
    ' Nächstes Fenster
    lngHWnd = GetWindow(lngHWnd, GW_HWNDNEXT)
  Loop
End Function

Dieser Tipp wurde bereits 30.013 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Aktuelle Diskussion anzeigen (3 Beiträge)

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(einschl. Beispielprojekt!)

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel