うぃろぅ.log

140字で綴りきれない日々の徒然備忘録

【Windows サービス】 Visual Studio 2017でWindows サービスを作る その1

うぃろぅです。

業務でWindows サービスを作ることになり、今後も作ることがあるかもしれないのでまとめることに。

若干長くなったので、
その1ではWindows サービスの登録/解除までとした。

今回の目標

フォルダの変更を検知し、ログファイルに吐き出す。

XMLファイルを検知して通信するサービスを作成しているのでそれの簡易版。

環境

Visual Studio 2017
C# 7 (規定値)

プロジェクト作成

f:id:vviilloovv:20181114115944p:plain

[新規作成] → [プロジェクト] → [Windows デスクトップ] → [Windows サービス]

名前は「WatchService」とでもしておきましょう。

f:id:vviilloovv:20181114120540p:plain

初期画面。"Service1"のようにイケてない初期値をカスタマイズ。

f:id:vviilloovv:20181114130803p:plain

"Watcher"とした。Fate/strange fake推しとしてもな。

サービス登録

Windows サービスの登録には少なくとも2種類の方法がある。
(他の方法を知っていたら教えてください…レジストリエディターからならいけそう?)

  • installutil コマンドを叩く
  • sc create コマンドを叩く

基本はinstallutilコマンドの方で大丈夫。
Visual Studio上で設定値を決めれば叩くだけなので楽。

ではsc createコマンドは何に使うかというと、ソースの変更無しに複数サービスを同時に登録したいときに使う。
サービス名を登録時に決められるから複数でも別サービスとして認識されるってワケ。
まあ普通はそんなことしないでしょう。私はしたけど。

両方見ていく。

installutil でサービス登録

Watcher.csのデザイナーを開き、右クリックメニューから [インストーラーの追加]を選択。

f:id:vviilloovv:20181114133334p:plain

するとこんな感じでインストーラーが生成される。
例によって名前の末尾に1が付与されるため消す。

f:id:vviilloovv:20181114134223p:plain

"serviceProcessInstaller"を選択し、プロパティを設定する。
ここでは"Account"を"LocalSystem"とした。
規定値の"User"だと登録時にユーザー情報を入力しなければならないため少し面倒。
アカウントの種類に関しては以下の記事が参考になる。

www.atmarkit.co.jp

f:id:vviilloovv:20181114134626p:plain

続いて"serviceInstaller"のプロパティをいじる。

  • Description : サービスの説明。なんでもよさげ。
  • DisplayName : サービスの表示名。日本語可なので"Watcherサービス"とした。
  • ServiceName : こちらはシステムに登録される名前。日本語不可なので"Watcher"とした。
  • StartType : Automaticとした。再起動すると自動的に起動するようになる。

中身はないがこれで最低限の設定はOK。ビルドしてみる。

f:id:vviilloovv:20181114135624p:plain

うまくいったっぽい。

Windows サービスはこのままデバッグ実行しても起動できない。

f:id:vviilloovv:20181114135752p:plain

ので、サービスとして登録する。
installutilコマンドはVisual Studioをインストールしたときに一緒にインストールされるプログラムのため、"開発者コマンドプロンプト for VS 2017"を起動。

**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.8.5
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************

> cd (Debugフォルダ)

> installutil WatchService.exe

トランザクション インストールが完了しました。

って出たら成功。
サービスに登録されているはず。

f:id:vviilloovv:20181114141807p:plain

登録を解除する場合、/uオプションをつければ良い。

> installutil /u WatchService.exe

アンインストールか完了しました。

って出たら成功。ちなみに原文ママ
まさかこんなところで誤字を発見するとは…。

sc create でサービス登録

こっちの場合、上でつらつらと並べたようなインストーラーの設定は一切必要ない。

f:id:vviilloovv:20181114143154p:plain

インストーラーを消し去った。オォウwwwwwマッサラデスwwwwww

コマンドプロンプト管理者権限で起動し、以下のコマンドを実行。
※管理者権限で起動していない場合、アクセスが拒否されました。と出るので注意。

Microsoft Windows [Version 6.1.7601]  
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.  

> sc create Watcher binPath= (Dubug配下のexeファイルのパス) displayname= Watchサービス start= auto  

[SC] CreateService SUCCESS

と出たら成功。
説明が空白だけれど、まあテストだし問題あるまいて(登録方法がわかりませんでした)。

f:id:vviilloovv:20181114144647p:plain

sc createコマンドのオプションについては以下の記事が詳しい。

Sc.exe を使用して Windows サービスを作成する方法

サービス名と表示名を変えることで同じサービスを複数登録することもできる。
sc create Watcher2 binPath= (略) displayname= 監視サービス みたいな感じ。

登録解除はsc delete (サービス名) でOK。
[SC] DeleteService SUCCESSと出たら成功。
かんたーん。

…あれ?説明をどこか別の箇所でできるのであればsc createコマンドでよくない??
まあどちらでもサービスは登録できるのでいいか。

思ったより長くなった

ここからさらにフォルダ監視とログ出力を書くと結構な長さになるため、今回はここまで。次でとりあえず終わるはず。

ではまた。