How do I know who called/ran my application? I'm talking about a compiled ahk script.
Was it user ran it directly from a file manager? was it via cmd? Was it another app? etc...
Thanks
Who called my app?
Re: Who called my app?
Guest, see this. Basically the idea is to get the name of the parent process.
Re: Who called my app?
Thanks trismarck : )
But that function is ancient ad I'm getting Chinese text, its not UNICODE :/
It seems all I need is the parent process PID
Any idea?
But that function is ancient ad I'm getting Chinese text, its not UNICODE :/
It seems all I need is the parent process PID
Any idea?
- LinearSpoon
- Posts: 156
- Joined: 29 Sep 2013, 22:55
Re: Who called my app?
I had used this code in another script to return the name of the process listening over a certain port, but I guess it can be adapted to your purposes. Tested on ANSI, Unicode, 32 bit and 64 bit AHK.
Edit: I take back what I said about doing both the parent PID and name in the same loop. Improved speed somewhat anyway.
Edit: I take back what I said about doing both the parent PID and name in the same loop. Improved speed somewhat anyway.
Code: Select all
scriptPID := GetCurrentProcess()
scriptEXE := GetProcessName(scriptPID)
parentPID := GetParentProcess(scriptPID)
parentEXE := GetProcessName(parentPID)
Msgbox % "Script PID: " scriptPID "`nScript executable: " scriptEXE "`nParent PID: " parentPID "`nParent executable: " parentEXE
GetParentProcess(PID)
{
static function := DllCall("GetProcAddress", "ptr", DllCall("GetModuleHandle", "str", "kernel32.dll", "ptr"), "astr", "Process32Next" (A_IsUnicode ? "W" : ""), "ptr")
if !(h := DllCall("CreateToolhelp32Snapshot", "uint", 2, "uint", 0))
return
VarSetCapacity(pEntry, sz := (A_PtrSize = 8 ? 48 : 36)+(A_IsUnicode ? 520 : 260))
Numput(sz, pEntry, 0, "uint")
DllCall("Process32First" (A_IsUnicode ? "W" : ""), "ptr", h, "ptr", &pEntry)
loop
{
if (pid = NumGet(pEntry, 8, "uint") || !DllCall(function, "ptr", h, "ptr", &pEntry))
break
}
DllCall("CloseHandle", "ptr", h)
return Numget(pEntry, 16+2*A_PtrSize, "uint")
}
GetProcessName(PID)
{
static function := DllCall("GetProcAddress", "ptr", DllCall("GetModuleHandle", "str", "kernel32.dll", "ptr"), "astr", "Process32Next" (A_IsUnicode ? "W" : ""), "ptr")
if !(h := DllCall("CreateToolhelp32Snapshot", "uint", 2, "uint", 0))
return
VarSetCapacity(pEntry, sz := (A_PtrSize = 8 ? 48 : 36)+260*(A_IsUnicode ? 2 : 1))
Numput(sz, pEntry, 0, "uint")
DllCall("Process32First" (A_IsUnicode ? "W" : ""), "ptr", h, "ptr", &pEntry)
loop
{
if (pid = NumGet(pEntry, 8, "uint") || !DllCall(function, "ptr", h, "ptr", &pEntry))
break
}
DllCall("CloseHandle", "ptr", h)
return StrGet(&pEntry+28+2*A_PtrSize, A_IsUnicode ? "utf-16" : "utf-8")
}
GetCurrentProcess()
{
return DllCall("GetCurrentProcessId")
}
- LinearSpoon
- Posts: 156
- Joined: 29 Sep 2013, 22:55
Re: Who called my app?
Looks like you grabbed the old version before I made some edits... I didn't close the snapshot handle and I made some changes to improve the speed. *Shrugs*
Re: Who called my app?
Turned out it could be done without all those dllCalls, see my gist post above.LinearSpoon wrote:Looks like you grabbed the old version before I made some edits... I didn't close the snapshot handle and I made some changes to improve the speed. *Shrugs*
Re: Who called my app?
LinearSpoon, thanks for the code. I have a question:
Shouldn't there be 40 instead of 48? LONG seems to be 4 bytes on 64-bit Windows.
Code: Select all
VarSetCapacity(pEntry, sz := (A_PtrSize = 8 ? 48 : 36)+(A_IsUnicode ? 520 : 260))
Code: Select all
return Numget(pEntry, 16+2*A_PtrSize, "uint") ; 20+A_PtrSize
...
return StrGet(&pEntry+28+2*A_PtrSize, A_IsUnicode ? "utf-16" : "utf-8") ; 32+A_PtrSize
- LinearSpoon
- Posts: 156
- Joined: 29 Sep 2013, 22:55
Re: Who called my app?
@trismark: No. It's true LONG is int type (4 bytes) on 64 bit Windows. The issue is that th32DefaultHeapID is an "int64" type. This has several implications.
First, th32DefaultHeapID must sit on an address offset from the start of the struct that is a multiple of its size (8 bytes). The previous member th32ProcessID, occupies offset 8 to 12. The compiler inserts 4 "pad" bytes here so that th32DefaultHeapID can sit at offset 16.
Second, th32DefaultHeapID is itself 4 bytes larger on 64 bit compared to on 32 bit.
Third and last, the size of the entire structure must be a multiple of its largest member (Exercise: Why?). The structure as defined would be 564 bytes, which is 4 bytes short of being divisible by the size of th32DefaultHeapID. Again, 4 more "pad" bytes are inserted to make it work.
Together, these account for the 12 byte difference between 64 and 32 bit versions of the structure. In the spoiler below is the layout of the struct for each AHK build.
First, th32DefaultHeapID must sit on an address offset from the start of the struct that is a multiple of its size (8 bytes). The previous member th32ProcessID, occupies offset 8 to 12. The compiler inserts 4 "pad" bytes here so that th32DefaultHeapID can sit at offset 16.
Second, th32DefaultHeapID is itself 4 bytes larger on 64 bit compared to on 32 bit.
Third and last, the size of the entire structure must be a multiple of its largest member (Exercise: Why?). The structure as defined would be 564 bytes, which is 4 bytes short of being divisible by the size of th32DefaultHeapID. Again, 4 more "pad" bytes are inserted to make it work.
Together, these account for the 12 byte difference between 64 and 32 bit versions of the structure. In the spoiler below is the layout of the struct for each AHK build.
Spoiler
This spoiler contains the exercise answer.
Spoiler
Re: Who called my app?
Can you tell me how to write this partChef wrote:
return, process[property]
I tried all types but final was process[ParentProcessId] etc, and example would help a lot
Who is online
Users browsing this forum: filipemb and 361 guests