【发布时间】:2010-06-29 13:50:53
【问题描述】:
给定一个服务名称,我想检索它运行时使用的用户名(即服务属性窗口的“登录”选项卡中显示的用户名)。
ServiceController 类中似乎没有任何东西可以检索此基本信息。 System.ServiceProcess 中的其他内容似乎也没有公开此信息。
是否有一个托管的解决方案,或者我将不得不下降到较低级别的东西?
【问题讨论】:
标签: c# authentication windows-services
给定一个服务名称,我想检索它运行时使用的用户名(即服务属性窗口的“登录”选项卡中显示的用户名)。
ServiceController 类中似乎没有任何东西可以检索此基本信息。 System.ServiceProcess 中的其他内容似乎也没有公开此信息。
是否有一个托管的解决方案,或者我将不得不下降到较低级别的东西?
【问题讨论】:
标签: c# authentication windows-services
使用 WMI,通过 System.Management 您可以尝试以下代码:
using System;
namespace WindowsServiceTest
{
class Program
{
static void Main(string[] args)
{
System.Management.SelectQuery sQuery = new System.Management.SelectQuery(string.Format("select name, startname from Win32_Service")); // where name = '{0}'", "MCShield.exe"));
using (System.Management.ManagementObjectSearcher mgmtSearcher = new System.Management.ManagementObjectSearcher(sQuery))
{
foreach (System.Management.ManagementObject service in mgmtSearcher.Get())
{
string servicelogondetails =
string.Format("Name: {0} , Logon : {1} ", service["Name"].ToString(), service["startname"]).ToString();
Console.WriteLine(servicelogondetails);
}
}
Console.ReadLine();
}
}
}
然后您可以稍后将注释代码替换为您的服务名称,它应该只返回正在运行的服务进程的实例。
【讨论】:
WMI 是您的朋友。查看Win32_Service,特别是StartName 属性。您可以通过 System.Management.ManagementClass 从 C# 访问 WMI。
如果你以前没有使用过 WMI,this 的文章似乎是一个不错的教程。
【讨论】:
试试这个:
System.Security.Principal.WindowsIdentity.GetCurrent();
但最明显的是您将获得 LOCAL SYSTEM 或 NETWORK。您无法显示此用户的原因 - 该服务可以管理多个用户(由桌面共享,附加到当前 Windows 会话,使用共享资源......) 系统启动服务,但任何用户都可以使用。
【讨论】:
WindowsIdentity,而不是指定服务的。
GetCurrent() 的建议将不起作用,因为根据 MSDN,它“返回代表当前 Windows 用户的 WindowsIdentity 对象”。在这种情况下,它将是运行 CLIENT 应用程序的当前 Windows 用户的 WindowsIdentity,而不是 SERVICE 的 WindowsIdentity。
这个解决方案对我来说很好:
ManagementObject wmiService = new ManagementObject("Win32_Service.Name='" + this.ServiceName + "'");
wmiService.Get();
string user = wmiService["startname"].ToString();
【讨论】:
您可以使用 Windows 注册表找到它,读取以下字符串值,将 [SERVICE_NAME] 替换为 Windows 服务的名称:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\[SERVICE_NAME]\ObjectName
【讨论】:
public String getUsername() {
string username = null;
try {
ManagementScope ms = new ManagementScope("\\\\.\\root\\cimv2");
ms.Connect();
ObjectQuery query = new ObjectQuery
("SELECT * FROM Win32_ComputerSystem");
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(ms, query);
foreach (ManagementObject mo in searcher.Get()) {
username = mo["UserName"].ToString();
}
string[] usernameParts = username.Split('\\');
username = usernameParts[usernameParts.Length - 1];
} catch (Exception) {
username = "SYSTEM";
}
return username;
}
【讨论】: