Windowsサービスを作成するには、Visual Studio Professional以上でないと、Visual Studioの新規プロジェクト作成から「Windowsサービス」を選択できないので作成できません。しかし、Visual Studio ExpressでもWindowsサービスのテンプレートを作ることができます。

開発/実行環境

  • Visual Studio2013 Express (C#)
  • Windows 7 Professional

Windowsサービスのソフトの作成

Visual Studio2013 Express (C#)を使用して、Windowsサービスアプリケーションのテンプレートを作る手順を次に示します。

  1. メニュー[ファイル]-[新しいプロジェクト]を開き、プロジェクト名は「PcMoniter」(任意)にします。
  2. コンソールアプリケーション」を選択します。
  3. 参照追加で以下を追加します
  4. 3-1) System.Configuration.Install

    • サービスアプリケーションはシステム(Windows のこと)が認識できるように登録しなければなりません。サービスアプリケーションの本体と同様に、インストーラの形式は System.Configuration.Install.Installer クラスから派生することに決まっているので、プロジェクトの参照に追加します。もちろん、using 文もです。

    3-2) System.ServiceProcess

    • サービスアプリケーションは System.ServiceProcess.ServiceBase クラスから派生することが決まりであるので、プロジェクトの参照に追加します。もちろん、using 文も必要です。
  5. プロジェクト名を右クリックして、[プロパティ][アプリケーション]タブを以下のように修正します。
  6. 4-1) 出力の種類:Windowsアプリケーション
    4-2) 対象のフレームワーク:.NET Framework 4.5
    4-3) スタートアップ オブジェクト:PcMoniter.Program

  7. 以下のファイルを追加します。~.Designer.csも自分でファイル追加します。
  8. 5-1) Program.cs
    5-2) PcMoniterService.cs
    5-3) PcMoniterService.Designer.cs
    5-4) PcMoniterServiceInstaller.cs
    5-5) PcMoniterServiceInstaller.Designer.cs

これで、クラスファイルは作成できたので、次のコードを作成したファイルに実装していきます。

Program.cs

using System.ServiceProcess;

namespace PcMoniter
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceBase[] servicesToRun =
                new ServiceBase[]
                {
                    new PcMoniterService(),
                };
            ServiceBase.Run(servicesToRun);
        }
    }
}

PcMoniterService.cs

Windows サービス作る場合、ServiceBase を継承して、適当なイベントメソッドをオーバライドして作ります。

using System.ServiceProcess;

namespace PcMoniter
{
    public partial class PcMoniterService : ServiceBase
    {
        
 // サービスを開始するときに呼び出されるメソッド
        protected override void OnStart(string[] args)
        {
        }

 // サービスを停止するときに呼び出されるメソッド
       protected override void OnStop()
        {
        }
}

PcMoniterService.Designer.cs

using System.Diagnostics;
using System.ServiceProcess;

namespace PcMoniter
{
    public partial class PcMoniterService : ServiceBase
    {
        // コンポーネント デザイナで必要です。
        private System.ComponentModel.IContainer components;

        [DebuggerNonUserCode()]
        protected override void Dispose(bool disposing)
        {
            if (disposing && this.components != null)
            {
                this.components.Dispose();
            }
            base.Dispose(disposing);
        }

        [DebuggerStepThrough()]
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();

            // PcMoniterService
            this.AutoLog = false;
            this.ServiceName = "PcMoniterService";
        }
    }
}

PcMoniterServiceInstaller.c

さらに、.NET Framework Runtimeに同梱されている InstallUtil.exeにてWindowsサービスの登録を行うために、Installerクラスを継承したサブクラスを用意します。

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

namespace PcMoniter
{
    [RunInstallerAttribute(true)]
    public partial class PcMoniterServiceInstaller : Installer
    {
        public PcMoniterServiceInstaller()
        {
            this.InitializeComponent();
        }
    }

}

PcMoniterServiceInstaller.cs

using System.Configuration.Install;
using System.Diagnostics;
using System.ServiceProcess;

namespace PcMoniter
{
    public partial class PcMoniterServiceInstaller : Installer
    {
        private ServiceInstaller serviceInstaller;
        private ServiceProcessInstaller serviceProcessInstaller;
        
        [DebuggerStepThrough()]
        private void InitializeComponent()
        {
            this.serviceProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller();
            this.serviceInstaller = new System.ServiceProcess.ServiceInstaller();
            // 
            // serviceProcessInstaller
            // 
            this.serviceProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
            this.serviceProcessInstaller.Password = null;
            this.serviceProcessInstaller.Username = null;
            // 
            // serviceInstaller
            // 
            this.serviceInstaller.ServiceName = "PcMoniterService";
            this.serviceInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
            // 
            // PcMoniterServiceInstaller
            // 
            this.Installers.AddRange(new System.Configuration.Install.Installer[] {
            this.serviceProcessInstaller,
            this.serviceInstaller});
        }
    }
}

これで、最低限のサービスアプリケーションが出来上がりました

Windowsサービスのソフトのインストール/アンインストール

サービスを Windows に登録する一般的な手順は .NET Framework に付属の InstallUtil.exe を使う方法です。ちなみに、InstallUtil.exe のインストールディレクトリは、私の環境の場合、「C:\Windows\Microsoft.NET\Framework\v4.0.30319\」にあります。管理者権限でコマンドプロンプトを開いて、サービスのexeのあるディレクトリへ移動して、以下のコマンドを実行します。

 [インストールディレクトリ]installutil PcMoniter

「インストールが完了しました。」と出れば正常に実行されました。管理ツール「コントロール パネル\システムとセキュリティ\管理ツール」の「サービス」を見ると、次のように「PcMoniterService」が登録されています。

管理ツールによるサービスの表示
アンインストールは、次のコマンドを実行します。

 
[インストールディレクトリ]installutil /u PcMoniter

バージョン別InstallUtil.exeのインストールディレクトリ

.NET Frameworkの複数バージョンを使っている場合には、コンパイルした.NET Frameworkと同じバージョンのInstallUtilを使う必要があります。InstallUtil.exeは、.NET Frameworkの次のディレクトリにあります。

2.0 - 3.5
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe
4
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe
次のメッセージが出た場合、管理者権限でコマンドを実行します。

インストール段階で例外が発生しました。
System.Security.SecurityException: ソースが見つかりませんでしたが、いくつかまたはすべてのログを検索できませんでした。アクセス不可能なログ: Security[/]

Windowsサービスのデバッグ

サービスをデバッグしたいときは、Visual Studioのツールメニューから「プロセスにアタッチ」を選択する。サービスのexeを一覧から選んで、次のように「アタッチ」すれば、あとはいつものようにデバッグできます。

Windowsサービスのデバッグ