在.NET Core中并没有像 .NET Framework下的 "windows服务"可创建,但我们依然可以通过powershell这个工具,将.NET CORE 下创建的项目以"windows服务"的形式来寄宿运行。
0.新建项目
新建、使用一个 web 应用程序 项目即可
本次示例所用 .NET CORE 版本为 2.1
项目结构如下:
1.修改项目csproj,增加RuntimeIdentifiers和IsTransformWebConfigDisabled
1 2 3 4 5 <PropertyGroup > <TargetFramework > netcoreapp2.1</TargetFramework > <RuntimeIdentifiers > win10-x64;win81-x64</RuntimeIdentifiers > <IsTransformWebConfigDisabled > true</IsTransformWebConfigDisabled > </PropertyGroup >
1 <RuntimeIdentifiers > win10-x64;win81-x64</RuntimeIdentifiers >
2.添加包引用:
Microsoft.AspNetCore.Hosting.WindowsServices
Microsoft.Extensions.Logging.EventLog -------为了启用 windows事件日志
启用 windows日志 start
创建一个自定义类,继承自 WebHostService ,用来重写 onstarting 等事件
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 public class MqWebHostService : WebHostService { private ILogger _logger; public MqWebHostService (IWebHost host ) : base (host ) { _logger = host.Services .GetRequiredService<ILogger<MqWebHostService>>(); } 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(); } }
创建一个 IHost 的扩展方法,用来运行自定义的服务:MqWebHostService
1 2 3 4 5 6 7 8 public static class WebHostServiceExtensions { public static void RunAsCustomService (this IWebHost host ) { var webHostService = new MqWebHostService(host); ServiceBase.Run(webHostService); } }
3.修改 Program.Main 方法:
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 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) { host.RunAsCustomService(); } else { host.Run(); } } public static IWebHostBuilder CreateWebHostBuilder (string [] args ) { var hostingConfig = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("hostsettings.json" , optional: true ) .Build(); return WebHost.CreateDefaultBuilder(args) .ConfigureLogging((hostingContext, logging) => { logging.SetMinimumLevel(LogLevel.Trace); logging.AddFilter("System" , LogLevel.Warning); logging.AddFilter("Microsoft" , LogLevel.Warning); if (Environment.OSVersion.Platform == PlatformID.Unix) { logging.AddLog4Net("log4net.linux.config" ); } else { logging.AddLog4Net(); } }) .ConfigureAppConfiguration((context, config) => { }) .UseConfiguration(hostingConfig) .UseStartup<Startup>() ; } }
4.发布
1 使用 dotnet public -c release 进行
1 dotnet public -c release -r win81-x64
7.使用 powershell 注册 windows 服务:
需要 6.1.3 或以上版本,下载:https://github.com/PowerShell/PowerShell/releases
以下使用 localservice 这个系统服务作为用户名进行注册服务。
1 New-Service -Name "MqConsumerForMemberCenter" -BinaryPathName "D:\Services\MemberCenterMqConsumer\SanbenTech.MC.Mq.Subscriber.exe" -Description "会员中心消息队列 Consumer,定位用户使用小程序时的区域" -DisplayName "MqConsumerForMemberCenter" -StartupType Automatic
删除服务:
1 remove-service -Name "MqConsumerForMemberCenter"
也可以做成一个批处理,如下:
registerService.ps1
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 param( [Parameter(mandatory=$true )] $Name , [Parameter(mandatory=$true )] $DisplayName , [Parameter(mandatory=$true )] $Description , [Parameter(mandatory=$true )] $Path , [Parameter(mandatory=$true )] $Exe , [Parameter(mandatory=$true )] $User ) $cred = Get-Credential -Credential $User $acl = Get-Acl $Path $aclRuleArgs = $cred .UserName, "Read,Write,ReadAndExecute" , "ContainerInherit, ObjectInherit" , "None" , "Allow" $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $aclRuleArgs $acl .SetAccessRule($accessRule )$acl | Set-Acl $Path New-Service -Name $Name -BinaryPathName "$Path \$Exe" -Credential $cred -Description $Description -DisplayName $DisplayName -StartupType Automatic
如果需要用其他用户来管理服务,则可以:
1.新建用户
1 2 3 4 5 6 net user {mcRabbitMqSubscriber} {mypwd} /add /expires:never net localgroup {GROUP} {USER ACCOUNT} /add net user {user account} /delete
2.给用户赋予权限:作为服务登录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 icacls "{PATH}" /grant "{USER ACCOUNT}:(OI)(CI){PERMISSION FLAGS}" /t icacls "X:\publish" /grant “mcRabbitMqSubscriber:(OI)(CI)WRX” /t
3.调整注册服务
registerService.ps1
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 param( [Parameter(mandatory=$true )] $Name , [Parameter(mandatory=$true )] $DisplayName , [Parameter(mandatory=$true )] $Description , [Parameter(mandatory=$true )] $Path , [Parameter(mandatory=$true )] $Exe , [Parameter(mandatory=$true )] $User ) $cred = Get-Credential -Credential $User $acl = Get-Acl $Path $aclRuleArgs = $cred .UserName, "Read,Write,ReadAndExecute" , "ContainerInherit, ObjectInherit" , "None" , "Allow" $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $aclRuleArgs $acl .SetAccessRule($accessRule )$acl | Set-Acl $Path New-Service -Name $Name -BinaryPathName "$Path \$Exe" -Credential $cred -Description $Description -DisplayName $DisplayName -StartupType Automatic
参考:
https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-2.1
https://docs.microsoft.com/zh-cn/powershell/scripting/learn/using-familiar-command-names?view=powershell-6