.NET Core 2.2 的 Windows 服务中的 ASP.NET Core。对现有 ASP.NET Core 项目进行以下更改以将应用作为服务运行:
要求:PowerShell 6.2 or later
依赖框架的部署 (FDD):
依赖于框架的部署 (FDD) 依赖于目标系统上是否存在共享系统范围的 .NET Core 版本。当 FDD 场景与 ASP.NET Core Windows 服务应用程序一起使用时,SDK 会生成一个可执行文件 (*.exe),称为依赖于框架的可执行文件。
将 Windows Runtime Identifier (RID) 添加到包含目标框架的 <PropertyGroup>。在以下示例中,RID 设置为win7-x64。将 <SelfContained> 属性集添加到 false。这些属性指示 SDK 为 Windows 生成可执行 (.exe) 文件。
通常在发布 ASP.NET Core 应用程序时生成的 web.config 文件对于 Windows 服务应用程序来说是不必要的。要禁用 web.config 文件的创建,请将 <IsTransformWebConfigDisabled> 属性集添加到 true。
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>
自包含部署 (SCD):
自包含部署 (SCD) 不依赖于目标系统上是否存在共享组件。运行时和应用程序的依赖项与应用程序一起部署到托管系统。
确认存在Windows Runtime Identifier (RID) 或将RID 添加到包含目标框架的<PropertyGroup>。通过将 <IsTransformWebConfigDisabled> 属性集添加到 true 来禁用 web.config 文件的创建。
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
<IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>
Program.Main
public class Program
{
public static void Main(string[] args)
{
var isService = !(Debugger.IsAttached || args.Contains("--console"));
if (isService)
{
var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
var pathToContentRoot = Path.GetDirectoryName(pathToExe);
Directory.SetCurrentDirectory(pathToContentRoot);
}
var builder = CreateWebHostBuilder(
args.Where(arg => arg != "--console").ToArray());
var host = builder.Build();
if (isService)
{
// To run the app without the CustomWebHostService change the
// next line to host.RunAsService();
host.RunAsCustomService();
}
else
{
host.Run();
}
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddEventLog();
})
.ConfigureAppConfiguration((context, config) =>
{
// Configure the app here.
})
.UseStartup<Startup>();
}
发布依赖于框架的部署 (FDD):
dotnet publish --configuration Release --output c:\svc
发布自包含部署 (SCD)
必须在项目文件的<RuntimeIdenfifier>(或<RuntimeIdentifiers>)属性中指定 RID。为dotnet publish 命令的-r|--runtime 选项提供运行时。
dotnet publish --configuration Release --runtime win7-x64 --output c:\svc
通过管理 PowerShell 6 命令外壳使用 icacls 命令授予对应用文件夹的写入/读取/执行访问权限。
icacls "{PATH}" /grant "{USER ACCOUNT}:(OI)(CI){PERMISSION FLAGS}" /t
- {PATH} – 应用文件夹的路径。
- {USER ACCOUNT} – 用户帐户 (SID)。
- (OI) – 对象继承标志将权限传播到下级
文件。
- (CI) – 容器继承标志将权限传播到
下级文件夹。
- {PERMISSION FLAGS} – 设置应用程序的访问权限。
- 写入 (W)
- 读取 (R)
- 执行 (X)
- 全(女)
- 修改(M)
- /t – 递归应用到现有的从属文件夹和文件。
命令:
icacls "c:\svc" /grant "ServiceUser:(OI)(CI)WRX" /t
使用RegisterService.ps1 PowerShell 脚本注册服务。在管理 PowerShell 6 命令 shell 中,使用以下命令执行脚本:
.\RegisterService.ps1
-Name MyService
-DisplayName "My Cool Service"
-Description "This is the Sample App service."
-Exe "c:\svc\SampleApp.exe"
-User Desktop-PC\ServiceUser
使用Start-Service -Name {NAME} PowerShell 6 命令启动服务。
Start-Service -Name MyService
处理启动和停止事件
internal class CustomWebHostService : WebHostService
{
private ILogger _logger;
public CustomWebHostService(IWebHost host) : base(host)
{
_logger = host.Services
.GetRequiredService<ILogger<CustomWebHostService>>();
}
protected override void OnStarting(string[] args)
{
_logger.LogInformation("OnStarting method called.");
base.OnStarting(args);
}
protected override void OnStarted()
{
_logger.LogInformation("OnStarted method called.");
base.OnStarted();
}
protected override void OnStopping()
{
_logger.LogInformation("OnStopping method called.");
base.OnStopping();
}
}
扩展方法:
public static class WebHostServiceExtensions
{
public static void RunAsCustomService(this IWebHost host)
{
var webHostService = new CustomWebHostService(host);
ServiceBase.Run(webHostService);
}
}
程序.Main:
host.RunAsCustomService();
将内容根路径设置为应用的文件夹:
程序.Main:
var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
var pathToContentRoot = Path.GetDirectoryName(pathToExe);
Directory.SetCurrentDirectory(pathToContentRoot);
CreateWebHostBuilder(args)
.Build()
.RunAsService();
来源:
https://github.com/aspnet/AspNetCore.Docs/tree/master/aspnetcore/host-and-deploy/windows-service/
https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-2.2