Hi!
I have the processID and the window handler. I need the .exe of the application. can you help me?
Thank you Wuerfel
Printable View
Hi!
I have the processID and the window handler. I need the .exe of the application. can you help me?
Thank you Wuerfel
VB Code:
Public Const TH32CS_SNAPPROCESS As Long = 2& Public Const MAX_PATH As Long = 260 Public 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 Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long Public Declare Function CreateToolhelpSnapshot Lib "Kernel32" Alias "CreateToolhelp32Snapshot" (ByVal lFlgas As Long, ByVal lProcessID As Long) As Long Public Declare Function ProcessFirst Lib "Kernel32" Alias "Process32First" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long Public Declare Function ProcessNext Lib "Kernel32" Alias "Process32Next" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long Public Declare Sub CloseHandle Lib "Kernel32" (ByVal hPass As Long) Public Function GetExeFromHandle(hWnd As Long) As String Dim threadID As Long, processID As Long, hSnapshot As Long Dim uProcess As PROCESSENTRY32, rProcessFound As Long Dim i As Integer, szExename As String ' Get ID for window thread threadID = GetWindowThreadProcessId(hWnd, processID) ' Check if valid If threadID = 0 Or processID = 0 Then Exit Function ' Create snapshot of current processes hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&) ' Check if snapshot is valid If hSnapshot = -1 Then Exit Function 'Initialize uProcess with correct size uProcess.dwSize = Len(uProcess) 'Start looping through processes rProcessFound = ProcessFirst(hSnapshot, uProcess) Do While rProcessFound If uProcess.th32ProcessID = processID Then 'Found it, now get name of exefile i = InStr(1, uProcess.szexeFile, Chr(0)) If i > 0 Then szExename = Left$(uProcess.szexeFile, i - 1) Exit Do Else 'Wrong ID, so continue looping rProcessFound = ProcessNext(hSnapshot, uProcess) End If Loop Call CloseHandle(hSnapshot) GetExeFromHandle = szExename End Function Private Sub Command1_Click() MsgBox GetExeFromHandle(Me.hWnd) End Sub
*
i didn't know you could do that :eek:
It seemed a wonderful solution, but on my NT4 station 'CreateToolhelp32Snapshot' is not part of kernel32.
I've seen other VB apps do the same thing on NT4, so it should be possible another way. Can someone please help?
??? That doesn't make any sense. kernel32 is kernel 32 is kernal 32. How can one kernal32 support something and not another. Are you getting some kind of error message?
It does make sense -NT4 workstation is quite a limited version of Windows.
I already found a piece of code that runs under NT4:
Code:Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare Function GetModuleFileName Lib "kernel32" Alias "GetModuleFileNameA" (ByVal hModule As Long, ByVal lpFileName As String, ByVal nSize As Long) As Long
Public Const GWL_HINSTANCE = -6
Public Function getHwndExe(ByVal myHwnd As Long) As String
Dim str As String
Dim hInstance, i As Long
str = String$(254, " ") + Chr(0)
hInstance = GetWindowLong(myHwnd, GWL_HINSTANCE)
If GetModuleFileName(hInstance, str, 255) Then
i = InStr(1, str, Chr(0))
str = LCase$(Left$(str, i - 1))
getHwndExe = str
Exit Function
End If
getHwndExe = ""
End Function
I checked C:\WINNT\system32\kernel32.dll with Quickview. You can get a list of subroutines inside the dll. The subroutines above can't be found in this list.
When I check it at my colleagues desktop (Win 2000), he has lots more subroutines in kernel32.
I heared from a friend that NT is dead, as far as Microsoft is concerned.
Perhaps the term NT is dead, but NT itself is very much alive. Windows 2000 started out life as NT5, and continues to be the new version of NT, under a different name.Quote:
Originally posted by hgroot
I heared from a friend that NT is dead, as far as Microsoft is concerned.
Your findings are interesting. I will definately make a note of the routine that you posted.
You're right - what I meant was NT as in NT4 etc.
Windows 2000 combines the strength of both '95 and NT.
I had to port that piece of code from C++.
Though I now found out that it doesn't work as well with hWnd as with hDC. When I use hWnd I get c:\winnt\system32\msvbvm60.dll
This is also interesting - Does all compiled VB code run inside a VB Virtual Machine?
I can only get the real executable name when I call: getHwndExe(Me.hDC)
It still shouldn't be too hard though to rewrite it for hWnd.
Post it when you do.Quote:
Originally posted by hgroot
It still shouldn't be too hard though to rewrite it for hWnd.
.
It has been a while since I last posted on this thread (or posted at all ;))
The NT version of the code was more complicated than I thought. I modified some code I found at AllApi.net. Here it is:
Code:Public Function hWnd2EXE(hwnd As Long) As String
Const clMaxNumProcesses As Long = 5000
Const MAX_PATH = 260, PROCESS_QUERY_INFORMATION = 1024, PROCESS_VM_READ = 16
Dim sModuleName As String * MAX_PATH, sProcessNamePath As String, sProcessName As String
Dim alMatchingNames() As String
Dim alModules(1 To 400) As Long
Dim lBytesReturned As Long, lNumMatching As Long
Dim lNumProcesses As Long, lBytesNeeded As Long, alProcIDs() As Long
Dim lHwndProcess As Long, lThisProcess As Long, lRet As Long
Dim sImageName As String
Dim theHwnd As Long
On Error GoTo ErrFailed
'Size array To hold process IDs
ReDim alProcIDs(clMaxNumProcesses * 4) As Long
'Populate an array containing all process ID's
lRet = EnumProcesses(alProcIDs(1), clMaxNumProcesses * 4, lBytesReturned)
'Count number of processes returned
lNumProcesses = lBytesReturned / 4
'Resize the array containing all the processes
ReDim Preserve alProcIDs(lNumProcesses)
'Resize the array To contain all the matching processes
ReDim alMatchingNames(1 To lNumProcesses)
For lThisProcess = 1 To lNumProcesses
'Open the process
lHwndProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, alProcIDs(lThisProcess))
theHwnd = pid2hWnd(alProcIDs(lThisProcess))
If lHwndProcess <> 0 And theHwnd = hwnd Then
'Get an array of the module handles For the specified process
lRet = EnumProcessModules(lHwndProcess, alModules(1), 200&, lBytesNeeded)
If lRet <> 0 Then
'Get Process Path And Name
lRet = GetModuleFileName(lHwndProcess, alModules(1), sModuleName, MAX_PATH)
sProcessNamePath = Trim$(UCase$(Left$(sModuleName, lRet)))
'Get the Process Name
sProcessName = sProcessNamePath ' Mid$(sProcessNamePath, InStrRev(sProcessNamePath, "\") + 1)
'Get the Process Name
hWnd2EXE = Mid$(sProcessNamePath, InStrRev(sProcessNamePath, "\") + 1)
lRet = CloseHandle(lHwndProcess)
Exit Function
End If
End If
'Close the handle To this process
lRet = CloseHandle(lHwndProcess)
Next
'No matching processes found
hWnd2EXE = "unknown"
Exit Function
ErrFailed:
hWnd2EXE = "failed"
End Function
Oops, almost forgot some other required routines and declarations:
Well... It's a little hard to extract all the required declarations from my vb module, so you'd have to find them for yourself...Code:Public Function pid2hWnd(ByVal pid As Long) As Long
Dim hwCurr As Long
Dim ShellPid As Long
Dim GetPid As Long
Dim aHwnd As Long
aHwnd = getMyHwnd
hwCurr = GetWindow(aHwnd, GW_HWNDFIRST) ' Get first window
Do While hwCurr ' repeat For all windows
GetWindowThreadProcessId hwCurr, GetPid
If GetPid = pid And IsWindowVisible(hwCurr) Then
pid2hWnd = hwCurr
Exit Function
End If
hwCurr = GetWindow(hwCurr, GW_HWNDNEXT)
Loop
pid2hWnd = -1
End Function
i have some stuff that works on win2k and winnt dead system as well.
More over i have C++ and VB code for that in case anybody needs ...
don't kill ur thirst for knowledge ;)