🈂️

WinSWで任意のexeをWindowsサービス化する方法について

2024/01/20に公開

概要

この記事では、WinSWを用いてnginx、或いは任意のプログラムをWindowsサービス化する方法を説明します。

WinSW(Windows Service Wrapper) とは、任意のプログラムやバッチをWindowsサービスとして登録できるようにするためのラッパープログラムです。
https://github.com/winsw/winsw

経緯

現在(2024年)までメンテナンスされているオープンソースの中でも比較的つかいやすいのでnginxのために使い方を勉強しようと思ったのですが、検索した記事がディレクトリ配置や設定内容が古かったりいまいち好みでないことが多かったので記事を書くことにしました。

ターゲット

  • nginxを使用する度に実行ファイル(enginx.exe)を直接、あるいはバッチで起動している方
  • nginxをタスクスケジューラで起動しているが、他の方法を検討したい方

今回はnginxを例にしますがnginx以外のプログラムでもサービス化は可能なので、適時読み替えながら参考にしてみてください。

ゴール

  • nginxがWindowsサービスで開始、終了することができるようにする

用意するもの

  • WinSW(v2.12)
    今回はWindows 11 proにインストールしたので、WinSW-x64.exeを用意。
    同一バージョンであれば別の実行ファイルでも問題はないと思われます。
  • nginx
    今回は執筆時安定板のバージョン1.24.0を使用したましたが、今回の主役ではないのでバージョンにはこだわりません。

WinSWを使用するための準備

nginxとWinSWのセットは任意のフォルダ(📂 . )にインストールしても構いませんが、私は「D:\service\nginx」をルートとする次のフォルダ配置にしました。

フォルダ配置
📂 . (例:D:\service\nginx)
├── 📂nginx-1.xx.x
│   └── nginx.exe
├── 📂WinSW
│   ├── 📂logs
│   ├── install.bat
│   └── uninstall.bat
├── WinSW-nginx.exe
└── WinSW-nginx.xml

「D:\service」には、nginxのようにサービス化したいアプリケーションを並べていこうかと考えています。

📂nginx-1.xx.x

nginxをインストールしたフォルダ、ダウンロードしたnginxを解凍したまま置きました。
「用意するもの」のnginxを使用した場合は「nginx-1.24.0」というフォルダ名になります。
内部のディレクトリ構造については割愛しますが、このフォルダを作業ディレクトリとして指定をするのでこのフォルダ直下にnginx.exeが存在することを確認してください。

📂WinSW

WinSWの関連ファイルを保管するフォルダです。
中には出力したログや、WinSWを操作するためのバッチを置いていきます。

📂logs

サービスの実行ログ、エラーログが格納されるフォルダです。
nginxのログ(アクセスログなど)はnginxで設定する必要があり、今回はここに出力されないので注意してください。

install.bat(インストールバッチ)

WinSWでラッパーしたサービスをインストールするためのバッチです。

install.bat
@echo off
pushd %~dp0\..\
setlocal

WinSW-nginx.exe install

endlocal
popd
exit /b

文字コードはShift_JISを指定して作成してください。

使い勝手を重視しているのでシンプルに。
pushdはcdに変更しても構いませんが、WinSW-nginx.exeの配置されているパスをカレントディレクトリにする必要があります。

uninstall.bat(アンインストールバッチ)

WinSWでラッパーしたサービスをアンインストールするためのバッチです。

uninstall.bat
@echo off
pushd %~dp0\..\
setlocal

WinSW-nginx.exe uninstall

endlocal
popd
exit /b

文字コードはShift_JISを指定して作成してください。

install.batとの差異は、WinSW-nginx.exeの起動引数です。

install.batとuninstall.batの違い
- WinSW-nginx.exe install
+ WinSW-nginx.exe uninstall

WinSW-nginx.exe

WinSW-x64.exeをリネームした実行ファイルです。
名称の変更は必須ではないのですが、ルートに置くプログラムはなるべくサービスにしたいプログラムに近しい名称にしたかったので変更しています。

WinSW-nginx.xml(WinSW設定ファイル)

WinSWの設定ファイルです。
WinSW-nginx.exeと必ず同じ名前にしてください。

WinSW-nginx.xml
<service>
    <id>nginx</id>
    <name>nginx (powered by WinSW)</name>
    <description>HTTPサーバー</description>
    
    <workingdirectory>%BASE%\nginx-1.24.0</workingdirectory>
    
    <executable>%BASE%\nginx-1.24.0\nginx.exe</executable>
    <startarguments></startarguments>
    <stoparguments>-s stop</stoparguments>
    
    <logpath>%BASE%\WinSW\logs</logpath>
    <log mode="roll-by-time">
        <pattern>yyyyMMdd</pattern>
        <keepFiles>8</keepFiles>
    </log>
</service>

文字コードはUTF-8を指定して作成してください。

設定値について

設定ファイルは環境にあわせて変更することが可能です。

id

設定必須
サービスの固有ID。今回は簡単にnginxとしたがパソコンに登録されているサービス全体でユニークである必要があるので、「nginx-1234567890」などのようにランダムの文字列をつけているのが安全かもしれません。

name, description

設定必須
サービス一覧で表示される名前(name)、説明(description)。
どちらもマルチバイト文字、つまり日本語文字の使用が可能です[^4]。nameはサービス全体でユニークである必要がありますが、後でみてもわかりやすく他者にとっても混乱をしない名称を設定することをおすすめします。
サービス

workingdirectory

サービスが認識する作業ディレクトリ。nginxをインストールしているフォルダを設定してください。
なお、変数「%BASE%」はインストールバッチで実行中のカレントディレクトリ(pushdで移動したフォルダ)を参照しているので、混同しないように注意です。

executable

設定必須
サービスで実行する実行ファイルのパス(executable)。
記事によってはサービス終了時に実行する実行ファイルのパス(stopexecutable)を指定している場合がありますが、同一の実行ファイルを起動する限りは設定不要です。

startarguments, stoparguments

サービスの起動引数(startarguments)、サービスの停止引数(stoparguments)。タグ名は複数系であることに注意してください(旧バージョンでは単数形だったようです)。
引数は半角スペースでつないで指定します。

log, logpath

サービスのログを出力する方法(log)、その出力先(logpath)。
今回は「日付毎に8ファイルまで」出力するようにしました。大体のログはこの設定で問題はないと思われますが、出力しない場合など他の設定方法については下記を参考にしてください。
https://github.com/winsw/winsw/blob/v3/docs/logging-and-error-reporting.md

サービスのインストール、アンインストール

インストールをする場合はinstall.batを、アンインストールをする場合はuninstall.batを管理者実行してください。
設定ファイル(WinSW-nginx.xml)を修正した場合は、都度再インストールをする必要があります。

以上でnginxのサービス化は完了です。

参考にした記事

nginxをWinSWでサービス化する手法について

各記事は古いために設定ファイルのタグが現在サポートされていなかったりするので注意。
https://qiita.com/sugasaki/items/83542f5614bc54a9475f
https://cointoss.hatenablog.com/entry/2017/03/06/125442
https://qiita.com/___ihabo/items/0787cccc4e4ee3b511e5

WinSWの起動引数について

https://stackoverflow.com/questions/75580185/how-to-use-environment-variable-into-winsw-xml-configuration
https://github.com/winsw/winsw/issues/1015

Discussion