为什么,当从c#执行mstsc.exe(远程桌面)时,进程已退出=true并且没有MainWindowHandle

为什么,当从c#执行mstsc.exe(远程桌面)时,进程已退出=true并且没有MainWindowHandle,c#,windows,winforms,remote-desktop,rdp,C#,Windows,Winforms,Remote Desktop,Rdp,我的主要目标是打开远程桌面,并在远程会话结束时释放它。 我正在尝试在winform应用程序中托管Mstsc.exe,因此我将管理进程的关闭并向远程PC发送释放命令。 这可以通过批处理文件完成: for /f "skip=1 tokens=3" %%s in ('query user %USERNAME%') do ( %windir%\System32\tscon.exe %%s /dest:console) c#代码: 添加远程PC的机箱 Process p = Proce

我的主要目标是打开远程桌面,并在远程会话结束时释放它。 我正在尝试在winform应用程序中托管Mstsc.exe,因此我将管理进程的关闭并向远程PC发送释放命令。 这可以通过批处理文件完成:

for /f "skip=1 tokens=3" %%s in ('query user %USERNAME%') do (  %windir%\System32\tscon.exe %%s /dest:console)
c#代码:

添加远程PC的机箱

        Process p = Process.Start(Environment.ExpandEnvironmentVariables(@"C:\Windows\system32\cmdkey.exe "), string.Format(" /generic:TERMSRV/{0} /user:{1} /pass:{2}", host, userName, password));
打开远程桌面:

        Process mainP = Process.Start(@"C:\Windows\system32\mstsc.exe ", (" /v " + host));
        mainP.Exited += P_Exited;
        while (mainP.MainWindowHandle ==null || mainP.MainWindowHandle == IntPtr.Zero)
        {
            Thread.Sleep(20);
            //mainP.Refresh();

        }
        Console.WriteLine(mainP.MainWindowHandle);
        SetParent(mainP.MainWindowHandle, panel1.Handle);
MainWindowHandle始终为零,如果刷新进程,则会出现异常。 mainP.HasExited为真,尽管mstsc已打开。 如何获取MSTSC.exe的MainWindowHandle


感谢

远程桌面客户端的实现方式似乎是,当使用命令行参数启动时,它将处理参数,启动单独的进程(如果参数有效),然后终止原始进程

这意味着您将需要一个表示新流程的
流程
实例,以便获得其主窗口的句柄

向原始代码中添加:

Process mainP = Process.Start(@"C:\Windows\system32\mstsc.exe ", (" /v " + "CLSERVER"));
mainP.WaitForExit();
mainP.Dispose();
Process otherP;
while ((otherP = Process.GetProcessesByName("mstsc").FirstOrDefault()) == null) {
    Thread.Sleep(20);
}
otherP.Exited += P_Exited;
while (otherP.MainWindowHandle == IntPtr.Zero) {
    Thread.Sleep(20);
}
Console.WriteLine(otherP.MainWindowHandle);
SetParent(otherP.MainWindowHandle, panel1.Handle);

在使用上述代码时,我能够成功地获得句柄,但是它不能解释mstsc.exe的多个实例-如果您需要区分它们,则需要更仔细地检查这些进程(可能查看
MainWindowTitle
?).

我在我的机器上测试了这一点,发现当您使用/v开关并且原始进程终止时,mstsc.exe会启动一个单独的进程(不同的PID)。您需要先找到新进程,然后才能获得其主窗口句柄:“这在技术上是合法的。玩链锯在技术上也是合法的……如果所涉及的一个或两个窗口都不知道它正在参与跨进程窗口树,则几乎无法管理链锯。(我经常在某人想要抓住属于另一个进程的窗口并强行将其移植到自己的进程中时看到这个问题……”
Process mainP = Process.Start(@"C:\Windows\system32\mstsc.exe ", (" /v " + "CLSERVER"));
mainP.WaitForExit();
mainP.Dispose();
Process otherP;
while ((otherP = Process.GetProcessesByName("mstsc").FirstOrDefault()) == null) {
    Thread.Sleep(20);
}
otherP.Exited += P_Exited;
while (otherP.MainWindowHandle == IntPtr.Zero) {
    Thread.Sleep(20);
}
Console.WriteLine(otherP.MainWindowHandle);
SetParent(otherP.MainWindowHandle, panel1.Handle);