父进程和子进程关系
Posted
技术标签:
【中文标题】父进程和子进程关系【英文标题】:Parent process and child process relation 【发布时间】:2010-07-26 07:44:48 【问题描述】:我有打开子进程的父进程。只有当父进程不再运行时,我才需要执行一些功能。
知道父进程未运行的最佳方法是什么?因为它可能会被暴力终止,所以我不想做一些功能会在关闭事件时向我的子进程发送信号。
或者只是像这样寻找我的父进程:
在父母中做这个并将其传递给孩子Process.GetCurrentProcess().Id
并且在孩子每隔几毫秒检查一次这个
Process localById = Process.GetProcessById(1234);
有什么想法吗?建议..
【问题讨论】:
Erm... 通常它是一个父进程。除非你真的认识到你的过程的性别。干杯。 @AOI Karasu:大声笑,说得好,我冒昧地改变了它(如果性别很重要,请恢复我的改变,夜行者)。 我刚刚发布了一个.NET的子进程库childprocess.codeplex.com 【参考方案1】:下面是一个简单的例子,如何使用Process.WaitForExit
来检查其 id 已在命令行中传递的父进程:
using System;
using System.Diagnostics;
using System.Threading;
class Program
static AutoResetEvent _autoResetEvent;
static void Main(string[] args)
int parentProcessId = int.Parse(args[0]);
_autoResetEvent = new AutoResetEvent(false);
WaitCallback callback = delegate(object processId) CheckProcess((int)processId); ;
ThreadPool.QueueUserWorkItem(callback, parentProcessId);
_autoResetEvent.WaitOne();
static void CheckProcess(int processId)
try
Process process = Process.GetProcessById(processId);
process.WaitForExit();
Console.WriteLine("Process [0] exited.", processId);
catch (ArgumentException)
Console.WriteLine("Process [0] not running.", processId);
_autoResetEvent.Set();
使用Process.Exited
事件可以这样完成:
using System;
using System.Diagnostics;
using System.Threading;
class Program
static AutoResetEvent _autoResetEvent;
static void Main(string[] args)
int parentProcessId = int.Parse(args[0]);
Process process = Process.GetProcessById(parentProcessId);
process.EnableRaisingEvents = true;
process.Exited += new EventHandler(process_Exited);
_autoResetEvent = new AutoResetEvent(false);
_autoResetEvent.WaitOne();
static void process_Exited(object sender, EventArgs e)
Console.WriteLine("Process exit event triggered.");
_autoResetEvent.Set();
请注意,在这两个示例中,AutoResetEvent
的目的仅仅是为了防止您的主线程退出。在 Windows 窗体应用程序中,您不需要使用它,因为您的程序将处于消息循环中,并且只有在您关闭它时才会退出。
【讨论】:
我使用了 Process.Exited 示例。真的很感谢你的解释。【参考方案2】:底层 Win32 进程句柄是可等待的,将在进程退出时发出信号。
在本机代码中:
DWORD res = WaitForSIngleObject(hProcess, INFINITE);
if (res == WAIT_OBJECT_0)
// process has exited.
在本机代码中,您需要为进程句柄创建 WaitHandle
的自定义子类型,或者使用 P/Invoke。 P/Invoke 的缺点是它更难组合(使用WaitForMultipleObjects
多次等待,因此您不会专门使用一个线程来等待一件事)。
感谢0xA3:只需使用Process.WaitForExit
(有超时的过载以避免无限期等待,不要在你的UI线程上这样做)。
【讨论】:
对不起,我真的不想去 Native Code 。 @Night Walker:没必要,直接用Process.WaitForExit
。最好放在单独的线程中。
但是我需要在子进程中等待父进程。不确定 Process.WaitForExit 如何提供帮助。
@NightWalker:父进程将父进程的 id 传递给子进程(例如在命令行上),或者对子进程使用 WMI 和 Win32_Process 请求并使用父进程 id 属性。一旦你有了父进程的 id,你就可以得到一个带有 Process.GetProcessById()
的 Process 实例。【参考方案3】:
当父进程启动子进程时,通过命令行参数将父进程ID传递给子进程。
然后在子进程上,使用Process.GetProcessById(int)
获取父进程,使用Process.WaitForExit()
。或者,您可以使用Process.Exited
事件在父进程退出时获得通知(记得将Process.EnableRaisingEvents
设置为true
,否则不会引发该事件)。
【讨论】:
【参考方案4】:我制作了一个子进程管理库,其中父进程和子进程通过双向 WCF 管道进行监控。如果子进程终止或父进程相互终止,则会收到通知。 还有一个调试器助手可用,它会自动将 VS 调试器附加到启动的子进程。
双向 WCF 通道是可扩展的,您可以处理进程启动和进程终止事件。
项目地点:
http://www.crawler-lib.net/child-processes
NuGet 包:
https://www.nuget.org/packages/ChildProcesses https://www.nuget.org/packages/ChildProcesses.VisualStudioDebug/
【讨论】:
以上是关于父进程和子进程关系的主要内容,如果未能解决你的问题,请参考以下文章