netcore开发windows普通服务(非Web)并一键发布到服务器

如何开发并一键发布WindowsService项目(netcore普通项目)

netcore下开发windows服务如果是web项目的话,由于aspnetcore本身是支持的,把默认的host.Run改为host.RunAsService就可以了。

但是普通的netcore的控制台项目我终于找到了如下方式来实现:

1. 打开vs 选择创建一个新的netcore 控制台项目

Nuget添加如下引用

  1. Microsoft.Extensions.Hosting
  2. System.ServiceProcess.ServiceController

新建一个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();
        }
    }
}

一键发布到服务器,在工程上点击右键 然后选择 AntDeploy

AntDeploy是我开发的一款开源一键部署vs插件(也是支持脱离vs单独使用的一个开源工具)

开源地址:https://github.com/yuzd/AntDeployAgent

配置AntDeploy

添加一个环境 名字叫 测试 然后 在 测试环境里面添加 windows服务器 这里我做测试就添加就是我本机,注意Host里面是填写格式为:ip:端口号

注意:Token不是windows服务器的密码!!!是安装agent后,agent的配置文件里面配置的Token(你自己自定义配置的)
注意:Port不是你要发布的项目的端口号!!!是安装agent后,agent的配置文件里面配置的端口号(你自己自定义配置的)
点击【Connect Test】按钮进行确认agent可以成功链接,否则会发布失败
如果【Connect Fail】失败 请查看 #10

进入 WindowsService Tab界面

Sdk类型选择 netcore
ServiceName 填写上面我们设置的名称:[TestService]

点击 【Deploy】按钮进行发布

确认服务器无误 点击 【是】开始执行一键部署
如果发布出现错误会出现下图所示:

可以在Log里面查看失败原因是因为我部署agent没有用管路员权限 报权限不足失败 需要用管理员权限运行agent才行

部署成功 如下图:

查看D盘下是否log.txt是否正常每隔1秒写入了当前时间

这里演示的是windows服务上没有这个service
所以自动创建了。
如果service已存在的情况 Deploy 就会全量覆盖 不会重新创建site的。
如果想要覆盖时排除指定文件 可以在 Setting Tab界面的IgnoreList里面增加(支持正则)

原文地址:https://www.cnblogs.com/yudongdong/p/10630835.html

时间: 2024-11-04 12:07:31

netcore开发windows普通服务(非Web)并一键发布到服务器的相关文章

杂记3:VS使用Web Deploy一键发布网站到服务器

我的开发环境,win7 64位,使用VS2013: 服务器环境WinServer08 64位. 关于Web Deploy是什么,有什么优势,请参考其他文章,比如:Web Deploy自动部署 本文以step by step的方式说明如何配置服务器和本地开发环境,以实现一键发布网站: 以及过程中可能遇到的问题和解决方案. 步骤一:在服务器下载并安装Web Platform Installer 这里推荐通过Web Platform Installer来安装Web Deploy,下载地址:Web Pl

C#开发Windows Services服务--服务安装失败的解决办法

问题1:“System.Security.SecurityException:未找到源,但未能搜索某些或全部事件日志.不可访问的日志: Security.” 正在运行事务处理安装. 正在开始安装的“安装”阶段. 查看日志文件的内容以获得…\bin\Debug\Service2.exe程序集的进度. 该文件位于…\bin\Debug\Service2.InstallLog. 在“安装”阶段发生异常. System.Security.SecurityException:未找到源,但未能搜索某些或全部

windows环境下解决web服务假死的问题

最近在windows系统在部署web服务器,发现很不稳定.web服务有容易假死,改过配置换过各种web软件,如apache.nginx都不管用. 所以干脆做个简易的定时检测Web服务状态的软件.一旦web出现问题,就会执行自定义的操作,例如web进行重启. 检测的网址.检测时间.以及自定义的操作都可以根据需要自己修改. 软件地址: http://files.cnblogs.com/files/itevol/guard_Release.zip

C# 开发 Windows 服务 使用Log4net 组件 不能生成日志文件

使用VS2012开发Windows服务,需要使用Log4net日志组件记录业务情况,但是始终生成不了日志文件. 1 /// <summary> 2 /// 入口方法 3 /// </summary> 4 /// <param name="args">参数</param> 5 public static void Main(string[] args) 6 { 7 // 加载Log4net模块 8 LogHelper.SetConfig(&

EJB_开发EJB容器模型的WEB服务

开发EJB容器模型的WEB服务 WEB服务 Web服务也是一种分布式技术,它与EJB最大的不同是,Web服务属于行业规范,可以跨平台及语言.而EJB属于Java平台的规范,尽管理论上可以跨平台,但实现起来比较复杂,所以其应用范围局限在了Java平台.它们两者的偏重点不一样,Web服务偏重的是这个系统对外提供什么功能,而EJB偏重的是如何使用一个个组件组装这些功能.就好比一个硬盘,它对外提供的是存储服务,这是Web服务的关注点,对于怎样组装这个硬盘,怎样构造这些小零件,Web服务并不关心,但这些却

.net开发windows服务小结 (转发)

.net开发windows服务小结 今天学习了在.net下创建一个windows服务,总结一下学习心得. 开发环境:visual studio 2012 一.编写程序 (1)创建一个空解决方法 (2)添加一个控制台应用程序项目 (3)添加一个Windows服务,如下所示: (4)右键 查看代码 看到如下代码: public WindowsService() { InitializeComponent(); } protected override void OnStart(string[] ar

win7下用c#开发windows服务

1.首选我们需要打开VS2008,然后点击文件-->新建-->项目,选择Visual C#-->windows-->windows服务.如下图所示: 2.然后修改Service1.cs类. 我们需要重写OnStart和OnStop方法.代码如下所示: [csharp] view plaincopy using System; using System.Collections.Generic; using System.ComponentModel; using System.Dat

微软C#6.0语言OOP面向对象编程》《微软ASP.NET\MVC56网站开发》《微软Web服务\WCF\Web API3.0课程视频》

最新<微软C#6.0语言OOP面向对象编程><微软ASP.NET\MVC56网站开发><微软Web服务\WCF\Web API3.0课程视频>下载 下载链接:http://pan.baidu.com/s/1bnjJQnd 密码:36ji 微软与开源实战训练营QQ群:  203822816微软MSDN俱乐部QQ群:  29754721,

服务端web开发:PHP简介以及常见语法

服务端web开发 在讲解什么是服务端开发之前,让我们先思考几个问题 网站访问: 当我们做好了.html的网站,如何让别人(朋友,用户)可以访问到呢? 使用U盘拷贝,QQ发送文件等直接将文件共享的方式?---不灵活 将网站放在服务器上,让用户通过网址访问?---绝大多数网站的做法 网站内容更新: 如果用户每次访问我们的网站看到的内容都是一样的,在最初的新鲜劲过去以后估计就再也不想访问我们的网站了o(╯□╰)o,那么如何去更新网站的内容呢? 当有内容,图片,或者界面需要更新是,直接修改.html文件