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

问题描述 投票:0回答:1

我的主要目标是打开远程桌面,并在远程会话结束时将其释放。我正在尝试将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?

谢谢

c# windows winforms remote-desktop rdp
1个回答
0
投票

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

这意味着您将需要一个代表新进程的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?)。

© www.soinside.com 2019 - 2024. All rights reserved.