インストール時にWindowsサービスを自動的に開始する


119

InstallUtil.exeを使用してインストールするWindowsサービスがあります。[起動方法]を[自動]に設定しても、インストール時にサービスが開始されないため、サービスを手動で開いて[開始]をクリックする必要があります。コマンドラインから、またはサービスのコードから起動する方法はありますか?

回答:


218

インストーラークラスで、AfterInstallイベントのハンドラーを追加します。その後、イベントハンドラーでServiceControllerを呼び出して、サービスを開始できます。

using System.ServiceProcess;
public ServiceInstaller()
{
    //... Installer code here
    this.AfterInstall += new InstallEventHandler(ServiceInstaller_AfterInstall);
}

void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e)
{
    ServiceInstaller serviceInstaller = (ServiceInstaller)sender;

    using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName))
    {
             sc.Start();
    }
}

これで、InstallUtilをインストーラーで実行すると、サービスがインストールされ、自動的に起動します。


40
(提案された編集からのコメント):serviceInstaller.ServiceNameを使用することをお勧めします。サービス名が変更された場合、コードで変更する必要なく、正しい名前が使用されます。
マークグラベル

1
またServiceController、usingステートメントでラップしても問題ありません。
ChrisO 2013年

3
serviceInstallerはどのように入手していますか?
Philip Rego

1
serviceInstallerはServiceInstaller、クラスの変数であると想定されています。そのようなクラスが実装されSystem.Configuration.Install.Installerます。詳細については、このmsdnガイドを参照してください。
Sergio Basurco 2017年

4
@PhilipRegoは、おそらくserviceInstallerあるServiceInstallerオブジェクトがで参照sender正常にインスタンス化されたイベントハンドラにServiceInstaller()コンストラクタ。したがってServiceInstaller serviceInstaller = (ServiceInstaller)sender;usingステートメントの前に追加できます。
khargoosh 2017

28

少しリファクタリングした後、これは自動起動を備えた完全なWindowsサービスインストーラーの例です。

using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace Example.of.name.space
{
[RunInstaller(true)]
public partial class ServiceInstaller : Installer
{
    private readonly ServiceProcessInstaller processInstaller;
    private readonly System.ServiceProcess.ServiceInstaller serviceInstaller;

    public ServiceInstaller()
    {
        InitializeComponent();
        processInstaller = new ServiceProcessInstaller();
        serviceInstaller = new System.ServiceProcess.ServiceInstaller();

        // Service will run under system account
        processInstaller.Account = ServiceAccount.LocalSystem;

        // Service will have Start Type of Manual
        serviceInstaller.StartType = ServiceStartMode.Automatic;

        serviceInstaller.ServiceName = "Windows Automatic Start Service";

        Installers.Add(serviceInstaller);
        Installers.Add(processInstaller);
        serviceInstaller.AfterInstall += ServiceInstaller_AfterInstall;            
    }
    private void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e)
    {
        ServiceController sc = new ServiceController("Windows Automatic Start Service");
        sc.Start();
    }
}
}

2
このコードにより、次のエラーが発生しました:インストールフェーズ中に例外が発生しました。System.InvalidOperationException:System.ServiceProcess.ServiceInstallerのOnAfterInstallイベントハンドラーで例外が発生しました。内部例外System.InvalidOperationExceptionが次のエラーメッセージでスローされました:コンピューター '。'でサービスserviceNameを開始できません。内部例外System.ComponentModel.Win32Exceptionが次のエラーメッセージでスローされました:このサービスが構成されている実行可能プログラムrun inはサービスを実装していません。
goamn

2
「InitializeComponent()」という行をコメントアウトすると、エラーが発生しました。エラーの前にログで2つの同じことが同時に発生しているように見えるため、この行が他のすべての行を複製していると思います。サービスserviceNameをインストールしています...サービスserviceNameが正常にインストールされました。ログアプリケーションにEventLogソースserviceNameを作成しています...サービスserviceNameをインストールしています...ログアプリケーションにEventLogソースserviceNameを作成しています... System.ServiceProcess.ServiceInstallerのOnAfterInstallイベントハンドラーで例外が発生しました。
goamn

あなたは本当に私の日を救った:)この便利なコメントをありがとう。InitializeComponent()呼び出しをコメントアウトした後、私のサービスも完全に開始されました
Konstantin

7

次のコマンドはどうですか?

net start "<service name>"
net stop "<service name>"

涼しい。インストールが完了した直後に、これをインストールバッチファイルに書き込みました。
M.ファワドスロッシュ

5

サービスを制御するためのプログラムオプション:

  • 「サービスの開始」のネイティブコードを使用できます。依存関係を最小限に抑えながら最大限の制御を行いますが、ほとんどが機能します。
  • WMI:Win32_ServiceにはStartServiceメソッドがあります。これは、他の処理を実行する必要がある場合(たとえば、どのサービスを選択するか)に適しています。
  • PowerShellは:実行Start-Service経由RunspaceInvokeしたり、独自に作成することによりRunspace、その使用してCreatePipeline実行する方法を。これは、WMIよりもはるかに簡単なコーディングモデルで他の処理を実行する必要がある(たとえば、どのサービスを選択する)必要がある場合に適していますが、インストールされているPSHに依存します。
  • .NETアプリケーションが使用できる ServiceController


2

ServiceControllerを使用して、コードからサービスを開始します。

更新:コマンドラインからサービスを開始するより正確な方法は、「net」の代わりに「sc」(サービスコントローラー)コマンドを使用することです。


6
なぜ「sc」は「より正しい」方法なのでしょうか?"net start"(およびstart-service PSHコマンドレット)の何が問題になっていますか?
Richard

1
scはリモートマシンから呼び出すことができるため、常に機能します。
MacGyver

1

正確に受け入れられた答えを、以下のにもかかわらず、私はまだ私が代わりにそれが存在していなかったとしてだけでインストールされたサービスを使用しているにもかかわらず、起動できなかったことを示す、インストール中にエラーメッセージを与えられたstart--するサービスを取得できませんでしたthis.serviceInstaller.ServiceNameではなくリテラルより...

私は最終的にコマンドラインを利用する代替ソリューションを見つけました:

private void serviceInstaller_AfterInstall(object sender, InstallEventArgs e) {
        ProcessStartInfo startInfo = new ProcessStartInfo();
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
        startInfo.FileName = "cmd.exe";
        startInfo.Arguments = "/C sc start " + this.serviceInstaller.ServiceName;

        Process process = new Process();
        process.StartInfo = startInfo;
        process.Start();
    }

0

自動起動とは、Windowsの起動時にサービスが自動的に起動されることを意味します。他の人が述べたように、コンソールから開始するには、ServiceControllerを使用する必要があります。


私はこれをしたくありません。コマンドラインから、またはWindowsサービスクラス内から、これを一度に実行することを検討しています。
mickyjtwin 2009年

申し訳ありませんが、残念ですが、コントロールパネルから起動する可能性を明示的に除外した点を逃しました。
マイケルクレメント

0

ServiceController クラスのGetServicesメソッドを使用して、すべてのサービスの配列を取得できます。次に、各サービスのプロパティをチェックして、サービスを見つけます。サービスが見つかったら、メソッドを呼び出してサービスを開始します。ServiceNameStart

また、Statusstartを呼び出す前に、プロパティをチェックして、どの状態にあるかを確認する必要があります(実行中、一時停止中、停止中など)。


0

あなたはあなたのデザイナーを壊しました。インストーラコンポーネントを再度追加します。serviceInstallerとserviceProcessInstallerが必要です。プロパティの[スタートアップ方法]が[自動]に設定されているserviceInstallerは、インストール時および各再起動後に起動します。


0

注:フォームインターフェイスを使用して、サービスインストーラーとプロジェクトインストーラーを追加するために、サービスを別の方法で設定した可能性があります。その場合は、serviceInstaller.ServiceNameとある箇所を「デザイナーの名前」.ServiceNameに置き換えます。

この場合、プライベートメンバーも必要ありません。

助けてくれてありがとう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.