[英]Windows service: Get username when user log on
my windows service should save the name of the user, which logon/logoff at the moment. 我的Windows服务应保存用户名,该用户名目前为登录/注销。 The following code works for me but didn't save the username: 以下代码对我有用,但没有保存用户名:
protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
try
{
string user = "";
foreach (ManagementObject currentObject in _wmiComputerSystem.GetInstances())
{
user += currentObject.Properties["UserName"].Value.ToString().Trim();
}
switch (changeDescription.Reason)
{
case SessionChangeReason.SessionLogon:
WriteLog(Constants.LogType.CONTINUE, "Logon - Program continues: " + user);
OnContinue();
break;
case SessionChangeReason.SessionLogoff:
WriteLog(Constants.LogType.PAUSE, "Logoff - Program is paused: " + user);
OnPause();
break;
}
base.OnSessionChange(changeDescription);
}
catch (Exception exp)
{
WriteLog(Constants.LogType.ERROR, "Error");
}
}
edit: The foreach loop gives me an error: 编辑: foreach循环给我一个错误:
Message: Access is denied. 消息:访问被拒绝。 (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) Type: System.UnauthorizedAccessException (来自HRESULT的异常:0x80070005(E_ACCESSDENIED))类型:System.UnauthorizedAccessException
But in my opinion, this code is not the solution, because it saves all users, which are logged onto the server. 但是我认为,此代码不是解决方案,因为它可以保存所有已登录到服务器的用户。
I ran into a similar problem while building a Windows Service. 在构建Windows服务时遇到了类似的问题。 Just like you, I had the Session ID and needed to get the corresponding username. 就像您一样,我具有会话ID,并且需要获取相应的用户名。 After several unsuccessful solution hereon SO, I ran into this particular answer and it inspired my solution: 经过几次失败的解决方案之后,我遇到了这个特殊的答案 ,这启发了我的解决方案:
Here's my code (all of them residing inside a class; in my case, the class inheriting ServiceBase
). 这是我的代码(所有代码都驻留在一个类中;对于我而言,该类是继承ServiceBase
的类)。
[DllImport("Wtsapi32.dll")]
private static extern bool WTSQuerySessionInformation(IntPtr hServer, int sessionId, WtsInfoClass wtsInfoClass, out IntPtr ppBuffer, out int pBytesReturned);
[DllImport("Wtsapi32.dll")]
private static extern void WTSFreeMemory(IntPtr pointer);
private enum WtsInfoClass
{
WTSUserName = 5,
WTSDomainName = 7,
}
private static string GetUsername(int sessionId, bool prependDomain = true)
{
IntPtr buffer;
int strLen;
string username = "SYSTEM";
if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WtsInfoClass.WTSUserName, out buffer, out strLen) && strLen > 1)
{
username = Marshal.PtrToStringAnsi(buffer);
WTSFreeMemory(buffer);
if (prependDomain)
{
if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WtsInfoClass.WTSDomainName, out buffer, out strLen) && strLen > 1)
{
username = Marshal.PtrToStringAnsi(buffer) + "\\" + username;
WTSFreeMemory(buffer);
}
}
}
return username;
}
With the above code in your class, you can simply get the username in the method you're overriding by calling 在您的课程中使用上面的代码,您只需调用以下方法即可获取您要覆盖的方法中的用户名
string username = GetUsername(changeDescription.SessionId);
You could try: 您可以尝试:
System.Security.Principal.WindowsIdentity.GetCurrent();
another option, see: Getting logged-on username from a service 另一个选项,请参阅: 从服务获取登录的用户名
Finally I got a solution. 终于我找到了解决方案。 In the windows service method, there is the session id provided. 在Windows服务方法中,提供了会话ID。 So with this session id we can execute a powershell command 'quser' and get the current user, who login/logoff on the server. 因此,使用此会话ID,我们可以执行powershell命令“ quser”并获取当前用户,该用户在服务器上登录/注销。 Seen here: How to get current windows username from windows service in multiuser environment using .NET 在这里看到: 如何使用.NET从多用户环境中的Windows服务获取当前Windows用户名
So this is the function, which we need to create: 这就是我们需要创建的函数:
private string GetUsername(int sessionID)
{
try
{
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript("Quser");
pipeline.Commands.Add("Out-String");
Collection<PSObject> results = pipeline.Invoke();
runspace.Close();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
foreach (string User in stringBuilder.ToString().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Skip(1))
{
string[] UserAttributes = User.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
if (UserAttributes.Length == 6)
{
if (int.Parse(UserAttributes[1].Trim()) == sessionID)
{
return UserAttributes[0].Replace(">", string.Empty).Trim();
}
}
else
{
if (int.Parse(UserAttributes[2].Trim()) == sessionID)
{
return UserAttributes[0].Replace(">", string.Empty).Trim();
}
}
}
}
catch (Exception exp)
{
// Error handling
}
return "Undefined";
}
And this is the windows service function: 这是Windows服务功能:
protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
try
{
switch (changeDescription.Reason)
{
case SessionChangeReason.SessionLogon:
string user = GetUsername(changeDescription.SessionId);
WriteLog("Logon - Program continue" + Environment.NewLine +
"User: " + user + Environment.NewLine + "Sessionid: " + changeDescription.SessionId);
//.....
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.