2013-03-28 53 views
2

我有一个类从System.Configuration.Install.Installer类继承,并用于安装Windows服务。它看起来像这样:安装程序类,接收'安装'方法中使用的参数

[RunInstaller(true)] 
public class HostInstaller : Installer 
{ 
    private const string _serviceName = "My service name"; 
    private ServiceProcessInstaller _process; 
    private ServiceInstaller _service; 

    public HostInstaller() 
    { 
     _process = new ServiceProcessInstaller(); 
     _process.Account = ServiceAccount.User; 
     _process.Username = "My user name"; // Hard coded 
     _process.Password = "My password"; // Hard coded 
     _service = new ServiceInstaller(); 
     _service.ServiceName = _serviceName; 
     _service.Description = "My service description"; 
     _service.StartType = ServiceStartMode.Automatic; 
     Installers.Add(_process); 
     Installers.Add(_service); 
    } 
} 

我已经使用了InstallUtil.exe实用程序安装和卸载此服务,一切工作就好了。

然后,我必须接收用户名和密码作为参数(而不是硬编码),所以我已经更改了类并重写了'Install'方法,并从构造函数移动了上述代码部分。现在

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

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

    _process = new ServiceProcessInstaller(); 
    _process.Account = ServiceAccount.User; 
    _process.Username = userName; 
    _process.Password = password; 
    _service = new ServiceInstaller(); 
    _service.ServiceName = _serviceName; 
    _service.Description = "My service description"; 
    _service.StartType = ServiceStartMode.Automatic; 
    Installers.Add(_process); 
    Installers.Add(_service); 

    base.Install(stateSaver); 
} 

,我再次安装的服务,使用此:

InstallUtil.exe /用户名=用户名/密码= userPassword的路径...

服务的安装工作很好,有所需的用户名和密码。但是,我现在确实有一个卸载服务的问题。我正在使用InstallUtil.exe/u,但该服务仍然存在。

我读here一个有用的技巧:

如果您需要安装实例添加到安装程序集合中的安装方法时,一定要在卸载方法执行相同的添加到集合中。但是,如果将安装程序实例添加到定制安装程序的类构造器中的Installers集合中,则可以避免在两种方法中维护集合。

我真的不明白什么可以解决这个问题。

任何帮助将不胜感激。

埃拉德

回答

1

*解决方案*

这里是我找到了解决办法,确实是按照我所显示上面的链接:

在我的安装做同样的像卸载()方法()方法(除了订阅AfterInstall事件),然后调用base.Uninstall()方法。

的方法是这样的:

public override void Uninstall(System.Collections.IDictionary stateSaver) 
{ 
    string userName = this.Context.Parameters["UserName"]; 
    if (userName == null) 
    { 
     throw new InstallException("Missing parameter 'UserName'"); 
    } 

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

    _process = new ServiceProcessInstaller(); 
    _process.Account = ServiceAccount.User; 
    _process.Username = userName; 
    _process.Password = password; 
    _service = new ServiceInstaller(); 
    _service.ServiceName = _serviceName; 
    _service.Description = "My service description"; 
    _service.StartType = ServiceStartMode.Automatic; 
    Installers.Add(_process); 
    Installers.Add(_service); 

    base.Uninstall(stateSaver); 
} 

当然,对于这两种方法的共同代码应被包装成一个单一的私有方法。

现在,为了卸载服务,您应该调用InstallUtil。exe文件与用户名和密码,就像这样:

InstallUtil.exe/U /用户名=用户名/密码= userPassword的路径...

祝你好运,

埃拉德

0

从你的链接

如果覆盖在派生类中的方法安装时,一定要首先调用基类的安装方法,在派生方法。

您正在致电base.Install(...)最后。请按照文档建议,在做任何其他工作之前尝试调用它,看看是否可以缓解您的问题。

+0

感谢杰克。该文档还说 - “Install方法调用此实例的Installers属性中包含的每个安装程序的Install方法”。它看起来像在尝试在base.Install(...)之后设置用户名和密码太晚。我会尝试这个并更新。 – 2013-03-28 00:56:02

相关问题