34
48

More than 1 year has passed since last update.

[C#] C#でサービスを作る

Last updated at Posted at 2021-02-08

サービス関連記事

やりたいこと

仕事でWindowsのサービスを扱った際、ログイン/ログアウトしたときに〇〇をする、みたいなことを書いたのだが、なにか、再起動したときのログインの動きが直感的ではないというか、妙な動きをしているように見えた。(まだログイン画面でログイン押してないのにサービス的にはログインしたことになって動き始めてる、とか。)

その辺を検証したかったのだが、Windowsの「サービス」というものを作ったことがなかったので、自宅でちゃちゃっと実験できる用意がなかった。

上の実験をするために、ついでに&急がば回れで、まずはC#でWindowsサービスをつくれるようになっておきたい。

やったこと

MSの公式と下記のページをかなり参考にさせていただき、C#でサービスを作った。

■C#でWindows Serviceを作る 1~5
https://qiita.com/yossihard/items/46f72af754915b242bed

■Tutorial: Create a Windows service app
https://docs.microsoft.com/ja-jp/dotnet/framework/windows-services/walkthrough-creating-a-windows-service-application-in-the-component-designer

手順

■プロジェクトの作成

まずプロジェクトを作る。
「新しいプロジェクトの作成」画面で、「Windowsサービス(.NET Framework)」を選択する。
(今回は.NETで作成。)

image.png

プロジェクトを開くと、下図のように、サービスの[デザイン]が開いた状態になっている。

image.png

■インストーラーの追加

このデザインの画面で、何もないところを右クリック > [インストーラーの追加] を選択する。

image.png

ProjectInstaller.csが追加される。

image.png

ProjectInstaller.csの[デザイン]が開いた状態になる。
SericeProcessInstallerとServiceInstallerがもとから入っている

image.png

ここに、サービスの基本設定をしていく。

■サービスの基本設定をする

SericeProcessInstallerの設定をする。
デザイナー上の「SericeProcessInstaller」を右クリ→プロパティ

Accountを設定する。
とりあえず、今回はサービスの作成をしたいだけで、管理者権限が必要になるようなことはしないので、Userにしておく。

image.png

次に、ServiceInstallerの設定をする。

image.png

  • DelayedAutoStart:他の自動的に開始されるサービスが実行されるまで、サービスの開始を遅延するかどうか
  • Description:サービスの説明
  • DisplayName:サービス管理ツール等での表示用の名前
  • ServiceName:サービス識別名
  • StartType:サービスの開始タイミングを指定

※それぞれ、タスクマネージャとかサービス管理画面でみると、こういう関係。
image.png
image.png

StartTypeは下記を参照。
https://docs.microsoft.com/ja-jp/dotnet/api/system.serviceprocess.servicestartmode?view=netframework-4.8
BootとSystemはドライバ用で、普通のサービスはAutomaticかManualを選択しておけばよいっぽい。

■ビルドする

インストールする際に使うので、ビルドしてexeができたフォルダパスを控えておく。
例えば、私の環境だとC:\Users\masa\source\repos\WindowsService2\WindowsService2\bin\Debug

■作ったサービスをインストールする

開発者コマンドプロンプトを管理者権限で起動する。

image.png

開発者コマンドプロンプトで下記を実行する

  • cd exeの出力先フォルダ
  • installutil exe名.exe image.png

上記を実行すると、ユーザー名とパスワードを入力する画面が表示されるので、管理者権限のあるユーザー名とパスワードを入力する。※ユーザー名の先頭には、「コンピューター名\」をつけること。

たとえば、PC名が「masa-PC」でユーザー名が「masa」だったら、下記のような感じ。

image.png

コンピュータ名はコントロールパネルの「システム」で見れる。

image.png

成功したら、こんなのが出る。

image.png

インストールしたサービスをservices.mscで見ると下記のような感じ。
image.png

インストールしたサービスをタスクマネージャーで見ると下記のような感じ。
image.png

■その他サービスの各種設定

デザイナー画面にしてるときに表示されるプロパティで、ServiceBaseの設定をする。

まず、電源周りのイベントを受け取りたい、Session関連のイベントを受け取りたいなど、必要な情報、うけとりたい情報を設定する。(いろいろ実験してたので、画像中のサービス名がservice 1だったり2だったりしてます。すみません)
image.png

また、Shutdownできるか、一時停止できるか、などもここで設定する。
上のプロパティでCanPauseAndContinueをtrueにしてると、下記のようにサービス管理画面で右クリしたときのメニューで「一時停止」と「再起動」が押せるようになる。
image.png

■デバッグする

デバッグするときは、アタッチを行う。
image.png

image.png

※管理者権限でVSを起動していない場合、アタッチしようとすると「管理者権限で再起動しますか?」ということを聞かれるので、管理者権限でVSを再起動してからもう一度アタッチする。

■各種イベント発生時にやりたいことを書く

ソリューションエクスプローラーで
service1.csを右クリックして、コードを表示、を選択し、コードを出す。

クラス名のところ(今回はService1)の右クリ→[上書きを追加]を押す。
(オーバーライドを追加するということ)
image.png

下記のような画面がでるので、必要なものだけチェックしてOKを押す。
今回はとりあえず実験的に、サービス管理画面でサービスを「一時停止」して「再開」したときにオーバーライドしたメソッドを通ることをみたいので「OnPause」「OnContinue」にチェックを入れてOKを押す。
image.png

そのメソッドを通ったときにデバッグ用メッセージを出すようにコードを書く。
image.png

これで、サービスを一時停止→再開と操作してやると、メッセージが出る。

これで、いったんサービスを作って実際に動かす一通りの実験はできたことになる。

■コードを修正したときにサービスに反映させる

ビルドしなおしてそれを反映させようと思ったら、一度サービスをアンインストールして、ビルドしなおした後、再度インストールする。

  • サービス停止
  • ビルド
  • サービスをアンインストール
  • サービスをインストール

という順番。手動でやっていると面倒なので、下記のようなバッチを作っておくと楽かもしれない。


rem まず開発者用コマンドプロンプトを起動してから
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat"

rem サービス名(サービス管理画面の名前欄に出てくる名前)
set SERVICENAME=Service1DisplayName
set SOLUTIONPATH="C:\Users\masa\source\repos\WindowsService1\WindowsService1.sln"
set EXEPAH="C:\Users\masa\source\repos\WindowsService1\WindowsService1\bin\Debug\WindowsService1.exe"

rem サービス停止
net stop "%SERVICENAME%"

rem ビルドする
MSBuild %SOLUTIONPATH% /t:clean;rebuild /p:Configuration=Debug;Platform="Any CPU" > nul
if %ERRORLEVEL% neq 0 (
    echo ErrorLevel:%ERRORLEVEL%
    echo ビルド失敗
    pause
    exit
)

rem アンインストール実施
installutil -u %EXEPAH%

rem インストール実施
installutil /username=masa-PC\masa /password=******** /unattended %EXEPAH%

rem サービス再開
net start "%SERVICENAME%"

pause

参考

■C#でWindows Serviceを作る 1~5
https://qiita.com/yossihard/items/46f72af754915b242bed

■Tutorial: Create a Windows service app
https://docs.microsoft.com/ja-jp/dotnet/framework/windows-services/walkthrough-creating-a-windows-service-application-in-the-component-designer

■権限
https://www.atmarkit.co.jp/ait/articles/0905/08/news095.html

34
48
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
48