NVR*_*RAM 34 c# service windows-services
我看了,找不到一个简单的问题:
Windows服务如何确定启动它的ServiceName?
我知道安装可以破解注册表并添加一个命令行参数,但逻辑上看起来它应该是不必要的,因此这个问题.
我希望比注册表黑客更干净地运行单个二进制文件的多个副本.
编辑:
这是用C#编写的.我的应用程序Main()入口点执行不同的操作,具体取决于命令行参数:
目前,安装步骤将服务名称和线程计数附加到注册表中的ImagePath,以便应用程序可以确定它的ServiceName.
NVR*_*RAM 29
来自:https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?反馈ID = 387024
这是一个WMI解决方案.覆盖ServiceBase.ServiceMainCallback()也可能有效,但这似乎对我有用......
protected String GetServiceName()
{
// Calling System.ServiceProcess.ServiceBase::ServiceNamea allways returns
// an empty string,
// see https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=387024
// So we have to do some more work to find out our service name, this only works if
// the process contains a single service, if there are more than one services hosted
// in the process you will have to do something else
int processId = System.Diagnostics.Process.GetCurrentProcess().Id;
String query = "SELECT * FROM Win32_Service where ProcessId = " + processId;
System.Management.ManagementObjectSearcher searcher =
new System.Management.ManagementObjectSearcher(query);
foreach (System.Management.ManagementObject queryObj in searcher.Get()) {
return queryObj["Name"].ToString();
}
throw new Exception("Can not get the ServiceName");
}
Run Code Online (Sandbox Code Playgroud)
ServiceBase.ServiceName属性提供编译时的服务名称.如果在安装服务时指定其他名称,则ServiceName属性将不会提供正确的名称.所以,我必须使用下面的代码来获取我的服务的服务名称.
它是NVRAM方法的另一种选择(不使用LINQ):
/**
* Returns the service name of currently running windows service.
*/
static String getServiceName()
{
ServiceController[] scServices;
scServices = ServiceController.GetServices();
// Display the list of services currently running on this computer.
int my_pid = System.Diagnostics.Process.GetCurrentProcess().Id;
foreach (ServiceController scTemp in scServices)
{
// Write the service name and the display name
// for each running service.
// Query WMI for additional information about this service.
// Display the start name (LocalSytem, etc) and the service
// description.
ManagementObject wmiService;
wmiService = new ManagementObject("Win32_Service.Name='" + scTemp.ServiceName + "'");
wmiService.Get();
int id = Convert.ToInt32(wmiService["ProcessId"]);
if (id == my_pid)
{
return scTemp.ServiceName;
#if IS_CONSOLE
Console.WriteLine();
Console.WriteLine(" Service : {0}", scTemp.ServiceName);
Console.WriteLine(" Display name: {0}", scTemp.DisplayName);
Console.WriteLine(" Start name: {0}", wmiService["StartName"]);
Console.WriteLine(" Description: {0}", wmiService["Description"]);
Console.WriteLine(" Found.......");
#endif
}
}
return "NotFound";
}
Run Code Online (Sandbox Code Playgroud)
我没有首先调用ServiceBase.Run()而错误地尝试在main()中获取Windows服务的名称作为第一行.我们必须在获取其名称之前使用ServiceBase.Run()将可执行文件注册为服务.
参考:http://msdn.microsoft.com/en-us/library/hde9d63a.aspx#Y320
带 Linq 的简短版本
int processId = System.Diagnostics.Process.GetCurrentProcess().Id;
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Service where ProcessId = " + processId);
ManagementObjectCollection collection = searcher.Get();
var serviceName = (string)collection.Cast<ManagementBaseObject>().First()["Name"];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
29636 次 |
| 最近记录: |