确定当前应用程序的父进程

时间:2009-12-06 23:36:38

标签: delphi winapi

我编写了这个实用程序(exe),可以从这个宿主应用程序中调用它。 我更喜欢它只能从主机应用程序调用该实用程序。 从外部或其他主机运行它应立即终止该实用程序。

有没有办法找出哪个进程启动了我的实用程序?

感谢您的回复。

5 个答案:

答案 0 :(得分:9)

您可以使用CreateToolhelp32Snapshot函数枚举正在运行的进程列表,然后使用Process32First函数来获取th32ParentProcessID,它是创建此进程的进程的标识符(其父级)处理)。

请参阅此示例。

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;

答案 1 :(得分:2)

如果guid不是传递给实用程序的参数的一部分,我会添加一个你只知道的额外参数(它可以是一个guid)。立即终止应用程序。

答案 2 :(得分:2)

您问题的快速回答是“嗯,不,您不能阻止执行申请”。如果它是可执行文件,则可以执行它。没办法阻止它。

并且,如果您无法控制应用程序(正如您的评论似乎表明的那样)那么Gs的优秀建议将无效,对吧?你无法控制应用程序的功能,也无法控制它对你的特殊命令行的反应。

所以这确实是一个有趣的情况。

我看到的唯一方法是完全阻止访问EXE,或者至少让它很难找到它。

你可以这样做:

  1. 将EXE作为资源嵌入主机EXE
  2. 当运行EXE时,然后使用TResourceStream
  3. 提取它
  4. 使用TFileStream
  5. 从TResourceStream写出来
  6. 执行
  7. 完成后删除它。
  8. 并不漂亮,但这是我能想到的唯一方法,让EXE不再按照您的条款和条款运行。

答案 3 :(得分:1)

如果仅从主机内部运行此应用程序,为什么不在主应用程序中包含应用程序的表单,并像其他表单一样激活它?

答案 4 :(得分:1)

我们使用一种相当简单的技术,只需几行代码。父应用程序和实用程序应用程序使用一些常见的GUIID字符串(在代码中)并调用RegisterWindowMessage来创建一种“Hello”握手协议。当实用程序应用程序首次启动时,它会发布该消息。如果父应用程序正在运行,并且确实启动了该实用程序,它会发布响应消息,该实用程序会看到并且一切正常。如果没有,则该实用程序会超时并退出。