Найти все дочерние процессы моего собственного .NET-процесса / выяснить, является ли данный процесс дочерним для меня? - PullRequest
8 голосов
/ 25 августа 2011

У меня есть библиотека классов .NET, которая запускает дополнительный процесс, который продолжается до тех пор, пока я не избавлюсь от объекта.

Из-за некоторых задержек программы в памяти я решил добавить интеграционный тест, чтобы убедиться, что, если я позволю объекту перейти к GC / Finalization, этот процесс будет замедлен.

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

Итак, я хочу убедиться, что клиент Mercurial, который я нахожу (или нет), является тем, кого я запустил, а не просто любым клиентом, который в данный момент работает.

Итак, вопрос такой:

  • Как я могу узнать, запущен ли клиент Mercurial, на который я смотрю, моим процессом?

«Глядя на», я смотрел на использование метода Process.GetProcesses , но это не является обязательным требованием.

Если другой вопрос лучше, «Как найти все дочерние процессы моего собственного процесса», т.е. проще ответить, что и этого более чем достаточно.

Я нашел эту страницу: Как узнать идентификатор родительского процесса для процесса? , но мне кажется, что я должен дать ему имя процесса. Если я просто скажу «hg», разве этот вопрос не слишком двусмысленный для искомого случая?

Ответы [ 2 ]

18 голосов
/ 25 августа 2011

как оказалось, у меня есть немного кода на C # / WMI, который рекурсивно убивает все процессы, порожденные указанным идентификатором процесса. убийство, очевидно, не то, что вы хотите, но, похоже, вас интересует поиск дочерних процессов. Надеюсь, это полезно:

    private static void KillAllProcessesSpawnedBy(UInt32 parentProcessId)
    {
        logger.Debug("Finding processes spawned by process with Id [" + parentProcessId + "]");

        // NOTE: Process Ids are reused!
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(
            "SELECT * " +
            "FROM Win32_Process " +
            "WHERE ParentProcessId=" + parentProcessId);
        ManagementObjectCollection collection = searcher.Get();
        if (collection.Count > 0)
        {
            logger.Debug("Killing [" + collection.Count + "] processes spawned by process with Id [" + parentProcessId + "]");
            foreach (var item in collection)
            {
                UInt32 childProcessId = (UInt32)item["ProcessId"];
                if ((int)childProcessId != Process.GetCurrentProcess().Id)
                {
                    KillAllProcessesSpawnedBy(childProcessId);

                    Process childProcess = Process.GetProcessById((int)childProcessId);
                    logger.Debug("Killing child process [" + childProcess.ProcessName + "] with Id [" + childProcessId + "]");
                    childProcess.Kill();
                }
            }
        }
    }
1 голос
/ 14 ноября 2017

Хотя ответ mtijn , вероятно, самый близкий, который вы можете получить, реальный ответ: вы не можете.

Windows не поддерживает реальное дерево процессов, где процессы реструктурируются, когда процесс на промежуточном уровне умирает. Однако Windows запоминает идентификатор родительского процесса.

Проблемным случаем является следующее:

Оригинальная структура процесса:

YourApp.exe
- SubApp.exe
  - Second.exe

Если теперь SubApp.exe завершает работу, идентификатор родительского процесса Second.exe не будет обновляться. Новый результат

YourApp.exe
Second.exe

Вы можете проверить это с помощью SysInternals Process Explorer. Он способен показывать процессы в виде дерева. Запустите CMD, затем введите start cmd. В новом окне введите start cmd еще раз. У вас будет 3 открытых окна. Теперь завершите средний.

...