Windows NT/2000/XP には「サービス」というのがあるが、あれを自分で作る場合、どうすればいいのか。方法は 4 種類。うち 1 種類が C ベースで、2 種類が C++ ベース、最後の 1 種類は .NET Framework を利用したもの。
C ベースの実装方法
これについては、以下のサイトが詳しい。残り 2 つの C++ ベースの方法というのはこれをラップしたものなので、どの方法で実装するにしろ、一度読むことをオススメしたい。
- depressionist - 20020821We
- http://hp.vector.co.jp/authors/VA015815/200234.html#D20020821
C++ ベースの実装方法 (1)
VC6 の ATL COM AppWizard で作る場合、基本はここから。
- [ファイル]→[新規作成]
- [プロジェクト]タブで、[プロジェクト名] を入力し、[ATL COM AppWizard] を選択
- [ATL COM AppWizard - ステップ 1/1] が開いたら、[サーバー タイプ] で [サービス (EXE)]を選択
これで空のサービスができあがる。出来上がったソースには、サービスを表す CServiceModule というクラスが定義されている。このクラスについては、MSDN に解説がちょっとだけある。
グローバル関数 _tWinMain を見ると、起動引数として以下の 3 つが定義されている。
- UnregServer
- 登録を解除する
- RegServer
- ローカルサーバとして登録する
- Service
- サービスとして登録する
ここで言う「ローカルサーバ」というのは、マシンローカルで動作する COM サーバのことだ。今回はサービスとして登録したいので、[プロジェクト]→[設定] でダイアログを開いて、[カスタムビルド] タブの [コマンド] を修正する。1 行目に
"$(TargetPath)" /RegServer
とあるのを、以下に直す (ちなみに、間違えて "/Server" と入力したら、プロセスが終わらなくなった)。
"$(TargetPath)" /Service
[OK] を押してダイアログを閉じたら、ビルドしてみると、サービスとして登録される。「管理ツール」の「サービス」を起動すると、一覧に追加されているはずだ (デフォルトではプロジェクト名がそのままサービス名として使われる)。何もしないサービスではあるが、起動・停止・再起動はできるし、プロパティの設定も行える。
後は、生成された CServiceModule をいじって、サービスの処理を実装していけばいい。基本的には、メンバ関数 Handler() でサービス操作に対応したり、Run() 内のメッセージループを修正していったりすればいいだろう。以下のサイトが参考になる。
- EZ-NET 研究 - ATL でサービスプログラムを作ってみる
- http://program.station.ez-net.jp/special/vc/atl/service_vc6.asp
C++ ベースの実装方法 (2)
前項は VC6 での実装方法だが、VC7 では変更が加えられているらしく、CServiceModule のかわりに、CAtlServiceModuleT テンプレートクラスを使用して実装するようになっている。手元に環境がないので、URL の紹介のみ。
- MSDN - ATL ライブラリ リファレンス - CAtlServiceModuleT クラス
- http://www.microsoft.com/japan/msdn/library/ja/vclib/html/vclrfcatlservicemodulet.asp
- EZ-NET 研究 - 【成功版】 ATL でサービスプログラムを作ってみる
- http://program.station.ez-net.jp/special/vc/atl/service_vc2003.asp
.NET Framework を使った実装方法
C# や VB.NET 等でサービスを実装する場合には、System.ServiceProcess 名前空間にある ServiceBase を継承したクラスを実装することになる。.NET Framework SDK のドキュメントを見ると、「アプリケーションの構築」の中に「Windows サービス アプリケーションの概要」がある。VS.NET は手元になくてわからないのだが、SharpDevelop にもテンプレートがあるので、そっからいじっていけばいい。