Windows服务 - 在“可执行文件路径”中提供参数

问题描述:

我无法弄清楚在启动时如何将(常量)参数传递到我的Windows服务中。我使用的是标准的.NET类,如ServiceBase来实现(和ServiceProcessInstaller和ServiceInstaller来安装)我的服务。Windows服务 - 在“可执行文件路径”中提供参数

在Windows服务属性对话框(一旦安装)的常规选项卡中,有一个“路径可执行文件”中,我可以看到,一些标准的Windows服务的指定命令行参数。 System.ServiceProcess.ServiceBase.OnStart需要string[] args,我推测这些参数可以从.NET代码中访问。

有没有对ServiceProcessInstaller或的ServiceInstaller一些属性,我可以设置为允许我启动参数传递给我自己的服务,或没有人知道它是如何应该做?

当用户使用命令行中的sc.exe start命令手动启动服务时,会提供OnStart()参数。或者可以用ServiceControl.Start(string [])方法重载以编程方式完成。这很少用,你可能希望你的服务自动启动而不需要用户登录。

是的,ImagePath的注册表项不支持传递参数给.exe文件,你会通过主(字符串[])入口点得到它们。不幸的是,ServiceInstaller不支持这一点。更好的方法是使用注册表。在您的安装程序中,创建HKLM \ System \ CurrentControlSet \ services \ yourServiceName \ Parameters键并向其中写入值。并将它们读回到您的服务的Main或OnStart方法中。

+0

谢谢。安装项目中的注册表视图对我来说有点笨拙。我尝试使用派生自ServiceInstaller的自定义类,其中我重写了Install方法,但基类在整个路径中放置了引号,并使我试图实现的内容失效。我想,如果我真的需要这样做,这将需要一些想法......但我可能会找到另一种将值传递给服务的方式。 – Jono 2010-06-07 15:54:28

嗯,这是大约10个月后,你发布和我有同样的问题。一旦我阅读了这个主题和其他主题,我就决定看看.NET Framework在幕后做了什么,并且证实没有文档记录的方式来做到这一点。有;然而,这是一个非常简单的无证方式。在父安装程序类中,覆盖安装方法或实现BeforeInstall事件。这并不重要,你可以使用以下方法之一:

public override void Install(System.Collections.IDictionary stateSaver) 
{ 
    base.Install(stateSaver); 

    base.Context.Parameters["assemblyPath"] = string.Format("\"{0}\" /service", base.Context.Parameters["assemblyPath"]); 
} 

或:

private void Installer_BeforeInstall(object sender, InstallEventArgs e) 
{ 
    base.Context.Parameters["assemblyPath"] = string.Format("\"{0}\" /service", base.Context.Parameters["assemblyPath"]); 
} 

的“assemblyPath”参数将与完整路径可执行文件从AssemblyInstaller内进行初始化类。此参数的值写入注册表中的ImagePath值。如果不存在引号,则引号将放在该值的周围,因此请确保将它们放在需要它们的位置(即至少在初始值附近)。在上面的行中,我将引号放在执行文件路径的周围,并将“/ service”作为参数添加到末尾。

这将适用于所有使用该父安装程序类的服务。如果您有不想添加参数或需要不同参数的服务,则可以嵌套安装程序类并将代码放在那些代码上,而不是根安装程序类。这没有记录在任何地方,将来可能会崩溃,并且可能无法在.NET Framework的非Microsoft版本上运行,但它目前确实有效。

我希望这会有所帮助。