代码之家  ›  专栏  ›  技术社区  ›  LorneCash

从控制台或Windows服务以编程方式创建Windows会话

  •  0
  • LorneCash  · 技术社区  · 7 年前

    另一个要求是,我需要它在运行程序/服务的本地系统上以及远程系统上工作。

    如果有一种方法可以使用pInvoke/Win32 API来实现这一点,我也愿意这样做。

    我在研究中发现了这些类似的问题/答案:

    Programmatically create and launch and RDP session (without gui)

    这里的答案说这是可能的,但是给出了一个链接,但是链接中的示例代码不起作用

    Create a Windows Session from a service via the Win32 API

    这个问题没有解决办法

    Create Windows session programmatically

    没有解决方案,但OP在评论中提到 http://freerdp.com 为他工作。

    1 回复  |  直到 7 年前
        1
  •  6
  •   LorneCash    7 年前

    我已经创建了一个简单的实用程序,我相信它满足问题中的所有要求。您需要添加对Microsoft终端服务活动客户端1.0类型库(ActiveX)的COM引用。

    using System;
    using System.Diagnostics;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using AxMSTSCLib;
    
    namespace Utility.RemoteDesktop
    {
        public class Client
        {
            private int LogonErrorCode { get; set; }
    
            public void CreateRdpConnection(string server, string user, string domain, string password)
            {
                void ProcessTaskThread()
                {
                    var form = new Form();
                    form.Load += (sender, args) =>
                    {
                        var rdpConnection = new AxMSTSCLib.AxMsRdpClient9NotSafeForScripting();
                        form.Controls.Add(rdpConnection);
                        rdpConnection.Server = server;
                        rdpConnection.Domain = domain;
                        rdpConnection.UserName = user;
                        rdpConnection.AdvancedSettings9.ClearTextPassword = password;
                        rdpConnection.AdvancedSettings9.EnableCredSspSupport = true;
                        if (true)
                        {
                            rdpConnection.OnDisconnected += RdpConnectionOnOnDisconnected;
                            rdpConnection.OnLoginComplete += RdpConnectionOnOnLoginComplete;
                            rdpConnection.OnLogonError += RdpConnectionOnOnLogonError;
                        }
                        rdpConnection.Connect();
                        rdpConnection.Enabled = false;
                        rdpConnection.Dock = DockStyle.Fill;
                        Application.Run(form);
                    };
                    form.Show();
                }
    
                var rdpClientThread = new Thread(ProcessTaskThread) { IsBackground = true };
                rdpClientThread.SetApartmentState(ApartmentState.STA);
                rdpClientThread.Start();
                while (rdpClientThread.IsAlive)
                {
                    Task.Delay(500).GetAwaiter().GetResult();
                }
            }
    
            private void RdpConnectionOnOnLogonError(object sender, IMsTscAxEvents_OnLogonErrorEvent e)
            {
                LogonErrorCode = e.lError;
            }
            private void RdpConnectionOnOnLoginComplete(object sender, EventArgs e)
            {
                if (LogonErrorCode == -2)
                {
                    Debug.WriteLine($"    ## New Session Detected ##");
                    Task.Delay(10000).GetAwaiter().GetResult();
                }
                var rdpSession = (AxMsRdpClient9NotSafeForScripting)sender;
                rdpSession.Disconnect();
            }
            private void RdpConnectionOnOnDisconnected(object sender, IMsTscAxEvents_OnDisconnectedEvent e)
            {
                Environment.Exit(0);
            }
        }
    }
    

    在旁注中,我发现了一个问题,即可能有一种方法可以使用ActiveX控件(用于RDP),而根本不使用windows窗体。我看到了他们给出的示例,我不确定在这种情况下使用他们的代码。

    ActiveX control without a form

    如果有人知道如何在不在表单上托管ActiveX控件的情况下执行此操作,请发布一个示例。

    推荐文章