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 /UserName=ユーザー名 /Password=UserPassword パス...

必要なユーザー名とパスワードを使用して、サービスのインストールはうまく機能しています。ただし、サービスのアンインストールに問題があります。InstallUtil.exe /u を使用していますが、サービスはまだ存在しています。

ここで役立つヒントを読みました:

Install メソッドで Installers コレクションにインストーラー インスタンスを追加する必要がある場合は、必ず Uninstall メソッドでコレクションに同じ追加を実行してください。ただし、カスタム インストーラーのクラス コンストラクターでインストーラー インスタンスを Installers コレクションに追加すると、両方の方法でコレクションを維持することを回避できます。

何がこの問題を解決できるのか本当に理解できません。

どんな助けでも大歓迎です。

エラド

4

2 に答える 2

1

* Solution *

Here is the solution I found, indeed according the link I have displayed above:

In the Uninstall() method I'm doing exactly the same like in the Install() method (besides subscribing the AfterInstall event), and then calling the base.Uninstall() method.

The method looks like this:

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);
}

Of course that the common code for both the methods should be wrapped into a single private method.

Now, in order to uninstall the service you should call InstallUtil.exe with the user name and the password, like this:

InstallUtil.exe /u /UserName=UserName /Password=UserPassword Path...

Good luck,

Elad

于 2013-04-02T22:26:41.903 に答える
0

あなたのリンクから

派生クラスで Install メソッドをオーバーライドする場合は、派生メソッドで最初に基本クラスの Install メソッドを呼び出してください。

base.Install(...)あなたは最後に電話しています。ドキュメントが示唆するように、他の作業を行う前にそれを呼び出して、問題が軽減されるかどうかを確認してください。

于 2013-03-28T00:46:21.513 に答える