View Full Version : Which app called my app?
LigH
24th October 2007, 15:55
Please excuse ... I am not a native english speaker, and I just had no luck guessing a useful search query in the MSDN or in Google:
How can I find out which application (preferably the full path and filename) called my application, using Win32 API calls? For example, if I executed my app from the Windows Explorer, I'd expect to get "C:\WINDOWS\explorer.exe" returned.
Kurtnoise
24th October 2007, 16:22
Hi,
Is that (http://en.wikipedia.org/wiki/Windows_Search) what you want ?
LigH
24th October 2007, 16:29
Not at all?!
I'm looking for Win32API functions. Like some already present in the source of application A:
- CreateProcess to execute an application B from application A;
- WaitforSingleObject and GetExitCodeProcess to let application A wait until application B closed.
What I miss is the function(s) to let application B know that application A executed it, to be implemented into the source of application B.
Selur
24th October 2007, 18:58
iirc it's possible to monitor win32 api calls, though it should be possible to monitor the calls filter the content you want,...
M_Knox
24th October 2007, 20:09
Here's some Delphi code I just put together. The code uses ToolHelp32 functions (CreateToolhelp32Snapshot, Process32First, Process32Next) and a PSAPI function (GetModuleFileNameEx). FYI, this piece of code is not Win9x compatible (because of the GetProcessTimes and GetModuleFileNameEx functions usage).
procedure DisplayParentInfo();
var
snap: DWORD;
pe32: PROCESSENTRY32;
currprocid: DWORD;
parentproc: DWORD;
parentprocid: DWORD;
parentpath: string;
isparent: Boolean;
time_currentproc: FILETIME;
time_create: FILETIME;
time_exit: FILETIME;
time_kernel: FILETIME;
time_user: FILETIME;
begin
isparent := False;
//create snapshot of all processes
snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if snap <> INVALID_HANDLE_VALUE then
begin
pe32.dwSize := SizeOf(pe32);
//walk through processes to find the current process info
if Process32First(snap, pe32) then
begin
currprocid := GetCurrentProcessId(); //store current process id for faster access
repeat
if pe32.th32ProcessID = currprocid then
begin
//we've found the current process info
{
now we should compare current process start time with the parent process
start time, to check if the parent process CAN be the real parent
(process identifiers are reusable, so when the parent process terminates,
any other process started later on can get the same ID)
}
GetProcessTimes(GetCurrentProcess(), time_create, time_exit, time_kernel, time_user);
time_currentproc := time_create;
parentprocid := pe32.th32ParentProcessID;
parentproc := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, parentprocid);
if parentproc <> 0 then
begin
if GetProcessTimes(parentproc, time_create, time_exit, time_kernel, time_user) then
begin
isparent := CompareFileTime(time_create, time_currentproc) < 0;
{
now we determined, that parentprocess CAN BE
the parent of the current process
}
SetLength(parentpath, 1024); //1024 should be enough for the full path :)
GetModuleFileNameEx(parentproc, 0, PChar(parentpath), 1024);
parentpath := PChar(parentpath);
end;
CloseHandle(parentproc);
end;
break; //do not enumerate any further
end;
until not Process32Next(snap, pe32);
end;
CloseHandle(snap);
end;
if parentpath <> '' then
begin
if isparent then
MessageBox(Handle,
PChar(parentpath),
PChar('Full path of the parent process [' + IntToStr(parentprocid) + ']'),
MB_ICONINFORMATION
)
else
MessageBox(Handle,
PChar(parentpath + #13#10#13#10 +
'Process [' + IntToStr(parentprocid) + '] found, but it is not the parent of the current process'
),
PChar('Full path of the process [' + IntToStr(parentprocid) + ']'),
MB_ICONEXCLAMATION
);
end;
end;
tuber99
25th October 2007, 15:12
I am a big fan of the sysinternals.com utilities/tools. They were recently purchased by MS, but the tools haven't changed. The one you probably want to start with is Process Explorer (http://www.microsoft.com/technet/sysinternals/ProcessesAndThreads/ProcessExplorer.mspx).
It will show all the processes running on your PC and they are displayed in hierarchical ownership order. So, if your ProcessX was launched by ProcessA, it will correctly display as a child process in the Process Explorer window.
This is also a great tool to watch CPU utilization by process and quickly find resource "hogs" on your PC.
LigH
25th October 2007, 15:44
@ tuber99:
ProcessExplorer is a great tool. But I can not make ProcessExplorer a function which my own program can use. My ProcessX itself has to be able to find out that it was launched from ProcessA. Looking with my eyes is no option.
__
@ M_Knox:
Looks complicated, but I will try it. Thank you for your efforts so far.
P.S.: Great, seems to work!
JohnnyMalaria
25th October 2007, 16:54
You can't get the information directly. The calling app (e.g., explorer.exe) just calls the CreateProcess() API function and then Windows creates the new process (your app).
To find out, you will have to hook the CreateProcess() function and monitor the lpApplicationName parameter. Naturally, you will need to write a separate dll/exe to do the monitoring.
Hooking article:
http://www.codeguru.com/Cpp/W-P/system/misc/article.php/c5667
LoRd_MuldeR
25th October 2007, 19:20
You can't get the information directly.
No, you can get those information without hooking the CreateProcess() function! You can use ToolHelp32 and PASPI for that purpose, see the sample code posted by M_Knox above! ProcessExplorer for example, a great tool anyway, can display the parent process of any process, even if ProcessExplorer was not running at the time when that process was created! Also, as far as I know, ProcessExplorer does not inject any DLL's into running processes in order to collect it's information...
http://img124.imageshack.us/img124/835/fileporcexpparentbt6.png (http://imageshack.us)
foxyshadis
26th October 2007, 07:15
MSDN has all the information on finding a process's parent (and other information) in Win32 and .Net if you're using one of those, as well. Of course it'll be wrong if the process was reparented or the parent killed, but there's usually a good reason for those.
LoRd_MuldeR
26th October 2007, 19:29
Of course it'll be wrong if the process was reparented or the parent killed, but there's usually a good reason for those.
I think M_Knox' code takes care of that case...
JohnnyMalaria
27th October 2007, 02:19
No, you can get those information without hooking the CreateProcess() function!
Cool! I even have an application for it (no pun intended, of course).
Sometimes it's good to be wrong :)
LigH
28th October 2007, 16:17
As I already said, the code provided by M_Knox was sufficient. It worked reliably for the test cases we needed.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.