I wanted to obtain a list of processes to search for the process id's of a specific running processes. So I used example 4 in the help of the Process command to obtain this. This all worked ok on XP, but somehow I was not able to retrieve the names of all processes with the DLLCall OpenProcess when I ran the script under Vista (and of course exactly the ones that I was looking for did not show up). I tried all kinds of access types and variations of the script mentioned in the forum, but none worked.
So I went looking for another way to obtain the process list and found the function CreateToolhelp32Snapshot. This works great to obtain a process list and is much simpler that the example in the help file.
Here is the code:
Code:
d = `n ; string separator
hProcessSnap := DllCall("CreateToolhelp32Snapshot", "UInt", 2, "Int", 0) ; Obtain list of processes
VarSetCapacity(pe32, 300, 0) ; reserve memory for struct
InsertInteger(296, pe32, 0, 4) ; put length of struct in first item
result := DllCall("Process32First", "UInt", hProcessSnap, "UInt", &pe32 ) ; Get first process
counter := 0
l := ""
if result then
Loop
{
counter := counter + 1
PID := ExtractInteger(pe32, 8, false, 4) ; Obtain process-id
str := GetStringFromStruct(pe32, 36) ; Obtain process name at position 36 in struct
l = %l%%PID%-%str%%d%
result := DllCall("Process32Next", "UInt", hProcessSnap, "UInt", &pe32 )
if !result
break
}
DllCall("CloseHandle", "UInt", hProcessSnap) ; close process handle to save memory
MsgBox, 0, %counter% Processes, %l%
GetStringFromStruct(ByRef pSource, pOffset = 0)
{
str := ""
kar := *(&pSource + pOffset)
Loop
{
if kar = 0
{
return str
}
else
{
str := str . chr(kar)
}
if a_index > 500
{
return "groter dan 500"
}
kar := *(&pSource + pOffset + a_index)
}
}
I dont know if there are easier ways to extract the process name from the struct than the way I did it with GetStringFromStruct, so if someone knows a better way, please let me know.
The script probably wont work on Vista 64, because I asume the struct size and the position of the process name will be different, but little experimenting will get you this. To obtain the struct size for example, do the following:
Code:
hProcessSnap := DllCall("CreateToolhelp32Snapshot", "UInt", 2, "Int", 0) ; Obtain list of processes
VarSetCapacity(pe32, 1000, 0) ; reserve memory for struct
Loop 500
{
InsertInteger(a_index, pe32, 0, 4) ; put length of struct in first item
result := DllCall("Process32First", "UInt", hProcessSnap, "UInt", &pe32 ) ; Get first process
if result
{
Msgbox, Length of struct is %a_index%
break
}
}
DllCall("CloseHandle", "UInt", hProcessSnap) ; close process handle to save memory