Процесс MMC немедленно закрывается, не может ссылаться на формы Windows

Конечная цель того, что я пытаюсь сделать, — встроить процесс оснастки управления компьютером (compmgmt.msc) MMC (Microsoft Management Console) в форму Windows или обходной путь, который будет рассматривать его как модальное всплывающее окно. вверх меню.

Прямо сейчас я просто пытаюсь заставить работать сам mmc.exe, прежде чем пытаться загрузить оснастку. Первая часть проблемы заключается в том, что процесс mmc.exe почти завершается немедленно.

Изменить: mmc.exe завершает работу немедленно только в том случае, если приложение создано как 32-разрядное (у меня 64-разрядная версия). Если приложение построено как 64-разрядное, первый процесс остается, что и является ожидаемым поведением. Тем не менее, мне все еще любопытно объяснить, почему происходит странное временное поведение процесса. Обратите внимание, что запущенный временный процесс mmc.exe является 32-разрядным, а окончательный запущенный процесс mmc.exe — 64-разрядным. Странный.

Следующий код успешно встраивает iexplore.exe в форму Windows, но не может встроить mmc.exe. Причиной сбоя является исключение, возникающее при вызове p.WaitForInputIdle();

Произошло необработанное исключение типа «System.InvalidOperationException» в System.dll.

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

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

Это означает, что создается другой процесс mmc.exe, который, похоже, не имеет связи с исходным созданным процессом.

Итак, возникает вопрос: почему процесс MMC сразу же закрывается, а другой процесс MMC открывается почти сразу же?

Соответствующий код Windows Form, похожий на этот вопрос< /а>.

[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

private void Form1_KeyPress(object sender, EventArgs e)
{
    /// Uncomment *one* of these:
    //Process p = Process.Start("mmc.exe");
    //Process p = Process.Start("iexplore.exe");
    Thread.Sleep(500);

    p.WaitForInputIdle();

    Console.WriteLine("MainWindowHandle: " + p.MainWindowHandle);
    Console.WriteLine("Handle: " + p.Handle);

    Thread.Sleep(5000);
    SetParent(p.MainWindowHandle, this.Handle);
}

Связано, но вопрос, похоже, больше связан с закрытием самого графического интерфейса консоли, не позволяющим редактировать, а не с закрытием некоторого базового процесса. https://superuser.com/questions/194252/mmc-exe-starts-and-then-immediately-stops



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

Обходной путь для этого заключался в простом добавлении сна (паузы) между созданием «временного» процесса mmc и ожиданием фактической готовности нового процесса. Обратите внимание, что process.WaitForInputIdle(); не ждала достаточно долго.

Для тех, у кого могут быть такие же проблемы, как у меня:

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = Environment.SystemDirectory + "\\" + "mmc.exe";
startInfo.Arguments = "\"" + Environment.SystemDirectory + "\\compmgmt.msc\" /s";
Process tempProcess = Process.Start(startInfo);
tempProcess.WaitForExit();

Thread.Sleep(500); // Added pause!
// Better alternative is to use a while loop on (MainWindowHandle == null)
// with some sort of timeout

Process[] processes = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(startInfo.FileName));
foreach (Process process in processes)
{
    // do what you want with the process
    Console.WriteLine("MainWindowHandle: " + process.MainWindowHandle);
    // Set Computer Management window on top
    SetWindowPos(process.MainWindowHandle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
    SetParent(process.MainWindowHandle, this.Handle);
    SetWindowLong(process.MainWindowHandle, GWL_STYLE, WS_VISIBLE);

    process.WaitForExit();
}

Но основная проблема заключается в том, чтобы выяснить, почему завершается первый процесс MMC.


person Talset    schedule 02.11.2017    source источник
comment
Вы запускаете процесс от имени администратора?   -  person John Wu    schedule 02.11.2017
comment
Если вы имеете в виду сам скомпилированный MyWinForm.exe, да, я все равно получаю такое же поведение при работе от имени администратора. Если вы имеете в виду часть кода Process.Start(mmc.exe), то я не уверен - есть ли дополнительные аргументы, которые я должен добавить, чтобы убедиться, что он запущен на уровне администратора? Спасибо за чтение!   -  person Talset    schedule 02.11.2017
comment
Итак, я понимаю, что мой вопрос, возможно, был не самым правильным, потому что он почти состоит из двух частей. Я нашел обходной путь ко второй части моего вопроса о том, что MainWindowHandle имеет значение null, и я отредактирую, чтобы сделать ситуацию более ясной. Однако первый вопрос о том, почему процесс завершается, до сих пор меня сбивает с толку.   -  person Talset    schedule 03.11.2017
comment
единственным обходным путем был Thread.Sleep(5000); для меня   -  person Daniel B    schedule 03.11.2017
comment
Обновление: такое поведение при закрытии первого экземпляра mmc.exe происходит только в том случае, если приложение запускается как 32-разрядное. Если я установлю форму Windows для сборки как 64-битную, tempProcess останется активным, как вы обычно ожидаете при выполнении Process.Start()   -  person Talset    schedule 10.11.2017


Ответы (1)


Он закрывается, потому что для запуска оснастки может потребоваться использовать MMC с другой разрядностью. Как я только сейчас узнаю, оснастки могут быть 32-битными или 64-битными. Windows может потребоваться перезапустить оснастку с помощью C:\Windows\SysWOW64\mmc.exe (1,34 МБ (1 409 024 байта)) или с помощью C:\Windows\System32\mmc.exe (1,71 МБ (1 802 240 байт)). https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms692753(v=vs.85)

Итак, для меня задача заключается в том, как определить перед запуском оснастки ее битовую глубину.

person Sean Roberts    schedule 24.11.2019