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

时间:2009-05-07 15:44:24

标签: c# .net windows-services windows-installer

我在C#中创建了一个Windows服务,将其安装在服务器上运行正常。

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

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

  

InstallUtil.exe / i   / servicename =“MyService Instance 2”   MyService.exe

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

任何建议都将不胜感激。

感谢您的时间。

3 个答案:

答案 0 :(得分:28)

我尝试使用

访问配置
ConfigurationManager.OpenExeConfiguration(string exePath)

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

相反,我决定在安装程序中使用System.Environment.GetCommandLineArgs(),如下所示:

string[] commandlineArgs = Environment.GetCommandLineArgs();

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

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

现在我可以使用

安装我的服务了
  

InstallUtil.exe / i   InstallableService.dll   /服务名= “myserviceinstance_2”   / servicedisplayname =“我的服务   实例2“

我写了一个更详尽的解释here

答案 1 :(得分:4)

你不能将它作为命令行arg传递,因为InstallUtil没有提供正确的钩子。

但是,您可以让服务安装程序从配置文件中读取ServiceName。如果您look at some code用于典型的ServiceInstaller,您将看到它只是在运行时设置了相应的DisplayName和ServiceName属性。这些可以很容易地从配置文件中读取,而不是硬编码。

答案 2 :(得分:2)

而不是使用Environment.GetCommandLineArgs();,类Installer有一个名为Context的属性,您可以从中访问传递给以良好StringDictionary结构化的InstallUtil的命令行参数。