使用InstallUtil安装带有启动参数的Windows服务

14

我正在使用InstallUtil安装我的服务,但我无法弄清楚如何指定它的启动参数!

这是我的Installer子类:

[RunInstaller(true)]
public class ServerHostInstaller : Installer
{
  private ServiceInstaller m_serviceInstaller;
  private ServiceProcessInstaller m_serviceProcessInstaller;
  private static string s_usage = "Usage:\ninstallutil /i /username=<user_name> /password=<user_password> NCStub.Server.Host.exe";

  public ServerHostInstaller()
  {
    m_serviceInstaller = new ServiceInstaller();
    m_serviceInstaller.ServiceName = Program.ServiceName;
    m_serviceInstaller.DisplayName = Program.ServiceName;
    m_serviceInstaller.StartType = ServiceStartMode.Automatic;

    m_serviceProcessInstaller = new ServiceProcessInstaller();
    m_serviceProcessInstaller.Account = ServiceAccount.User;

    Installers.Add(m_serviceInstaller);
    Installers.Add(m_serviceProcessInstaller);
  }

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

    string userName = this.Context.Parameters["username"];
    if (userName == null)
    {
      Console.WriteLine(s_usage);
      throw new InstallException("Missing parameter 'username'");
    }

    string userPass = this.Context.Parameters["password"];
    if (userPass == null)
    {
      Console.WriteLine(s_usage);
      throw new InstallException("Missing parameter 'password'");
    }

    m_serviceProcessInstaller.Username = userName;
    m_serviceProcessInstaller.Password = userPass;
  }
}

有人能指示我如何指定服务启动参数吗?

2个回答

15

找到了。

我已经像这样重新编写了安装方法:

public override void Install(IDictionary stateSaver)
{
  string userName = this.Context.Parameters["username"];
  if (userName == null)
  {
    Console.WriteLine(s_usage);
    throw new InstallException("Missing parameter 'username'");
  }

  string userPass = this.Context.Parameters["password"];
  if (userPass == null)
  {
    Console.WriteLine(s_usage);
    throw new InstallException("Missing parameter 'password'");
  }

  m_serviceProcessInstaller.Username = userName;
  m_serviceProcessInstaller.Password = userPass;

  var path = new StringBuilder(Context.Parameters["assemblypath"]);
  if (path[0] != '"')
  {
    path.Insert(0, '"');
    path.Append('"');
  }
  path.Append(" --service");
  Context.Parameters["assemblypath"] = path.ToString();
  base.Install(stateSaver);
}

虽然我提供了预定义的命令行参数 (--service),但代码很容易适应传递真实的命令行参数,只需使用相同的模式传递 usernamepassword 参数。


2
如果您将处理程序附加到服务安装程序对象的BeforeInstall事件,而不是覆盖Install方法,则此方法也适用。 - Peter Wone
2
实际上不是这样的。它应该是这样的,我相当确定它曾经是这样的,但我刚刚检查了一下,它不是这样的。坚持使用覆盖版本。 - Peter Wone
我有一个与我的安装程序传递凭据的相同解决方案。问题是日志文件也包含您的凭据,这在我看来是一个大问题。您有什么想法可以禁用日志文件中“受影响的参数为:”的编写吗?我不想完全禁用日志文件! - flayn
@FlorianGerhardt - 不好意思,我已经转向Java和Javascript了,半年来没有用.NET。抱歉,伙计。 - mark
3
这个解决方案不起作用。它为服务生成以下命令行: ""C:\folder\file.exe" --service"。 - Sergey

4
我知道这是一篇老帖子,但我想回复一下。我在一个使用了 .net 4 的服务中,通过 BeforeInstall 事件来实现。

ServiceProcessInstaller 的 BeforeInstall 事件:

private void serviceProcessInstaller1_BeforeInstall(object sender, InstallEventArgs e)
{
    System.ServiceProcess.ServiceProcessInstaller installer = sender as System.ServiceProcess.ServiceProcessInstaller;

    if (installer != null)
    {
        //Get the existing assembly path parameter
        StringBuilder sbPathWIthParams = new StringBuilder(installer.Context.Parameters["assemblypath"]);

        //Wrap the existing path in quotes if it isn't already
        if (!sbPathWIthParams[0].Equals("\""))
        {
            sbPathWIthParams.Insert(0, "\"");
            sbPathWIthParams.Append("\"");
        }

        //Add desired parameters
        sbPathWIthParams.Append(" test");

        //Set the new path
        installer.Context.Parameters["assemblypath"] = sbPathWIthParams.ToString();
    }
}

已安装的服务如下所示: enter image description here 它能够正常执行,并且我可以在服务的主函数内部检查参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接