Родительский процесс и отношение дочернего процесса - PullRequest
2 голосов
/ 26 июля 2010

У меня есть родительский процесс, который открывает дочерний процесс.Мне нужно выполнять некоторые функции только тогда, когда родительский процесс больше не работает.

Как лучше всего узнать, что родительский процесс не запущен?Поскольку это может быть принудительно завершено, я не хочу делать некоторые функции, которые будут отправлять мой дочерний процесс сигнал о событии закрытия.

Или просто искать мой родительский процесс следующим образом:

В родителе сделайте это и передайте его ребенку Process.GetCurrentProcess().Id А в ребенке проверяйте это каждые несколько миллисекунд

Process localById = Process.GetProcessById(1234);

Есть идеи?Рекомендации ..

Ответы [ 4 ]

4 голосов
/ 26 июля 2010

Вот простой пример использования Process.WaitForExit для проверки родительского процесса, чей идентификатор был передан в командной строке:

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 Forms вам не нужно его использовать, поскольку ваша программа будет находиться в цикле обработки сообщений и завершится, только если вы закроете его.

4 голосов
/ 26 июля 2010

Основной дескриптор процесса Win32 является ожидаемым и будет сигнализироваться при выходе из процесса.

В нативном коде:

DWORD res = WaitForSIngleObject(hProcess, INFINITE);
if (res == WAIT_OBJECT_0) {
  // process has exited.
}

В нативном коде вам нужно либо создать пользовательский подтип WaitHandle для дескрипторов процесса, либо использовать P / Invoke. Недостаток P / Invoke состоит в том, что его сложнее комбинировать (используя WaitForMultipleObjects несколько ожиданий, поэтому вы не выделяете поток только для ожидания одной вещи).


Благодаря 0xA3 : просто используйте Process.WaitForExit (существует перегрузка с таймаутом, чтобы избежать неопределенного ожидания, и не делайте этого в потоке пользовательского интерфейса).

0 голосов
/ 09 апреля 2015

Я создал дочернюю библиотеку управления процессами, в которой родительский процесс и дочерний процесс отслеживаются с помощью двунаправленного канала WCF. Если либо дочерний процесс завершается, либо родительский процесс завершает работу друг друга, это уведомляется. Также доступен помощник отладчика, который автоматически присоединяет отладчик VS к запущенному дочернему процессу.

Двунаправленный канал WCF является расширяемым, и вы можете обрабатывать события запуска и завершения процесса.

Сайт проекта:

http://www.crawler -lib.net / дочерние процессы

Пакеты NuGet:

https://www.nuget.org/packages/ChildProcesses https://www.nuget.org/packages/ChildProcesses.VisualStudioDebug/

0 голосов
/ 26 июля 2010

Когда родительский процесс запускает дочерний процесс, передайте идентификатор родительского процесса дочернему процессу через аргументы командной строки.

Затем в дочернем процессе используйте Process.GetProcessById(int), чтобы получить родительский процесс и использовать Process.WaitForExit().В качестве альтернативы вы используете событие Process.Exited для получения уведомления при выходе из родительского процесса (не забудьте установить Process.EnableRaisingEvents в true, в противном случае событие не будет инициировано).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...