为什么,从 c# 执行 mstsc.exe(远程桌面)时,进程 HasExited = true 并且没有 MainWindowHandle
Why ,when executing mstsc.exe (remote desktop) from c# , the process HasExited = true and doesnt have MainWindowHandle
我的主要目标是打开远程桌面并在远程会话结束时将其释放回来。
我正在尝试在 winform 应用程序中托管 Mstsc.exe,因此我将管理进程的关闭并将释放命令发送到远程 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 是真的,虽然 mstsc 是开放的。
如何获得 MSTSC.exe 的 MainWindowHandle?
谢谢
远程桌面客户端的实现方式似乎是,当使用命令行参数启动时,它将处理参数,启动一个单独的进程(如果参数有效),然后终止原始进程.
这意味着您将需要一个代表新进程的 Process
实例,以便获取其主进程的句柄 window。
添加到您的原始代码:
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
?)。
我的主要目标是打开远程桌面并在远程会话结束时将其释放回来。 我正在尝试在 winform 应用程序中托管 Mstsc.exe,因此我将管理进程的关闭并将释放命令发送到远程 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 是真的,虽然 mstsc 是开放的。 如何获得 MSTSC.exe 的 MainWindowHandle?
谢谢
远程桌面客户端的实现方式似乎是,当使用命令行参数启动时,它将处理参数,启动一个单独的进程(如果参数有效),然后终止原始进程.
这意味着您将需要一个代表新进程的 Process
实例,以便获取其主进程的句柄 window。
添加到您的原始代码:
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
?)。