基本は↓に書いてあるのだけど、所々間違っている?というか、バージョンアップあたりで動かなくなっているので、ポイントだけメモ書き。
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」に変える。
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
から
<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() を使えるようにしておく。
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.8" />
</ItemGroup>
から
<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 に書き替えてしまう。
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
から
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 コマンドを管理者権限のコマンドプロンプトで実行する。
sc create UsbService binpath="D:\work\SG\git\usbblocker\UsbBlocker.Web\bin\Debug\net461\win7-x64\UsbBlocker.Web.exe --service"
binpath には、フルパスを指定する。スイッチを付けるためにダブルクォートで囲ってある。サービス名は UsbService としているが、ダブらないように自前で名前をつける。
サービスの起動は sc start でできる。
sb start UsbBlockerService
サービスを削除するときは sc delete する。
sb delete UsbBlockerService
