C#获取与当前进程对应的 Windows 服务的实际名称

前言

有时,可能需要在运行时获取当前进程所属的 Windows 服务(有关创建 Windows 服务的说明,请参阅 https://learn.microsoft.com/zh-cn/dotnet/core/extensions/windows-service)。例如,可能需要在 Windows 服务中使用不同的日志记录器。

本文将讨论如何获取当前进程所属的 Windows 服务。.

IHostLifetime

IHostLifetime 接口定义了用于控制主机启动和关闭的方法,它有两个实现:

  • ConsoleLifetime:控制台应用程序的主机生存期实现。

  • WindowsServiceLifetime:Windows 服务的主机生存期实现。

WindowsServiceLifetime 类会在其 StartAsync 方法中设置 ServiceName 属性的值,该方法是对应于当前进程的 Windows 服务的名称:

public WindowsServiceLifetime(IHostEnvironment Environment, IHostApplicationLifetime applicationLifetime, ILoggerFactory loggerFactory, IOptions<HostOptions> optionsAccessor, IOptions<WindowsServiceLifetimeOptions> windowsServiceOptionsAccessor) 
{ 
    ... 
    ServiceName = windowsServiceOptionsAccessor.Value.ServiceName;  
    ... 
} 

因此,在 Windows 服务中,可以通过 IHostLifetime 接口获取当前进程对应的 Windows 服务的名称:

var host = builder.Build();

var lifetime = host.Services.GetService(typeof(IHostLifetime)) as IHostLifetime;
var serviceName = lifetime.GetType().GetProperty("ServiceName").GetValue(lifetime);
logger.LogInformation($"The service name is {serviceName}");

await host.RunAsync();

问题

但是,上述方法有一个问题,即获取的 ServiceName 属性的值实际上是 AddWindowsService 代码中设置的名称,而不是 Windows 服务的真实名称。

builder.Services.AddWindowsService(options =>
{
    options.ServiceName = ".NET Joke Service";
});

C#获取与当前进程对应的 Windows 服务的实际名称

因此,要获取 Windows 服务的真实名称,需要另辟蹊径。

解决方案

Windows 服务启动后,它对应于一个进程。因此,可以通过其 Id 获取与当前进程对应的 Windows 服务的名称。

C#获取与当前进程对应的 Windows 服务的实际名称

可以使用 WMI 来获取与当前进程对应的 Windows 服务的名称:

await host.StartAsync();

var processId = Process.GetCurrentProcess().Id;
var query = $"SELECT * FROM Win32_Service WHERE ProcessId = {processId}";
var searcher = new ManagementObjectSearcher(query);
var services = searcher.Get();
var serviceName = services.Cast<ManagementObject>().Select(s => s["Name"]).FirstOrDefault();
logger.LogInformation($"The service name is {serviceName}");

await host.WaitForShutdownAsync();

注意,必须在调用 host.StartAsync 之后才能获取与当前进程对应的 Windows 服务。

结论

本文讨论了如何获取与当前进程对应的 Windows 服务的名称。希望这篇文章对你有所帮助。