使用c查找与windows服务相关联的实际可执行文件和路径

本文关键字:可执行文件 路径 关联 查找 windows 服务 使用 | 更新日期: 2023-09-27 18:28:54

我正在为我公司的一款产品编写安装程序。该产品可以安装多次,每次安装都代表一个单独的windows服务。当用户升级或重新安装程序时,我想查找正在运行的服务,找到属于该产品的服务,然后找到该服务的可执行文件及其路径。然后使用该信息查找用户希望升级/更换/安装的服务。在下面的代码示例中,我看到了服务名称、描述等,但没有看到实际的文件名或路径。有人能告诉我我缺了什么吗?提前谢谢!

我的代码如下:

        ServiceController[] scServices;
        scServices = ServiceController.GetServices();
        foreach (ServiceController scTemp in scServices)
        {
            if (scTemp.ServiceName == "ExampleServiceName")
            {
                Console.WriteLine();
                Console.WriteLine("  Service :        {0}", scTemp.ServiceName);
                Console.WriteLine("    Display name:    {0}", scTemp.DisplayName);
                ManagementObject wmiService;
                wmiService = new ManagementObject("Win32_Service.Name='" + scTemp.ServiceName + "'");
                wmiService.Get();
                Console.WriteLine("    Start name:      {0}", wmiService["StartName"]);
                Console.WriteLine("    Description:     {0}", wmiService["Description"]);
            }
        }

使用c查找与windows服务相关联的实际可执行文件和路径

我可能错了,但ServiceController类没有直接提供这些信息。

因此,正如吉恩所建议的那样,你必须使用注册表或WMI。

有关如何使用注册表的示例,请参阅http://www.codeproject.com/Articles/26533/A-ServiceController-Class-that-Contains-the-Path-t

如果你决定使用WMI(我更喜欢),

ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Service");
ManagementObjectCollection collection = searcher.Get();
foreach (ManagementObject obj in collection)
{    
    string name = obj["Name"] as string;
    string pathName = obj["PathName"] as string;
    ...
}

您可以决定将所需的属性封装在类中。

自从@sidprasher应答后,接口发生了变化,请尝试:

var collection = searcher.Get().Cast<ManagementBaseObject>()
        .Where(mbo => mbo.GetPropertyValue("StartMode")!=null)
        .Select(mbo => Tuple.Create((string)mbo.GetPropertyValue("Name"), (string)mbo.GetPropertyValue("PathName")));