Gibt's eigentlich auch eine neuere Version der WIN32.hlp? Und was ist dieses SDK, von dem Fluid Byte sprach?
Von PID oder hWnd auf den EXE-Namen schließen
Tatsache...
Gibt's eigentlich auch eine neuere Version der WIN32.hlp? Und was ist dieses SDK, von dem Fluid Byte sprach?
Gibt's eigentlich auch eine neuere Version der WIN32.hlp? Und was ist dieses SDK, von dem Fluid Byte sprach?
PB 4.30
Code: Alles auswählen
Macro Happy
;-)
EndMacro
Happy EndSchon etwas älter, ich hole das aber mal wieder hoch, da ich auf http://www.vbarchiv.net/archiv/tipp_det ... p?pid=1018 eine Möglichkeit gefunden habe, Den Filenamen, der zu einen Fenster gehört zuverlässiger zu ermitteln als dies mit GetWindowModuleFilename geschieht, wo öfter kein Filename zurückgeliefert wird.
Ich habe das mal nach Purebasic umgesetzt:
Ich habe das mal nach Purebasic umgesetzt:
Code: Alles auswählen
Prototype.l GetModuleFileNameEx(hProcess.l, hModule.l, *lpFilename, nSize)
Prototype.l EnumProcessModules(hProcess, *lphModule, cb, lpchNeeded)
Global GetModuleFileNameEx.GetModuleFileNameEx
Global EnumProcessModules.EnumProcessModules
Procedure.s GetEXEFromHandle(nHWnd.l = 0)
Protected nProcID, nResult, nTemp, hProcess
Protected sFile.s
Dim lModules.l(200)
; ProcessID ermitteln
If GetWindowThreadProcessId_(nHWnd, @nProcID) <> 0
; Prozess-Handle ermitteln
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, nProcID)
If hProcess <> 0
; Module des Prozess enumerieren
nResult = EnumProcessModules(hProcess, @lModules(0), 200, @nTemp)
If nResult <> 0
; Dateiname ermitteln
sFile = Space(260)
nResult = GetModuleFileNameEx(hProcess, 0, @sFile, Len(sFile))
sFile = LCase(Left(sFile, nResult))
EndIf
; Handle schließen
CloseHandle_(hProcess)
EndIf
EndIf
ProcedureReturn sFile
EndProcedure
If OpenLibrary(0, "psapi.dll")
;Process Status Helper API einbinden
GetModuleFileNameEx = GetFunction(0, "GetModuleFileNameExA")
EnumProcessModules = GetFunction(0, "EnumProcessModules")
EndIf
;Hier Code einfügen
CloseLibrary(0)
Zuletzt geändert von Ligatur am 24.04.2007 15:46, insgesamt 1-mal geändert.
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Etwas einfacher, sollte dasselbe bewirken
Code: Alles auswählen
Procedure.s GetEXEFromHandle(hWnd.l = 0)
Protected Result.s, PID.l, handle.l, err.l
Protected Entry.MODULEENTRY32
If hWnd = 0 : hWnd = GetForegroundWindow_() : EndIf
Entry\dwSize = SizeOf(MODULEENTRY32)
GetWindowThreadProcessId_(hWnd, @PID)
handle = CreateToolhelp32Snapshot_(#TH32CS_SNAPMODULE, PID)
If handle
err = Module32First_(handle, Entry)
If err
Result = PeekS(@Entry\szExePath)
EndIf
CloseHandle_(handle)
EndIf
ProcedureReturn Result
EndProcedure
Debug GetEXEFromHandle()PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

@ts-soft:
Stimmt, deine Methode ist einfacher und bewirkt das selbe, ist aber wesentlich langsamr.
Bei mir braucht deine Methode bei 1000 Durchläufen 560 ms, die von mir gepostete nur 80 ms (ohne Debugger).
Stimmt, deine Methode ist einfacher und bewirkt das selbe, ist aber wesentlich langsamr.
Code: Alles auswählen
Prototype.l GetModuleFileNameEx(hProcess.l, hModule.l, *lpFilename, nSize)
Prototype.l EnumProcessModules(hProcess, *lphModule, cb, lpchNeeded)
Global GetModuleFileNameEx.GetModuleFileNameEx
Global EnumProcessModules.EnumProcessModules
Procedure.s GetEXEFromHandle(nHWnd.l = 0)
Protected nProcID, nResult, nTemp, hProcess
Protected sFile.s
Dim lModules.l(200)
If nHwnd = 0
nHWnd = GetForegroundWindow_()
EndIf
; ProcessID ermitteln
If GetWindowThreadProcessId_(nHWnd, @nProcID) <> 0
; Prozess-Handle ermitteln
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, nProcID)
If hProcess <> 0
; Module des Prozess enumerieren
nResult = EnumProcessModules(hProcess, @lModules(0), 200, @nTemp)
If nResult <> 0
; Dateiname ermitteln
sFile = Space(260)
nResult = GetModuleFileNameEx(hProcess, 0, @sFile, Len(sFile))
sFile = LCase(Left(sFile, nResult))
EndIf
; Handle schließen
CloseHandle_(hProcess)
EndIf
EndIf
ProcedureReturn sFile
EndProcedure
If OpenLibrary(0, "psapi.dll")
;Process Status Helper API einbinden
GetModuleFileNameEx = GetFunction(0, "GetModuleFileNameExA")
EnumProcessModules = GetFunction(0, "EnumProcessModules")
EndIf
st = ElapsedMilliseconds()
For i = 1 To 1000
path.s = GetEXEFromHandle()
Next
sp = ElapsedMilliseconds() - st
MessageRequester(path, Str(sp))
CloseLibrary(0)
Code: Alles auswählen
Procedure.s GetEXEFromHandle(hWnd.l = 0)
Protected Result.s, PID.l, handle.l, err.l
Protected Entry.MODULEENTRY32
If hWnd = 0 : hWnd = GetForegroundWindow_() : EndIf
Entry\dwSize = SizeOf(MODULEENTRY32)
GetWindowThreadProcessId_(hWnd, @PID)
handle = CreateToolhelp32Snapshot_(#TH32CS_SNAPMODULE, PID)
If handle
err = Module32First_(handle, Entry)
If err
Result = PeekS(@Entry\szExePath)
EndIf
CloseHandle_(handle)
EndIf
ProcedureReturn Result
EndProcedure
st = ElapsedMilliseconds()
For i = 1 To 1000
path.s = GetEXEFromHandle()
Next
sp = ElapsedMilliseconds() - st
MessageRequester(path, Str(sp))
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Dann Deins noch schneller, schöner und mit Unicode-Support
Code: Alles auswählen
Import "psapi.lib"
EnumProcessModules(a.l,b.l,c.l,d.l) As "_EnumProcessModules@16"
CompilerIf #PB_Compiler_Unicode
GetModuleFileNameEx(a.l,b.l,c.l,d.l) As "_GetModuleFileNameExW@16"
CompilerElse
GetModuleFileNameEx(a.l,b.l,c.l,d.l) As "_GetModuleFileNameExA@16"
CompilerEndIf
EndImport
Procedure.s GetEXEFromHandle(nHWnd.l = 0)
Protected nProcID, nResult, nTemp, hProcess
Protected sFile.s
Dim lModules.l(200)
If nHwnd = 0
nHWnd = GetForegroundWindow_()
EndIf
; ProcessID ermitteln
If GetWindowThreadProcessId_(nHWnd, @nProcID) <> 0
; Prozess-Handle ermitteln
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, nProcID)
If hProcess <> 0
; Module des Prozess enumerieren
nResult = EnumProcessModules(hProcess, @lModules(0), 200, @nTemp)
If nResult <> 0
; Dateiname ermitteln
sFile = Space(260)
nResult = GetModuleFileNameEx(hProcess, 0, @sFile, Len(sFile))
sFile = LCase(Left(sFile, nResult))
EndIf
; Handle schließen
CloseHandle_(hProcess)
EndIf
EndIf
ProcedureReturn sFile
EndProcedurePureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

- Fluid Byte
- Beiträge: 3110
- Registriert: 27.09.2006 22:06
- Wohnort: Berlin, Mitte
Zuverlässiger?Ich hole das aber mal wieder hoch, da ich auf http://www.vbarchiv.net/archiv/tipp_det ... p?pid=1018 eine Möglichkeit gefunden habe, Den Filenamen, der zu einen Fenster gehört zuverlässiger zu ermitteln
Windows 10 Pro, 64-Bit / Outtakes | Derek
@ts - soft,
Nagut, ich gebs zu, das ist jetzt schöner, schneller und mit Unicode - Unterstützung, dem habe ich nichts mehr entgegenzusetzen.
@Fluid Byte,
Ja, zuverlässiger, probiere das mal bei mehreren Fenstern.
1. Mit GetWindowModuleFilename:
Und Mit Openprocess ...
Wie du sehen wirst wird bei 1. Methode Fehlgeschlagen angezeigt wo die 2. Methode funktioniert.
Nagut, ich gebs zu, das ist jetzt schöner, schneller und mit Unicode - Unterstützung, dem habe ich nichts mehr entgegenzusetzen.
@Fluid Byte,
Ja, zuverlässiger, probiere das mal bei mehreren Fenstern.
1. Mit GetWindowModuleFilename:
Code: Alles auswählen
Procedure tp(hwnd, message, id, time)
Protected fn.s{260}
fhwnd = GetForegroundWindow_()
SendMessage_(fhwnd, #WM_GETTEXT, 260, @wt.s)
If GetWindowModuleFileName_(fhwnd, @fn, 260)
SetGadgetText(0, wt + " - " +fn)
Else
SetGadgetText(0, wt + " - " + "Fehlgeschlagen")
EndIf
EndProcedure
hwnd = OpenWindow(0, 0, 0, 600, 100, "WindowModuleFilename")
CreateGadgetList(hwnd)
StringGadget(0, 10, 40, 580, 20, "", #PB_String_ReadOnly)
StickyWindow(0, #True)
SetTimer_(hwnd, 0, 100, @tp())
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Code: Alles auswählen
Import "psapi.lib"
EnumProcessModules(a.l,b.l,c.l,d.l) As "_EnumProcessModules@16"
CompilerIf #PB_Compiler_Unicode
GetModuleFileNameEx(hProcess.l, hModule.l, *lpFilename, nSize) As "_GetModuleFileNameExW@16"
CompilerElse
GetModuleFileNameEx(hProcess.l, hModule.l, *lpFilename, nSize) As "_GetModuleFileNameExA@16"
CompilerEndIf
EndImport
Procedure.s GetEXEFromHandle(nHWnd.l = 0)
Protected nProcID, nResult, nTemp, hProcess
Protected sFile.s
Dim lModules.l(200)
If nHwnd = 0
nHWnd = GetForegroundWindow_()
EndIf
; ProcessID ermitteln
If GetWindowThreadProcessId_(nHWnd, @nProcID) <> 0
; Prozess-Handle ermitteln
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, nProcID)
If hProcess <> 0
; Module des Prozess enumerieren
nResult = EnumProcessModules(hProcess, @lModules(0), 200, @nTemp)
If nResult <> 0
; Dateiname ermitteln
sFile = Space(260)
nResult = GetModuleFileNameEx(hProcess, 0, @sFile, Len(sFile))
sFile = LCase(Left(sFile, nResult))
EndIf
; Handle schließen
CloseHandle_(hProcess)
EndIf
EndIf
ProcedureReturn sFile
EndProcedure
Procedure tp(hwnd, message, id, time)
Protected fn.s{260}
fhwnd = GetForegroundWindow_()
SendMessage_(fhwnd, #WM_GETTEXT, 260, @wt.s)
fn = GetEXEFromHandle(fhwnd)
If fn <> ""
SetGadgetText(0, wt + " - " +fn)
Else
SetGadgetText(0, wt + " - " + "Fehlgeschlagen")
EndIf
EndProcedure
hwnd = OpenWindow(0, 0, 0, 600, 100, "OpenProcess")
CreateGadgetList(hwnd)
StringGadget(0, 10, 40, 580, 20, "", #PB_String_ReadOnly)
StickyWindow(0, #True)
SetTimer_(hwnd, 0, 100, @tp())
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Wie du sehen wirst wird bei 1. Methode Fehlgeschlagen angezeigt wo die 2. Methode funktioniert.