Windowsサービスを作成する。(System.Configuration.Install.Installer,System.ServiceProcess.ServiceBase)

Windowsサービスを作成するためには最低限2つのクラスを作成する必要があります。

■Serviceの登録:System.Configuration.Install.Installer
まずは、.NetアプリをWindowsサービスとして登録するインストールプログラムを実装します。

.Netではカスタムインストーラを作成する場合はSystem.Configuration.Install.Installerクラスを継承してカスタムインストールの処理を実装します。Installerクラスは、インストール時にのみ実行されるコードを実装するクラスです。このクラスでWindowsサービスの実行ユーザアカウント、手動起動・自動起動、サービス名を登録する処理を実装し、.NetのインストールユーティリティInstallUtil.exeを使ってインストールを行うという流れになります。


public class MyInstaller : System.Configuration.Install.Installer
{

private ServiceInstaller _si;
private ServiceProcessInstaller _pi;

public MyInstaller()
{

_pi = new ServiceProcessInstaller();

_pi.Account = ServiceAccount.LocalSystem;

this.Installers.Add(_pi);

_si = new ServiceInstaller();

_si.StartType = ServiceStartMode.Automatic;
_si.ServiceName = "tekk windows service sample";

this.Installers.Add(_si);

}
}

System.ServiceProcess.ServiceProcessInstallerで、Windowsサービスの実行アカウント。System.ServiceProcess.ServiceInstallerで自動起動か手動起動か、サービス名を設定しています。

サービスの実行アカウントは、LocalSystemアカウント(管理者権限)が一般的だと思いますが下記の中から任意の値を設定できます。

LocalService:ローカル コンピュータ上の特権を与えられていないユーザーとして機能するアカウント。このアカウントは、匿名の資格情報をリモート サーバーに提示します。
LocalSystem:ローカル コンピュータ上で広範囲の特権を持ち、ネットワーク上のコンピュータとして機能するアカウント。このアカウントは、サービス コントロール マネージャが使用します。
NetworkService:広範囲のローカル特権を提供するアカウント。このアカウントは、コンピュータの資格情報をリモート サーバーに提示します。
User:ネットワーク上の特定のユーザーによって定義されたアカウント。ServiceProcessInstaller.Account メンバに対して User を指定すると、ServiceProcessInstaller インスタンスの Username プロパティ値と Password プロパティ値を設定していない限りは、サービスのインストール時に有効なユーザー名とパスワードを入力するように要求されます。

■Serviceの実装:System.ServiceProcess.ServiceBase
ServiceBaseクラスを継承したクラスを作成してスタートアップに継承したクラスを指定して作成します。OnStartメソッドが起動,OnStopが停止,OnShutDownがシステムがシャットダウンした際のイベントに対応します。中断と再開をサポートする場合は、OnPauseメソッド(中断)とOnContinue(再開)をオーバーライドします。

Shutdownをサポートするためには、CanShutDownプロパティをTrueに、中断と再開をサポートするためにはCanPauseAndContinueプロパティをTrueに設定します。

実務ではShutdownをサポート、中断と再開はサポートしないというケースが多いと思います。(ユーザがシャットダウン操作をした場合でも適切な終了処理を行いたい、中断と再開までは特に要らない(起動と停止で足りる)などの理由)

*シャットダウンの場合は、ShutDownイベントでOnStopメソッドを呼び出さない限り、OnStopは走らないので注意してください。


public class MyService : System.ServiceProcess.ServiceBase
{

public static void Main()
{

MyService s = new MyService();

s.CanShutdown = true;
s.CanPauseAndContinue = false;

ServiceBase.Run(s);
}

protected override void OnStart(string[] args)
{
base.OnStart(args);
}

protected override void OnStop()
{
base.OnStop();
}

protected override void OnShutdown()
{
base.OnShutdown();
}

}

Windowsサービスのデバッグ
サービスのデバッグは難しいので、通常はコンソールアプリケーションとしてサーバプログラムを開発してクライアントとマルチスタートアッププロジェクトとして構成してデバッグする。サービス部分は、ステップ実行でのデバッグが出来ないので、ログを出力してデバッグするというのがお勧めです。サービス部分は最低限の処理のみ実装し、複雑な処理を記載しないのがコツです。複雑な初期処理・終了処理はコンソールアプリからでもデバッグできるように設計しておきましょう。

Windowsサービスとして構成されるアプリはWCFや.Net Remoting,Socketベースの受信サーバプログラムが多いと思います。

テスト用コンソールプログラムは以下の様な、待ち処理のみで構成すると開発しやすくなります。


public class ConsoleStartUp
{
public static void Main(string[] args)
{

Console.WriteLine("何かキーを押すと終了します。");
Console.ReadLine();

}
}