如何通过`installutil`安装长期运行的服务时将参数传递给`Configuration.Install.Installer`

时间:2013-05-27 08:06:13

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

我有一个应用程序,我想作为 Windows服务运行。按照this MSDN doc page中提供的说明(我需要托管 WCF 服务,所以程序也详细说明了这一部分),我可以这样做,如果我实现示例服务就可以了。我使用installutil.exe实用程序,可以将我的应用程序安装和卸载为Windows服务。

我的问题

但是我需要在本地计算机上安装相同应用程序的更多服务。所以我需要给他们不同的System.ServiceProcess.ServiceBase.ServiceName s!因此,请再次考虑安装代码:

[RunInstaller(true)]
public class ProjectInstaller : Installer {
    private ServiceProcessInstaller process;
    private ServiceInstaller service;

    public ProjectInstaller() {
        process = new ServiceProcessInstaller();
        process.Account = ServiceAccount.LocalSystem;
        service = new ServiceInstaller();
        service.ServiceName = /* NEED TO PUT HERE THE NAME!!! */;
        Installers.Add(process);
        Installers.Add(service);
    }
}

在调用installutil.exe时,我有办法传递服务名称吗? 如何解决这个问题?我也尝试使用App.Config文件并执行以下操作:

public ProjectInstaller() {
    process = new ServiceProcessInstaller();
    process.Account = ServiceAccount.LocalSystem;
    service = new ServiceInstaller();
    service.ServiceName = System.Configuration.ConfigurationManager.
        AppSettings["SrvName"];
    Installers.Add(process);
    Installers.Add(service);
}

但当然它不起作用,当应用程序运行时调用此文件!!!

2 个答案:

答案 0 :(得分:3)

您可以打开配置文件以执行程序集。如果您的安装程序代码放在主服务exe文件中 - 它将是您的app.config。否则,配置文件需要命名为[assemblyname] .dll.config。

process = new ServiceProcessInstaller();
process.Account = ServiceAccount.LocalSystem;
service = new ServiceInstaller();

var path = Assembly.GetExecutingAssembly().Location;
var config = ConfigurationManager.OpenExeConfiguration(path);
service.ServiceName = config.AppSettings.Settings["ServiceName"];
Installers.Add(process);
Installers.Add(service);

此外,本文还介绍了如何pass installutil parameters explicitly through command line

答案 1 :(得分:2)

面对这个问题,我首先使用方法here

但是我转而回到一个架构,在那里我有一个服务启动可变数量的进程(在我的例子中,我使用zookeeper来设置要运行的进程数和它们的命令行参数,但是如果它只是一个在许多情况下,app.config都很好。

我以这种方式找到的主要优点是我的启动服务可以监视正在运行的子进程,例如,如果它已经崩溃,则重新启动它。