C# 如何在安装时(或在编译时轻松地)配置 Windows 服务的名称?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/835422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:32:50  来源:igfitidea点击:

How do I configure the name of a Windows service upon installation (or easily at compile time)?

c#.netwindows-serviceswindows-installer

提问by Rune

I've created a Windows service in C#, installed it on a server and it is running fine.

我在 C# 中创建了一个 Windows 服务,将其安装在服务器上并且运行良好。

Now I want to install the same service again, but running from a different working directory, having a different config file etc. Thus, I would like to have two(or more) instances of the same service running simultaneously. Initially, this isn't possible since the installer will complain that there's already a service with the given name installed.

现在我想再次安装相同的服务,但从不同的工作目录运行,具有不同的配置文件等。因此,我希望同时运行同一服务的两个(或更多)实例。最初,这是不可能的,因为安装程序会抱怨已经安装了具有给定名称的服务。

I can overcome this by changing my code, setting the ServiceBase.ServiceNameproperty to a new value, then recompiling and running InstallUtil.exe again. However, I would much prefer if I could set the service name at install-time, i.e. ideally I would do something like

我可以通过更改我的代码,将ServiceBase.ServiceName属性设置为新值,然后重新编译并再次运行 InstallUtil.exe来克服这个问题。但是,如果我可以在安装时设置服务名称,我会更喜欢,即理想情况下我会做类似的事情

InstallUtil.exe /i /servicename="MyService Instance 2" MyService.exe

InstallUtil.exe /i /servicename="MyService Instance 2" MyService.exe

If this isn't achievable (I very much doubt it), I would like to be able to inject the service name when I build the service. I thought it might be possible to use some sort of build event, use a clever msbuild or nant trick or something along those lines, but I haven't got a clue.

如果这无法实现(我非常怀疑),我希望能够在构建服务时注入服务名称。我认为可能可以使用某种构建事件,使用聪明的 msbuild 或 nant 技巧或类似的东西,但我没有任何线索。

Any suggestions would be greatly appreciated.

任何建议将不胜感激。

Thank you for your time.

感谢您的时间。

采纳答案by Rune

I tried accessing a configuration using

我尝试使用访问配置

ConfigurationManager.OpenExeConfiguration(string exePath)

in the installer, but couldn't get it to work.

在安装程序中,但无法使其工作。

Instead I decided to use System.Environment.GetCommandLineArgs()in the installer like this:

相反,我决定System.Environment.GetCommandLineArgs()在安装程序中像这样使用:

string[] commandlineArgs = Environment.GetCommandLineArgs();

string servicename;
string servicedisplayname;
ParseServiceNameSwitches(
    commandlineArgs, 
    out servicename, 
    out servicedisplayname);

serviceInstaller.ServiceName = servicename;
serviceInstaller.DisplayName = servicedisplayname;

Now I can install my services using

现在我可以使用安装我的服务

InstallUtil.exe /i InstallableService.dll /servicename="myserviceinstance_2" /servicedisplayname="My Service Instance 2"

InstallUtil.exe /i InstallableService.dll /servicename="myserviceinstance_2" /servicedisplayname="我的服务实例 2"

I wrote up a more elaborate explanation here.

在这里写了一个更详细的解释。

回答by Reed Copsey

You can't pass this in as a command line arg, since InstallUtil doesn't provide the right hooks for that.

您不能将其作为命令行参数传递,因为 InstallUtil 没有为此提供正确的挂钩。

However, you can make your service installer read the ServiceName from a config file. If you look at some codefor a typical ServiceInstaller, you'll see it's just a matter of having the appropriate DisplayName and ServiceName properties setup at runtime. These could easily be read from a configuration file instead of being hard-coded.

但是,您可以让服务安装程序从配置文件中读取 ServiceName。如果您查看典型 ServiceInstaller 的一些代码,您会发现这只是在运行时设置适当的 DisplayName 和 ServiceName 属性的问题。这些可以很容易地从配置文件中读取,而不是硬编码。

回答by Arthur Rizzo

Instead of using Environment.GetCommandLineArgs();the class Installerhas a property called Contextfrom which you can access command line arguments passed to InstallUtil structured in a nice StringDictionary.

而不是使用具有调用的属性Environment.GetCommandLineArgs();的类,您可以从中访问传递给 InstallUtil 的命令行参数,该参数以一个 nice .InstallerContextStringDictionary