【问题标题】: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

标签: c# .net process


【解决方案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/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-11
      • 1970-01-01
      • 1970-01-01
      • 2017-08-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多