vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Erstellen von dynamischen Kontextmen?s - wann immer Sie sie brauchen!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2015
 
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:  24.649 
www.tools4vb.deSystem:  Win9x, WinNT, Win2k, WinXP, Vista, Win7, Win8 Beispielprojekt auf CD 

Summer-Special bei Tools & Components!
Gute Laune Sommer bei Tools & Components
Top Summer-Special - Sparen Sie teilweise über 100,- EUR
Alle sev-Entwicklerkomponenten und Komplettpakete jetzt bis zu 25% reduziert!
zum Beispiel:
  • Developer CD nur 455,- EUR statt 569,- EUR
  • sevDTA 2.0 nur 224,30 EUR statt 299,- EUR
  •  
  • vb@rchiv   Vol.6 nur 18,70 EUR statt 24,95 EUR
  • sevCoolbar 3.0 nur 58,70 EUR statt 69,- EUR
  • - Werbung -Und viele weitere Angebote           Aktionspreise nur für kurze Zeit gültig

    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 24.649 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-2015 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