2009-12-06 56 views
8

我编写了可在此主机应用程序中调用的此实用程序(exe)。 我宁愿它只能从主机应用程序调用该实用程序。 从外部或其他主机运行它应立即终止实用程序。确定当前应用程序的父进程

有没有办法找出哪个进程启动了我的工具?

感谢您的回复。

+0

我已经得到了SysInternals ProcessExplorer,它显示了所有当前正在运行的进程以及每个启动进程的树,因此这些信息肯定可用。问题是如何访问它,不幸的是,我不知道它。我会将“winapi”标签添加到您的帖子中,并使其更加清晰,这就是您要查找的内容。 – 2009-12-07 01:47:56

+0

我见过的最佳答案是http://stackoverflow.com/a/3346055/647492 – 2012-12-20 21:36:41

回答

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; 
+0

感谢RRUZ!正是我一直在寻找的。 :) – Rick 2009-12-07 04:36:17

1

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

+2

我们没有写这个宿主程序。有这个能力来执行另一个应用程序。我只是碰巧知道他们是如何执行它的。 谢谢蒂姆! – Rick 2009-12-06 23:52:42

2

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

+0

我去过那条路。问题是通过主机应用程序的设置或设置屏幕可以看到传递给实用程序的参数。而且我无法指示主机应用程序在其他地方寻找一些魔术密钥。 谢谢Gs! – Rick 2009-12-07 02:04:18

2

对你的问题的快速回答是“嗯,不,你不能阻止应用程序被执行”。如果它是一个可执行文件,那么它可以被执行。没办法阻止。

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

所以这确实提出了一个有趣的情况。

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

你可以这样做:在时机成熟时运行EXE

  1. 嵌入的EXE到你的主机EXE作为资源
  2. ,然后使用TResourceStream
  3. 写出来从提取它使用TFileStream的TResourceStream
  4. 执行它
  5. 完成后删除它。

不是很漂亮,但它是我能想到的唯一方法,使EXE不会只依照条款和条件运行。

+3

看起来他问的是如果可以验证启动应用程序的进程的身份,然后立即终止,如果它是错误的。这应该是可能的。 – 2009-12-07 01:42:55

1

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

+0

父应用程序将不得不被修改/重写来实现它。那是对的吗 ? – Rick 2009-12-10 22:46:54

+0

是的。我没有看到第三方应用程序是运行该实用程序的应用程序,直到我写完该程序。我的错。 – 2009-12-16 21:31:25