C# 从控制台或Windows服务以编程方式创建Windows会话
如何以编程方式登录到windows以创建windows登录会话? 我需要一种从WinForms应用程序、控制台应用程序和(最重要的)Windows服务运行的方式 另一个要求是,我需要它在运行程序/服务的本地系统上以及远程系统上工作 如果有一种方法可以使用pInvoke/Win32 API来实现这一点,我也愿意这样做 我在研究中发现了这些类似的问题/答案: 这里的答案说这是可能的,但是给出了一个链接,但是链接中的示例代码不起作用 这个问题没有解决办法C# 从控制台或Windows服务以编程方式创建Windows会话,c#,winforms,windows-services,activex,rdp,C#,Winforms,Windows Services,Activex,Rdp,如何以编程方式登录到windows以创建windows登录会话? 我需要一种从WinForms应用程序、控制台应用程序和(最重要的)Windows服务运行的方式 另一个要求是,我需要它在运行程序/服务的本地系统上以及远程系统上工作 如果有一种方法可以使用pInvoke/Win32 API来实现这一点,我也愿意这样做 我在研究中发现了这些类似的问题/答案: 这里的答案说这是可能的,但是给出了一个链接,但是链接中的示例代码不起作用 这个问题没有解决办法 没有解决方案,但在一篇对他有效的评论中提
没有解决方案,但在一篇对他有效的评论中提到了OP。我创建了一个简单的实用程序,我相信它满足问题中的所有要求。您需要添加对Microsoft终端服务活动客户端1.0类型库(ActiveX)的COM引用 我认为在本地机器上创建会话可能不起作用,但我在2012R2中测试了作为服务运行,它实际上可以。可以从WinForms应用程序或控制台应用程序调用相同的方法。当从WinForms或Console应用程序启动时,a表单会显示几秒钟,因此我确保将控件设置为enabled=false,以便无法与之交互
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控件托管在表单上的情况下执行此操作,请发布一个示例。非常好!您的“OnLogonError”事件是否针对所有操作系统版本触发?不确定我只针对Windows服务器(而不是7或10)进行了测试。如果你做了测试,请发表评论让每个人都知道。这是否回答了你的问题?很明显,这一直是你链接的第一个问题的一个骗局,因为你在发布问题的同一时间发布了这个问题的自我答案,Q&a风格,并且你也向所述骗局目标发布了相同的答案。