我有一个可以通过调用“CreateProcessAsUser”函数在用户窗口会话中创建可执行文件的Windows服务。只要已经存在Windows会话,这样就可以正常工作。如果没有一个我已经希望能够以编程方式创建一个。这有可能吗?似乎找不到这样做的功能。
答案 0 :(得分:3)
您无法从服务创建新会话。会话由操作系统管理。当用户以交互方式登录时,会创建新的。
答案 1 :(得分:3)
这不是我提出的问题的解决方案,但如果你明白我的意思,那就是通过提出这个问题帮助实现我想要实现的目标的解决方案。
您可以将Windows配置为在引导时自动登录,而不是拥有创建服务器会话的Windows服务。这仍然意味着有人可以加入注销,但可以解决会话消失的主要原因:服务器正在重新启动。使用以下步骤激活自动登录:
这篇文章的说明如下: http://channel9.msdn.com/Blogs/coolstuff/Tip-Auto-Login-Your-Windows-7-User-Account
答案 2 :(得分:0)
LogonUser功能怎么样?
答案 3 :(得分:-1)
@Robert,我知道这是一个古老的问题,您已经找到了适合您的问题,但就我而言,我一直在寻找与您原来的问题类似的问题,我终于弄清楚了,所以我想分享。我的解决方案仅使用.NET和COM引用,而不使用标题中提到的Win32 API,但我想这并不是您真正需要的。
我已经编写了一个简单的实用程序来使用远程桌面ActiveX控件(COM参考)。如果将此代码粘贴到类库中,则可以通过简单地传入服务器,用户名,域和密码来调用它,并且一切都为您完成,而无需任何其他交互。方法完成后,您可以调用“ CreateProcessAsUser”代码。我以某种方式编写了该实用程序,以便您每次都可以调用它,但是启动RDP会话需要花费几秒钟的时间,因此出于性能方面的考虑,我建议您编写另一种枚举会话并查看用户是否已登录并仅在确定您的用户未登录时才调用此实用程序(这是我在实际项目中所做的事情)。如果您认为需要在评论中提供帮助,我将分享我的操作方式,但这并不是该问题的一部分,因此,我暂时将其遗漏。
这是一个指向我的问题的链接,该链接比该问题有更多的要求/细节。
Create Windows Session programmatically from Console or Windows Service
这是我的RDP实用程序。将此代码放入类库后,您可以从控制台应用程序,winForms应用程序或在同一台计算机或远程计算机上运行的Windows服务中调用它。
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);
}
}
}