有没有办法调用CreateProcess以便杀死父进程自动杀死子进程?
也许使用Create Process Flags?
编辑
解决方案是创建一个作业对象,将父级和子级都放在作业对象中。当他的父母被杀时,孩子也被杀了。我从这里得到代码:
杀死父进程时杀死子进程
注意@wilx关于继承句柄的评论。
有没有办法调用CreateProcess以便杀死父进程自动杀死子进程?
也许使用Create Process Flags?
编辑
解决方案是创建一个作业对象,将父级和子级都放在作业对象中。当他的父母被杀时,孩子也被杀了。我从这里得到代码:
杀死父进程时杀死子进程
注意@wilx关于继承句柄的评论。
像尼尔所说的那样使用工作是恕我直言的最好方法。您可以通过JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
在作业对象上使用SetInformationJobObject()
. 当您的父进程退出/死亡时,作业对象句柄将关闭。为此,作业句柄不被子进程继承是很重要的。如果您还想跟踪孙子进程,那么您将必须创建暂停的子进程,将它们添加到您的作业对象中,然后才让它们运行。
您可以做的最好的事情是将两个进程放在同一个作业中,以便杀死作业会杀死两个进程。
您是否需要杀死子进程,或者仅仅检测父进程退出以便它可以干净地终止?父进程可以为自己创建一个可继承的句柄,然后子进程可以将WaitForMultipleObjects(Ex)
其与自己的对象一起传递给它。
如果子进程不是专门为此编写的,则可以将其标准输入附加到管道,管道的另一端由父进程持有。如果父节点死亡,管道将自动关闭。
这与 Unix 行为非常相似,其中子代在其父代死亡时不会被杀死,它通常会退出以响应SIGHUP
(但它可以处理该信号并实现任何行为)。在 Linux 上,孤儿的父 PID 更改为 1 (init)。
不同的方法
并非在所有情况下都有用,但是我有一个特定的场景,即应用程序完全控制子进程。对于通信和 API 拦截,需要 DLL 注入,因此 DLL 在实际子进程中运行以向父进程报告。
注意:现在,这不是创意奖。这里的背景是:需要包装的应用程序,但它是遗留应用程序,既不能修改,也不能以令人满意的方式重写。我们需要保持这个系统运行,同时仍然截取它的输出。
另外,子进程写得不好,立即再次启动然后终止,因此父进程实际上不是我们的主要应用程序。
如果你控制子进程并且有一个注入的 DLL,你可以通过监视父进程来扩展这个 DLL,以检查它是否正在运行。如果没有,ExitProcess
.
如果您不需要子进程中的 DLL,则其他解决方案很可能要好得多。
parentProcessID
例如,您可以通过您的应用程序已经使用的注册表项进行传输。或者,如果这不会破坏子进程,您可以传递命令行。
这必须在自己的线程中运行。我的 DLL 有两个线程:这里的代码和控制和通信代码。
动态链接库
bool IsProcessRunning(HANDLE hProcess)
{
DWORD exitCode;
GetExitCodeProcess(hProcess, &exitCode);
return exitCode == STILL_ACTIVE;
}
bool WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
int parentProcessID = [...]
HANDLE parentProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, parentProcessID);
while (IsProcessRunning(parentHandle)) Sleep(100);
ExitProcess(0);
}
return true;
}
我想DEBUG_PROCESS
或DEBUG_ONLY_THIS_PROCESS
会这样做几乎是偶然的副作用。Windows 不像类 Unix 系统那样在树中创建进程。
不了解 Windows,但这将适用于 linux:prctl(PR_SET_PDEATHSIG, SIGHUP);