• 踩坑 Windows 服务来宿主 .NET 程序


    本文所指的 .NET 程序为 .NET6 的程序。因为 .NET 的版本更新很快,所以方式、方法也有变化,所以网上搜到的方法有些也过时了。以下是最近我实践下来的一点心得(坑)。
    上一篇说到 不安装运行时运行 .NET 程序 后我们的程序已经只有一个 dll/exe 了,但是在 windows 上运行的时候会是一个控制台程序,很容易人不小心关闭了。所以想着把我们的程序部署成 windows 服务,这样不会误关,重启服务器的时候也会自动启动。所以最近折腾了一下把 .NET 程序,特别是 ASP.NET Core 程序部署为 windows 服务。本来以为网上随便搜一搜就很容易,事实上没想得这么美好。

    Worker Service#

    如果你的服务只想执行一些后台任务,比如定时任务,并不提供网站的服务。那么使用 Worker service 项目模板新建一个项目是最合适的。

    新建完项目后使用 nuget 安装:

    Microsoft.Extensions.Hosting.WindowsServices
    

    修改 program.cs 文件

    using WorkerService1;
    
    IHost host = Host.CreateDefaultBuilder(args)
        .UseWindowsService()
        .ConfigureServices(services =>
        {
            services.AddHostedService();
        })
        .Build();
    
    await host.RunAsync();
    

    其中就只添加一句 UseWindowsService 就可以了。
    编译之后使用 sc 命令就可以注册为服务了。

    sc create "wsTest" binPath=wsTest.exe
    sc start "wsTest"
    pause
    

    我们把它写成一个 bat 文件方便执行。使用管理权限运行这个 bat 文件服务会被注册并且直接运行:

    ASP.NET Core#

    以上尝试了一下 worker service 模式注册为服务,感觉简单的很。但是下面把 ASP.NET Core 程序注册为服务的时候就没那么简单啦。我查了一些文章,写的时间有些早了,所以还是安照微软官方的文档 Host ASP.NET Core in a Windows Service 的提示来操作。这篇文章虽然叫 Host ASP.NET Core in a Windows Service ,但其实里面的内容说的是上面的 worker service 。当按照上面的步骤尝试把 asp.net core 程序部署为服务的时候死活起不来,一直报未找到文件的异常。
    我们新建一个最简单的 asp.net core 程序来演示一下:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddRazorPages();
    
    builder.Host.UseWindowsService();
    
    var app = builder.Build();
    
    app.UseStaticFiles();
    app.UseRouting();
    await app.RunAsync();
    

    这是一个最简单的 asp.net core razor pages 程序。我们按照文档安装扩展包:

    Microsoft.Extensions.Hosting.WindowsServices
    

    然后调用 UseWindowsService 方法

    builder.Host.UseWindowsService();
    

    同样使用 sc 命令注册为服务并运行它。很遗憾它会报错。

    经过多种尝试方法都不行。最后翻了一下微软仓库里的 sample 代码才发现原来他们自己的 sample 代码里多了几行代码 。

    注意下面的代码了啊 !!!

    在构建 builder 的时候需要多传几个参数:

    var options = new WebApplicationOptions
    {
        Args = args,
        ContentRootPath = WindowsServiceHelpers.IsWindowsService() ? AppContext.BaseDirectory : default
    };
    var builder = WebApplication.CreateBuilder(options);
    

    只要使用这段代码来构建 builder ,服务就可以顺利的运行起来。根据以往的经验,可能还是作为服务运行的时候程序根目录的问题,通过以上方法来指定 AppContext.BaseDirectory 来作为程序的根目录,不然就有可能被定位到 system32 目录下。
    吐槽。。。虽然解决方案很简单,但是微软没有在文档里把这么关键的代码给些出来,着实有点坑啊,辛亏现在代码都在 github 上,很容易翻到,不然得折腾死人。

    PS#

    就在今天2022/09/02微软的英文文档已经更新了示例代码,中文版还没更新:
    https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-6.0&tabs=visual-studio#app-configuration-1

    关注我的公众号一起玩转技术#

  • 相关阅读:
    你做什么工作?
    算法——前缀和之除自身以外数组的乘积、和为K的子数组、和可被K整除的子数组、连续数组、矩阵区域和
    1 | Nessus使用
    计算机毕业设计ssm+vue+elementUI服装定制系统
    Java开发学习(四十八)----MyBatisPlus删除语句之逻辑删除
    python find函数
    C# 替换字符串最后一个逗号为分号
    Codeforces Round 924 (Div. 2)---->B. Equalize
    基于motoharw平台的电机控制策略模型simulink仿真实现
    HarmonyOS系统中内核实现MQTT协议开发的方法
  • 原文地址:https://www.cnblogs.com/kklldog/p/host-net-on-windows-service.html