基本は↓に書いてあるのだけど、所々間違っている?というか、バージョンアップあたりで動かなくなっているので、ポイントだけメモ書き。
Windows サービスで ASP.NET Core をホストします。
https://docs.microsoft.com/ja-jp/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-2.0&tabs=aspnetcore2x
https://github.com/aspnet/Docs/tree/master/aspnetcore/host-and-deploy/windows-service/sample
*.csprojでターゲットを.NET Frameworkにする
ASP.NET Core + .NET Core で作成したプロジェクト(*.csproj)を開いて、TargetFramework を「netcoreapp2.0」から「net461」に変える。
1 2 3 | < PropertyGroup > < TargetFramework >netcoreapp2.0</ TargetFramework > </ PropertyGroup > |
から
1 2 3 4 | < PropertyGroup > < TargetFramework >net461</ TargetFramework > < RuntimeIdentifier >win7-x64</ RuntimeIdentifier > </ PropertyGroup > |
に変更する。
これは Windows サービスを使うために .NET Framework に切り替えているので、Linux上で動かす場合は、netcoreapp2.0 で使うことになる。
NuGetパッケージを変更する
ASP.NET Core を使っているところを、.NET Core から .NET Framework のものに切り替える。あと「Microsoft.AspNetCore.Hosting.WindowsServices」を追加して、Windows サービスで起動するための RunAsService() を使えるようにしておく。
1 2 3 | < ItemGroup > < PackageReference Include = "Microsoft.AspNetCore.All" Version = "2.0.8" /> </ ItemGroup > |
から
1 2 3 4 5 | < ItemGroup > < PackageReference Include = "Microsoft.AspNetCore" Version = "2.0.3" /> < PackageReference Include = "Microsoft.AspNetCore.Mvc" Version = "2.0.4" /> < PackageReference Include = "Microsoft.AspNetCore.Hosting.WindowsServices" Version = "2.0.3" /> </ ItemGroup > |
Program.csを書き替える
ASP.NET Core + .NET Core の場合には、IWebHost インターフェースを使っているのだが、面倒なので、Main に書き替えてしまう。
1 2 3 4 5 6 7 8 9 10 11 12 | public class Program { public static void Main( string [] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost( string [] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); } |
から
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting.WindowsServices; public class Program { public static void Main( string [] args) { bool isService = false ; if (Debugger.IsAttached || args.Contains( "--console" )) { isService = false ; } if ( args.Contains( "--service" )) { isService = true ; } // パラメータを消しておく args = new string [] { }; if (isService) { // サービスで動作させる var pathToExe = Process.GetCurrentProcess().MainModule.FileName; var pathToContentRoot = Path.GetDirectoryName(pathToExe); var host = WebHost.CreateDefaultBuilder(args) .UseContentRoot(pathToContentRoot) .UseStartup<Startup>() .Build(); host.RunAsService(); } else { // コンソールアプリで起動する var host = WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseUrls($ "http://*:{port}" ) .Build(); host.Run(); } } } |
起動スイッチを付けて通常起動とサービスの起動に切り替えている。MSのサンプルでは、デフォルトでサービス起動になっているのだが、こちらは「–service」を付けたときだけ、Windows サービスで起動するようにしている。
WebHost.CreateDefaultBuilder に不要なパラメータを渡すと落ちるので、args の中身を消しておく(なんとなくバグ臭いのだが)。
サービスで起動する
サービスを登録するために sc コマンドを管理者権限のコマンドプロンプトで実行する。
1 | sc create UsbService binpath= "D:\work\SG\git\usbblocker\UsbBlocker.Web\bin\Debug\net461\win7-x64\UsbBlocker.Web.exe --service" |
binpath には、フルパスを指定する。スイッチを付けるためにダブルクォートで囲ってある。サービス名は UsbService としているが、ダブらないように自前で名前をつける。
サービスの起動は sc start でできる。
1 | sb start UsbBlockerService |
サービスを削除するときは sc delete する。
1 | sb delete UsbBlockerService |