ASP.NET Core Web程式託管到Windows 服務

  • 2020 年 2 月 24 日
  • 筆記

前言

在 .NET Core 3.1和WorkerServices構建Windows服務 我們也看到了,如何將workerservices構建成服務,那麼本篇文章我們再來看看如何將web應用程式託管到我們的服務中.

將WEB應用作為服務運行

我們需要將我們的WEB應用程式編譯成exe文件,在ASP.NETCore中其實這是一個很簡單的過程,我們只需要修改.csproj即可。正如下面程式碼片段

<Project Sdk="Microsoft.NET.Sdk.Web">    <PropertyGroup>      <TargetFramework>netcoreapp3.1</TargetFramework>      <OutputType>Exe</OutputType>    </PropertyGroup>  </Project>

我們只需要添加OutputType即可.

接著來我們需要安裝Microsoft.Extensions.Hosting.WindowsServices到我們的WEB應用程式中,如下所示:

Install-Package Microsoft.Extensions.Hosting.WindowsServices

現在我們需要在Program.cs中的CreateDefaultBuilder方法中進行擴展UseWindowsService

    public class Program      {          public static void Main(string[] args)          {              CreateHostBuilder(args).Build().Run();          }            public static IHostBuilder CreateHostBuilder(string[] args) =>              Host.CreateDefaultBuilder(args)                  .ConfigureWebHostDefaults(webBuilder =>                  {                      webBuilder.UseStartup<Startup>();                  }).UseWindowsService();      }

上述程式碼中我們已經操作完了….

部署服務

我們還需要做的是部署到我們的服務中.

以管理員身份打開命令提示符,然後在項目文件夾中運行以下命令以發布項目:

dotnet publish -c Release

接下來,我們可以使用標準Windows服務命令將exe作為服務安裝。因此,將命令提示符移動到輸出文件夾(可能沿著myprojectbinReleasenetcoreapp3.1publish)。並運行類似的內容以作為服務安裝:

sc create ASPNETCoreWindowsService binPath=ASPNETCoreWindowsService.exe

當然我們也可以停止和刪除該服務

sc.exe stop ASPNETCoreWindowsService  sc.exe delete ASPNETCoreWindowsService 

獨立部署

將Web App作為Windows服務運行的全部原因是,我們不必在電腦上安裝其他工具。但這隻有在我們進行所謂的獨立部署時才有效。這意味著我們將應用程式所需的一切部署在發布文件夾中,而不必在目標電腦上安裝.NET Core運行時。

我們需要做的就是運行我們的dotnet release命令,其中包含一些額外的標誌:

dotnet publish -c Release -r win-x64 --self-contained

這告訴.NET Core SDK我們要以獨立形式發布,並且適用於Windows。

您的輸出路徑將從binReleasenetcoreapp3.0publish 更改為binRelease netcoreapp3.0win-x64publish

您還將注意到此新輸出目錄中的大量文件以及該文件夾的一般大小。但是,考慮到這一點,是的,我們正在部署整個運行時,因此它應該很大。

Content Root

我快速瀏覽了UseWindowsService的調用在此處的實際源程式碼。我注意到的是,它專門為在Windows Service下運行的內容設置了根目錄。我想知道如果以Windows服務運行時從應用程式內的磁碟讀取本地文件怎麼辦?通常我只會寫類似:

File.ReadAllText("myfile.json");

但是……顯然,在WindowsService上下文中運行時有一些特殊之處。所以我嘗試了一下,我的程式異常了。我不得不檢查機器上的事件查看器,發現:

Exception Info: System.IO.FileNotFoundException: Could not find file 『C:WINDOWSsystem32myfile.json』.

因此,當作為Windows服務運行時,我的應用程式的」根」認為它位於System32內。再次查看Microsoft的源程式碼可以找到解決方案。我可以簡單地使用它們設置內容根目錄的相同方法,以從正確的位置載入我的文件:

File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "myfile.json"));

Reference

https://github.com/hueifeng/BlogSample/tree/master/src/ASPNETCoreWindowsService

https://dotnetcoretutorials.com/2019/12/21/hosting-an-asp-net-core-web-app-as-a-windows-service-in-net-core-3/

Tags: