-
January 3rd, 2006, 05:50 PM
#1
Find full path to EXE file from process information
I am using the following code to find the EXE of all the running processes. (This code is very stripped down to show only the essentials.) It works great on Windows 98. That is, it returns the full path of the program (e.g., "C:\Windows\Program.exe"). However, in XP this same code returns only the EXE file, without the path (e.g., "Program.exe"). For some aspects of my program, I need the full path. Specifically, the program is an anti-Trojan program designed to shut down any Trojan programs and optionally delete the file. In both 98 and XP this code allows me to shut down the program (using KillProcess(uProcess.th32ProcessID, 0)), but I need the full path to do a Kill afterward if the user elects to destroy the Trojan file. Someone please tell me how to get the full path under XP using the following code, or something very close to it using Visual Basic.
Here is my existing code, stripped to the essentials:
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
Declare Function ProcessFirst _
Lib "kernel32" Alias "Process32First" _
(ByVal hSnapshot As Long, _
uProcess As PROCESSENTRY32) As Long
Declare Function ProcessNext _
Lib "kernel32" Alias "Process32Next" _
(ByVal hSnapshot As Long, _
uProcess As PROCESSENTRY32) As Long
Declare Function CreateToolhelpSnapshot _
Lib "kernel32" Alias "CreateToolhelp32Snapshot" _
(ByVal lFlags As Long, _
lProcessID As Long) As Long
Declare Function CloseHandle _
Lib "kernel32" (ByVal hObject As Long) As Long
Sub ListPrograms()
uProcess.dwSize = Len(uProcess)
hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
rProcessFound = ProcessFirst(hSnapshot, uProcess)
Do While rProcessFound
NumProcesses = NumProcesses + 1
i = InStr(1, uProcess.szexeFile, Chr(0))
szExename = LCase$(Left$(uProcess.szexeFile, i - 1))
MainForm.List1.AddItem szExename
rProcessFound = ProcessNext(hSnapshot, uProcess)
Loop
Call CloseHandle(hSnapshot)
End Sub
-
February 3rd, 2006, 01:33 AM
#2
Re: Find full path to EXE file from process information
Hope this is still applicable, I just started going through the forum yesterday. Anyway, I'm posting it, because I remember needing this information before I figured it out (not that I didn't find sample code) so hopefully this'll save someone some research time and add more coding time.
Under XP, 2000, and presumably 2003 Server, you're probably going to need to changeyour code a bit to include calls to OpenProcess(), EnumProcessModules() and GetModuleFileNameEx() (or GetModuleInfo() for more information).
It's late, and I don't have sample code here, but those are standard API calls (API Text Viewer should have the declarations, if not, MSDN does). The flow is going to be something like this (taking care to note that I'm just sort of winging it off the top of my head - save before running, and be prepared to spend a few minutes at MSDN):
' New API Declarations: Joe-added code 020206
Public Declare Function EnumProcessModules Lib "psapi.dll" _
(ByVal hProcess As Long, pModuleList As Any, _
ByVal lArraySize As Long, lSizeNeeded As Long) As Boolean
Public Declare Function GetModuleFilenameEx Lib "psapi.dll" _
(ByVal hProcess As Long, ByVal hModule As Long, _
ByVal strFilename As String, lSize As Long) As Long
' End Joe-added code 020206
Sub ListPrograms()
uProcess.dwSize = Len(uProcess)
hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
rProcessFound = ProcessFirst(hSnapshot, uProcess)
Do While rProcessFound
NumProcesses = NumProcesses + 1
' Commented this way of doing it... JJP 020206
' i = InStr(1, uProcess.szexeFile, Chr(0))
' szExename = LCase$(Left$(uProcess.szexeFile, i - 1))
' Joe-added code 020206
' XP/2000 way of doing it
Dim hProcess As Long
hProcess = OpenProcess(uProcess.th32ProcessID)
If (0 <> hProcess) Then
Dim hModules(999) As Long ' Make it bigger than reasonably needed
Dim lModuleCount As Long
' (1000 * 4) is because size is in bytes, even though a single element is
' 4 bytes...
EnumProcessModules hProcess, hModules(0)), (1000 * 4), lModuleCount
' You could get creative here, and check the return from
' EnumProcessModules to make sure your array was big enough, and all
' but this is demo code, right?
' The only one we care about is the base module, which is the exe
' and happens to always be element 0 in the module list
Dim lExeSize As Long
lExeSize = 256
szExename = String$(lExeSize, Chr$(0))
lExeSize = GetModuleFilenameEx(hProcess, hModules(0), _
strFilename, lExeSize)
szExeName = LCase$(Left$(InStr(1, szExename, Chr(0))-1))
CloseHandle hProcess
End If
' End Joe-added code, 020206
MainForm.List1.AddItem szExename
rProcessFound = ProcessNext(hSnapshot, uProcess)
Loop
Call CloseHandle(hSnapshot)
End Sub
Anyway, if that's not particularly clear (really long day, coding in a browser window makes it worse), feel free to contact me, and I'll send you code I have elsewhere that I've tweaked to work, though it uses EnumProcesses instead of CreateSnapshot. Also, I think psapi may not be available on 9x machines, and if so, you may need to do some OS version checking, and do it your existing way for 9x, and a derivative of my way for XP, 2000, et al.
Hope that helps.
Joe
-
March 2nd, 2006, 01:51 AM
#3
Re: Find full path to EXE file from process information
solution is already kept in following link of this forum
http://www.codeguru.com/forum/showth...t=process+list
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|