MMC进程立即关闭,不能link到windows表格

MMC process immediately closing, can't link to windows forms

我正在尝试做的最终目标是将 MMC(Microsoft 管理控制台)计算机管理管理单元 (compmgmt.msc) 进程嵌入到 Windows 表单中,或者将其视为模态弹出菜单的解决方法。

现在,我只是想让 mmc.exe 本身正常工作,然后再尝试加载管理单元。问题的第一部分是 mmc.exe 进程几乎 立即退出

编辑: mmc.exe 只有当应用程序构建为 32 位(我的机器是 64 位)时才会立即退出。如果应用程序构建为 64 位,则第一个进程保留,这是预期的行为。 但是,我仍然很好奇为什么会出现奇怪的临时进程行为。请注意,启动的临时 mmc.exe 进程是 32 位的,但最终启动的 mmc.exe 进程是 64 位的。奇怪。

以下代码将成功地将 iexplore.exe 嵌入到 Windows 表单中,但无法嵌入 mmc.exe。 它失败的原因是在调用 p.WaitForInputIdle(); 时发生异常。

An unhandled exception of type 'System.InvalidOperationException' occurred in System.dll

Additional information: Cannot process request because the process has exited.

正如您从错误消息中看到的那样,进程在几毫秒内退出,但从用户的角度来看,MMC 的 GUI 仍然作为一个单独的、与我启动的原始进程无关的进程弹出。

这意味着正在创建另一个 mmc.exe 进程,它似乎与创建的原始进程无关。

所以问题是:为什么MMC进程立即关闭,而另一个MMC进程几乎立即打开?

相关Windows表单代码,类似this question.

[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);
}

相关,但问题似乎更多是关于控制台 GUI 本身的关闭,不允许编辑,而不是一些底层进程关闭。 https://superuser.com/questions/194252/mmc-exe-starts-and-then-immediately-stops



此问题的后续问题是,即使我 located the new mmc process that pops up, it appears to have MainWindowHandle set to null, possibly meaning Windows doesn't recognize it as having a GUI.

解决方法是在创建 "temporary" 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 进程退出的原因。

它退出是因为它可能需要使用不同位深度的 MMC 到 运行 管理单元。正如我现在刚刚了解到的那样,管理单元可以是 32 位或 64 位的。 Windows 可能需要使用 C:\Windows\SysWOW64\mmc.exe(1.34 MB(1,409,024 字节))或使用 C:\Windows\System32\mmc.exe(1.71 MB(1,802,240 字节))重新启动管理单元。 https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms692753(v=vs.85)

因此,对我来说,手头的任务似乎是如何在启动管理单元之前发现该管理单元的位深度。