C# 使用远程桌面连接本机

前言

最近由于项目需求,需要实现 远程桌面连接当前本机(自己连接自己)
当程序完成操作之后,注销远程桌面(确保每次打开的,都是新的桌面)

注意事项: 此功能只能在专业版系统上使用,我测试过家庭版、教育版等,均不能连接上远程桌面

白屏问题

最近看到不少朋友都反馈有白屏问题,请检查:

1 当前操作系统是否为Windows专业版,此功能只能在专业版系统上使用。

2 调用WTSEnableChildSessions时是否返回True,如果返回False,用管理员权限启动程序即可解决。


引用DLL

需要引用AxInterop.MSTSCLib.dll和MSTSCLib.dll

Dll下载地址
提取码 egqq

代码实现

WPF项目,使用 WindowsFormsHost来展示远程桌面画面,需要引用WindowsFormsIntegration
在这里插入图片描述

在这里插入图片描述

  • 引用命名空间
using AxMSTSCLib;
using MSTSCLib;
  • 初始化
        /// /// 全局RDP对象/// private AxMsRdpClient9NotSafeForScripting rdp;public PictureInPictureForm(){InitializeComponent();//实例化对象rdp = new AxMsRdpClient9NotSafeForScripting();//远程桌面的内容显示在窗体中formhost.Child = rdp;}
  • 连接方法
        /// /// 连接方法/// public void Connect(){//连接本机,不会把自己挤掉线rdp.Server = "localhost";          var settings = (rdp.GetOcx() as IMsRdpExtendedSettings);object otrue = true;//设置连接自己,必须要加这一行,加了这一行后,会自动定位到LocalHostsettings.set_Property("ConnectToChildSession", ref otrue);//设置账号密码,我这里因为不知道用户的账号密码,暂时屏蔽掉//rdp.UserName = "";//rdp.AdvancedSettings2.ClearTextPassword=""//启用CredSSupSupport//一定要把EnableCredSspSupport属性置为ture 否则连接上去就是一片空白            rdp.AdvancedSettings7.EnableCredSspSupport = true;//自动尺寸rdp.AdvancedSettings7.SmartSizing = true;//显示连接栏rdp.AdvancedSettings7.DisplayConnectionBar = false;//重新定向rdp.AdvancedSettings7.RedirectSmartCards = true;            //远程桌面登录完成事件rdp.OnLoginComplete += (_, __) => { //如有需要,编写代码        };//远程桌面警告事件rdp.OnWarning += (_, e) => { //如有需要,编写代码        };//正在连接远程桌面事件rdp.OnConnecting += (_, e) => {    //如有需要,编写代码        };//连接成功后触发事件rdp.OnConnected += (_, e) =>{//如有需要,编写代码        };//断开连接回调事件rdp.OnDisconnected += OnDisconnected;//登录远程桌面事件rdp.OnLogonError += delegate (object _, IMsTscAxEvents_OnLogonErrorEvent e){if (e.lError != -2){    //如有需要               this.Close();}                                              };//远程桌面发生致命错误事件rdp.OnFatalError += delegate (object _, IMsTscAxEvents_OnFatalErrorEvent e){//如有需要this.Close();};                    //连接rdp.Connect();}
  • 断开连接
        /// /// 窗体关闭的时候,断开连接/// /// /// private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e){if (rdp == null){return;}//减去事件rdp.OnDisconnected -= OnDisconnected;//查看连接数,断开连接if (rdp.Connected != 0){rdp.Disconnect();}}           }
  • OnDisconnected事件
        /// /// 断开连接/// /// /// private void OnDisconnected(object sender, IMsTscAxEvents_OnDisconnectedEvent e){this.Close();}
  • 效果

在这里插入图片描述

  • 注销远程桌面

    由于连接远程桌面的类库并没有提供此功能,先自己实现,思路是开启远程桌面之前,设置一个自己开发的程序为开机启动,并且不可见,程序执行完相应的功能之后,取消设置开机启动,注销掉远程桌面

 //注销Process.Start("shutdown.exe", "-l");
           //设置开机启动项 ,Path开机启动程序的地址   using (var key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true)){key.SetValue("Program", Path);}//删除开机启动using (var key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true)){key.DeleteValue("Program", false);}

2021/3/18

今天测试的时候发现一个问题,同事的机器上连接远程桌面的时候白屏后闪退,我的机器正常,为了解决这个问题,翻阅了一下微软官方文档

https://docs.microsoft.com/zh-cn/windows/win32/termserv/child-sessions
在这里插入图片描述
微软的官方文档上写让我调用WTSEnableChildSessions函数启用子会话功能,还可以通过使用WTSIsChildSessionsEnabled函数来判断是否已启用子会话

解决方法:

        /// /// 注销使用/// public unsafe static readonly IntPtr WTS_CURRENT_SERVER_HANDLE = (IntPtr)(void*)null;/// /// 打开子会话功能/// /// /// [DllImport("Wtsapi32.dll")]private static extern bool WTSEnableChildSessions(bool enable);/// /// 判断用户是否打开了子会话功能/// /// /// [DllImport("Wtsapi32.dll")]private static extern bool WTSIsChildSessionsEnabled(out bool isEnabled);/// /// 获取子会话的SessionID/// /// /// [DllImport("Wtsapi32.dll")]private static extern bool WTSGetChildSessionId(out uint SessionId);/// /// 注销子会话/// /// /// [DllImport("Wtsapi32.dll", SetLastError = true)]private static extern bool WTSLogoffSession(IntPtr hServer, uint SessionId, bool bWait);

调用WTSEnableChildSessions即可

         /// /// 连接方法/// public void Connect(){//打开子会话功能if (!WTSEnableChildSessions(true)){throw new InvalidOperationException("启用画中画功能失败");}//连接本机,不会把自己挤掉线rdp.Server = "localhost";          var settings = (rdp.GetOcx() as IMsRdpExtendedSettings);object otrue = true;//设置连接自己,必须要加这一行,加了这一行后,会自动定位到LocalHostsettings.set_Property("ConnectToChildSession", ref otrue);//设置账号密码,我这里因为不知道用户的账号密码,暂时屏蔽掉//rdp.UserName = "";//rdp.AdvancedSettings2.ClearTextPassword=""//启用CredSSupSupport//一定要把EnableCredSspSupport属性置为ture 否则连接上去就是一片空白            rdp.AdvancedSettings7.EnableCredSspSupport = true;//自动尺寸rdp.AdvancedSettings7.SmartSizing = true;//显示连接栏rdp.AdvancedSettings7.DisplayConnectionBar = false;//重新定向rdp.AdvancedSettings7.RedirectSmartCards = true;            //远程桌面登录完成事件rdp.OnLoginComplete += (_, __) => { //如有需要,编写代码        };//远程桌面警告事件rdp.OnWarning += (_, e) => { //如有需要,编写代码        };//正在连接远程桌面事件rdp.OnConnecting += (_, e) => {    //如有需要,编写代码        };//连接成功后触发事件rdp.OnConnected += (_, e) =>{//如有需要,编写代码        };//断开连接回调事件rdp.OnDisconnected += OnDisconnected;//登录远程桌面事件rdp.OnLogonError += delegate (object _, IMsTscAxEvents_OnLogonErrorEvent e){if (e.lError != -2){    //如有需要               this.Close();}                                              };//远程桌面发生致命错误事件rdp.OnFatalError += delegate (object _, IMsTscAxEvents_OnFatalErrorEvent e){//如有需要this.Close();};                    //连接rdp.Connect();}

另外,发现了注销远程桌面的函数,原来并不是没有方法,只是我没有仔细查阅官方文档

        private void Window_Closed(object sender, EventArgs e){if (WTSGetChildSessionId(out var SessionId) && !WTSLogoffSession(WTS_CURRENT_SERVER_HANDLE, SessionId, bWait: true)){Trace.TraceError($"注销子会话 {SessionId},失败,错误信息: {Marshal.GetLastWin32Error()}");}}

然后打包在同事的电脑和虚拟机上测试,问题解决。

2022/1/19

今天发现了一个新的问题,专业版电脑上调用WTSEnableChildSessions失败,返回了False,解决此问题需要用管理员权限启用程序,再次打开子会话界面即可解决。

另外调用WTSEnableChildSessions之前应该判断功能是否已经开启,代码如下。

 /// /// 判断是否已经打开了画中画功能/// /// public static bool IsChildSessionEnabled(){try{WTSIsChildSessionsEnabled(out var isEnabled);return isEnabled;}catch (Exception innerException){throw new InvalidOperationException(innerException.Message);}}

应该先调用WTSIsChildSessionsEnabled,如果没有开启子会话功能,再去调用WTSEnableChildSessions。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部