netcore开发windows普通服务(非Web)并一键发布到服务器
?如何开发并一键发布WindowsService项目(netcore普通项目)netcore下开发windows服务如果是web项目的话,由于aspnetcore本身是支持的,把默认的host.Run改为host.RunAsService就可以了。 但是普通的netcore的控制台项目我终于找到了如下方式来实现: 1. 打开vs 选择创建一个新的netcore 控制台项目? ? Nuget添加如下引用
? ? 新建一个ServiceBaseLifetime.cs 并将下面的内容复制进去public class ServiceBaseLifetime : ServiceBase,IHostLifetime { private readonly TaskCompletionSource _delayStart = new TaskCompletionSource(); public ServiceBaseLifetime(IApplicationLifetime applicationLifetime) { ApplicationLifetime = applicationLifetime ?? throw new ArgumentNullException(nameof(applicationLifetime)); } private IApplicationLifetime ApplicationLifetime { get; } public Task WaitForStartAsync(CancellationToken cancellationToken) { cancellationToken.Register(() => _delayStart.TrySetCanceled()); ApplicationLifetime.ApplicationStopping.Register(Stop); new Thread(Run).Start(); // Otherwise this would block and prevent IHost.StartAsync from finishing. return _delayStart.Task; } private void Run() { try { Run(this); // This blocks until the service is stopped. _delayStart.TrySetException(new InvalidOperationException("Stopped without starting")); } catch (Exception ex) { _delayStart.TrySetException(ex); } } public Task StopAsync(CancellationToken cancellationToken) { Stop(); return Task.CompletedTask; } // Called by base.Run when the service is ready to start. protected override void OnStart(string[] args) { _delayStart.TrySetResult(null); base.OnStart(args); } // Called by base.Stop. This may be called multiple times by service Stop,ApplicationStopping,and StopAsync. // That‘s OK because StopApplication uses a CancellationTokenSource and prevents any recursion. protected override void OnStop() { ApplicationLifetime.StopApplication(); base.OnStop(); } } ? 新建一个ServiceBaseLifetimeHostExtensions.cs 并将下面的内容复制进去public static class ServiceBaseLifetimeHostExtensions { public static IHostBuilder UseServiceBaseLifetime(this IHostBuilder hostBuilder) { return hostBuilder.ConfigureServices((hostContext,services) => services.AddSingleton<IHostLifetime,ServiceBaseLifetime>()); } public static void RunAsService(this IHostBuilder hostBuilder) { hostBuilder.UseServiceBaseLifetime().Build().Run(); } public static Task RunAsServiceAsync(this IHostBuilder hostBuilder) { return hostBuilder.UseServiceBaseLifetime().Build().RunAsync(CancellationToken.None); } } 新建一个服务类 TestService.cs 并写入以下内容(该服务就是每1秒往d:log.txt写入当前时间)public class TestService: IHostedService,IDisposable { readonly System.Timers.Timer tmBak = new System.Timers.Timer(); public TestService() { tmBak.Interval = 1000;//1秒执行1次 tmBak.AutoReset = true;//执行1次false,一直执行true tmBak.Enabled = true; tmBak.Elapsed += (sender,eventArgs) => { using (StreamWriter sw = new StreamWriter("D:log.txt",true)) { sw.WriteLine($"AntDeploy Windows服务:{DateTime.Now:yyyy-MM-dd HH:mm:ss}"); } }; } public Task StartAsync(CancellationToken cancellationToken) { tmBak.Start(); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { tmBak.Stop(); return Task.CompletedTask; } public void Dispose() { this.tmBak.Dispose(); } } 编辑 Program.cs 写入如下内容,保证既可以作为控制台打开又可以作为windows服务运行:class Program { // P/Invoke declarations for Windows. [DllImport("kernel32.dll")] static extern IntPtr GetConsoleWindow(); [DllImport("user32.dll")] static extern bool IsWindowVisible(IntPtr hWnd); public static bool HaveVisibleConsole() { return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? IsWindowVisible(GetConsoleWindow()) : Console.WindowHeight > 0; } private static async Task Main(string[] args) { var pathToExe = Process.GetCurrentProcess().MainModule.FileName; var pathToContentRoot = Path.GetDirectoryName(pathToExe); Directory.SetCurrentDirectory(pathToContentRoot); var isService = !(Debugger.IsAttached || args.Contains("--console")); if (HaveVisibleConsole()) isService = false; var builder = new HostBuilder() .ConfigureServices((hostContext,services) => { services.AddHostedService<TestService>(); }); if (isService) { await builder.RunAsServiceAsync(); } else { await builder.RunConsoleAsync(); } } } ? 一键发布到服务器,在工程上点击右键 然后选择 AntDeployAntDeploy是我开发的一款开源一键部署vs插件(也是支持脱离vs单独使用的一个开源工具) 开源地址:https://github.com/yuzd/AntDeployAgent ? ? 配置AntDeploy添加一个环境 名字叫 测试 然后 在 测试环境里面添加 windows服务器 这里我做测试就添加就是我本机,注意Host里面是填写格式为:ip:端口号? ?注意:Token不是windows服务器的密码!!!是安装agent后,agent的配置文件里面配置的Token(你自己自定义配置的) ? 进入 WindowsService Tab界面Sdk类型选择 netcore ? 点击 【Deploy】按钮进行发布 确认服务器无误 点击 【是】开始执行一键部署 ? 可以在Log里面查看失败原因是因为我部署agent没有用管路员权限 报权限不足失败 需要用管理员权限运行agent才行 ? ?部署成功 如下图: ? ?查看D盘下是否log.txt是否正常每隔1秒写入了当前时间 这里演示的是windows服务上没有这个service所以自动创建了。如果service已存在的情况 Deploy 就会全量覆盖 不会重新创建site的。如果想要覆盖时排除指定文件 可以在 Setting Tab界面的IgnoreList里面增加(支持正则) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows – 如何获取包含我的应用程序创建的所有线程的列表
- 当通过LoadLibrary调用DLL时,MFC状态无效
- NodeJS基础API-path相关的问题basename,extname,dirname,pa
- windows-server-2008 – IIS FTP 7.5用户帐户如何工作?
- windows-server-2008 – 忽略主机文件的Squid代理服务器:(
- win10专业版激活方法——亲测可行!!!
- Windows Phone 8 – GetGeopositionAsync不返回
- 保护用户的Windows计算机
- windows – 是否有格式说明符总是表示使用_tprintf的字符串
- 在现有2008R2中添加Windows Server 2012 DC而不更新架构