Who called my app?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Guest

Who called my app?

14 Jan 2014, 05:19

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
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Who called my app?

14 Jan 2014, 05:21

Guest, see this. Basically the idea is to get the name of the parent process.
Guest

Re: Who called my app?

14 Jan 2014, 07:41

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?
User avatar
LinearSpoon
Posts: 156
Joined: 29 Sep 2013, 22:55

Re: Who called my app?

14 Jan 2014, 08:46

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.

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")
}
User avatar
Chef
Posts: 50
Joined: 14 Nov 2013, 13:01

Re: Who called my app?

14 Jan 2014, 10:03

Last edited by Chef on 14 Jan 2014, 13:51, edited 1 time in total.
User avatar
LinearSpoon
Posts: 156
Joined: 29 Sep 2013, 22:55

Re: Who called my app?

14 Jan 2014, 10:33

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*
User avatar
Chef
Posts: 50
Joined: 14 Nov 2013, 13:01

Re: Who called my app?

14 Jan 2014, 15:51

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*
Turned out it could be done without all those dllCalls, see my gist post above.
User avatar
trismarck
Posts: 506
Joined: 30 Sep 2013, 01:48
Location: Poland

Re: Who called my app?

21 Sep 2014, 06:15

LinearSpoon, thanks for the code. I have a question:

Code: Select all

VarSetCapacity(pEntry, sz := (A_PtrSize = 8 ? 48 : 36)+(A_IsUnicode ? 520 : 260))
Shouldn't there be 40 instead of 48? LONG seems to be 4 bytes on 64-bit Windows.

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
User avatar
LinearSpoon
Posts: 156
Joined: 29 Sep 2013, 22:55

Re: Who called my app?

21 Sep 2014, 17:34

@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.
Spoiler
This spoiler contains the exercise answer.
Spoiler
JeezLouise

Re: Who called my app?

22 Apr 2018, 05:09

Chef wrote:
Can you tell me how to write this part

return, process[property]

I tried all types but final was process[ParentProcessId] etc, and example would help a lot

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: filipemb and 361 guests