我的主要目标是打开远程桌面,并在远程会话结束时将其释放。我正在尝试将Mstsc.exe托管在winform应用程序中,因此我将管理进程的关闭并将释放命令发送到远程PC。这可以通过批处理文件来完成:
for /f "skip=1 tokens=3" %%s in ('query user %USERNAME%') do ( %windir%\System32\tscon.exe %%s /dest:console)
C#代码:
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
添加远程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为true已打开mstsc。如何获取MSTSC.exe的MainWindowHandle?
谢谢
远程桌面客户端的实现方式似乎是,使用命令行参数启动时,它将处理参数,启动单独的进程(如果参数有效),然后终止原始进程。
这意味着您将需要一个代表新进程的Process
实例,以便将句柄获取到其主窗口。
添加到您的原始代码:
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
?)。