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
Anzeige
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. |
vb@rchiv CD Vol.6 Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! Online-Update-Funktion Entwickler-Vollversionen u.v.m. Tipp des Monats März 2024 Dieter Otter UTF-8 Konvertierung von Dateien und Strings VB6 selbst verfügt über keine Funktionen zur UTF-8 Konvertierung von Daten. Mit Hilfe des ADODB.Stream-Objekts lassen sich diese fehlenden Funktionen aber schnell nachrüsten. Neu! sevEingabe 3.0 Einfach stark! Ein einziges Eingabe-Control für alle benötigten Eingabetypen und -formate, inkl. Kalender-, Taschenrechner und Floskelfunktion, mehrspaltige ComboBox mit DB-Anbindung, ImageComboBox u.v.m. |
||||||||||||||||
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. |