我正在为我公司的一个产品制作安装程序。该产品可以多次安装,每个安装代表一个单独的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"]);
}
}
答案 0 :(得分:11)
我可能错了,但ServiceController
类没有直接提供这些信息。
正如Gene所建议的那样 - 您将不得不使用注册表或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;
...
}
您可以决定在课程中包装所需的属性。
答案 1 :(得分:1)
自@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")));