Determine the parent process of the current app
I wrote this utility (exe) which can be called from within this host application. And I'd prefer it that the utility can only be开发者_JAVA百科 called from the host application. Running it from the outside or a different host should terminate the utility immediately.
Is there a way to find out which process launched my utility?
Thanks for the replies.
You can use the CreateToolhelp32Snapshot function to enumerate the running process list and then the Process32First function to get the th32ParentProcessID which is the identifier of the process that created this process (its parent process).
See this example .
uses
Psapi,
Windows,
tlhelp32,
SysUtils;
function GetTheParentProcessFileName(): String;
const
BufferSize = 4096;
var
HandleSnapShot : THandle;
EntryParentProc : TProcessEntry32;
CurrentProcessId: DWORD;
HandleParentProc: THandle;
ParentProcessId : DWORD;
ParentProcessFound : Boolean;
ParentProcPath : String;
begin
ParentProcessFound := False;
HandleSnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //enumerate the process
if HandleSnapShot <> INVALID_HANDLE_VALUE then
begin
EntryParentProc.dwSize := SizeOf(EntryParentProc);
if Process32First(HandleSnapShot, EntryParentProc) then //find the first process
begin
CurrentProcessId := GetCurrentProcessId(); //get the id of the current process
repeat
if EntryParentProc.th32ProcessID = CurrentProcessId then
begin
ParentProcessId := EntryParentProc.th32ParentProcessID; //get the id of the parent process
HandleParentProc := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ParentProcessId);
if HandleParentProc <> 0 then
begin
ParentProcessFound := True;
SetLength(ParentProcPath, BufferSize);
GetModuleFileNameEx(HandleParentProc, 0, PChar(ParentProcPath),BufferSize);
ParentProcPath := PChar(ParentProcPath);
CloseHandle(HandleParentProc);
end;
break;
end;
until not Process32Next(HandleSnapShot, EntryParentProc);
end;
CloseHandle(HandleSnapShot);
end;
if ParentProcessFound then
Result := ParentProcPath
else
Result := '';
end;
I would add an extra parameter that you only know about ( it can be a guid ) if that guid is not part of the parameters passed to your utility .. Terminate the application right away.
The quick answer to your question is "Well, no, you can't prevent an application from being executed". If it is an executable, then it can be executed. No way to stop that.
And, if you can't control the application (as your comments seem to indicate) then Gs's excellent suggestion won't work, right? You don't have any way of controlling what the app does and you can't control it's reaction to your special command line.
So this does present an interesting situation.
The only way I see around this is to prevent access to the EXE altogether, or at least make it hard to find it.
You could do this:
- Embed the EXE into your host EXE as a resource
- When the time comes to run the EXE, then extract it using TResourceStream
- Write it out from the TResourceStream using TFileStream
- Execute it
- Delete it when you are done.
Not pretty, but it is the only way I can think of to keep the EXE from being run on your terms and your terms only.
We use a fairly simple technique that just takes a few lines of code. The parent app and the utility app use some common GUIID strings (in code) and call RegisterWindowMessage to create a sort of "Hello" handshake protocol. When the utility app first fires up, it posts that message. If the parent app is running, and did start the utility, it posts the response message, which the utility sees and all is well. If not, the utility times out and exits.
If this application is only being run from inside the host, why not just include the forms for the application inside the main application, and activate it as you would another form?
精彩评论