问题描述
我尝试做的最终目标是将 MMC(Microsoft 管理控制台)计算机管理管理单元 (compmgmt.msc) 进程嵌入到 Windows 窗体中,或将其视为一个解决方法模态弹出菜单.
The end goal of what I am trying to do is get the MMC (Microsoft Management Console) Computer Management snap-in (compmgmt.msc) process to be embedded into a Windows Form, or a workaround that will treat it like a modal pop-up menu.
现在,在尝试加载管理单元之前,我只是想让 mmc.exe 本身正常工作.问题的第一部分是 mmc.exe 进程几乎立即退出.
Right now, I am just trying to get mmc.exe itself working, before I try to load a snap-in. The first part of the problem is the mmc.exe process almost exits immediately.
mmc.exe 只有在应用程序构建为 32 位(我的机器是 64 位)时才会立即退出.如果应用程序构建为 64 位,则第一个进程会保留,这就是预期的行为.但是,我仍然很好奇为什么会发生奇怪的临时进程行为.请注意,启动的临时 mmc.exe 进程是 32 位的,但最终启动的 mmc.exe 是 64 位的.奇怪.
mmc.exe only exits immediately if the application is built as 32-bit (my machine is 64-bit). If the application is built to be 64-bit, the first process stays, which is what the expected behavior is.However, I am still curious for an explanation as to why the strange temporary process behavior occurs. Note that the temporary mmc.exe process that is launched is 32-bit, but the final mmc.exe launched is 64-bit. Strange.
以下代码将成功将 iexplore.exe 嵌入 Windows 窗体中,但无法嵌入 mmc.exe.它失败的原因是调用 p.WaitForInputIdle(); 时发生的异常;
The following code will successfully embed iexplore.exe inside a Windows Form, but it fails to embed mmc.exe.The reason it fails is an exception that occurs at the call to p.WaitForInputIdle();
System.InvalidOperationException"类型的未处理异常发生在 System.dll
附加信息:无法处理请求,因为进程有退出.
正如您从错误消息中看到的,该进程在几毫秒内退出,但从用户的角度来看,MMC 的 GUI 仍然作为一个单独的、与我启动的原始进程无关的进程弹出.
As you can see from the error message, the process exits within milliseconds, but from a user's point of view, the MMC's GUI does still pop up as a separate, unrelated process to the original one I started.
这意味着正在创建另一个 mmc.exe 进程,该进程似乎与创建的原始进程没有联系.
This means that another mmc.exe process is being created which seems to have no connection to the original process created.
那么问题是:为什么 MMC 进程立即关闭,而另一个 MMC 进程几乎立即打开?
相关的Windows Form代码,类似于这个问题.
Relevant Windows Form code, similar to 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-然后立即停止
随之而来的一个问题是,即使我找到了弹出的新 mmc 进程,它似乎将 MainWindowHandle 设置为 null,可能意味着 Windows 没有't 将其识别为具有 GUI.
A subsequent issue to this was that even when I 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.
解决这个问题的方法很简单,在创建临时"mmc 进程和等待新进程实际准备好之间添加睡眠(暂停).注意 process.WaitForInputIdle();没有等待足够长的时间.
The workaround to this was as simple adding sleep (a pause) between creating the "temporary" mmc process, and waiting for the new process to actually be ready. Note that process.WaitForInputIdle(); did not serve as a long-enough wait.
对于可能和我有同样问题的任何人:
For anyone that might be having the same trouble as I had:
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)
It exits because it may need to use a different bit-depth of MMC to run the snapin. As I am just learning now, snapins can be 32-bit or 64-bit. Windows may need to restart the snapin using either C:\Windows\SysWOW64\mmc.exe (1.34 MB (1,409,024 bytes)) or using C:\Windows\System32\mmc.exe (1.71 MB (1,802,240 bytes)).https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms692753(v=vs.85)
所以,对我来说,手头的任务似乎是如何在启动管理单元之前发现管理单元的位深度.
So, for me, the task at hand seems to be how to discover, before launching a snapin, that snapin's bit-depth.
这篇关于MMC 进程立即关闭,无法链接到 Windows 窗体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!