天天看點

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

前言

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

将WEB應用作為服務運作

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

<TargetFramework>netcoreapp3.1</TargetFramework>
<OutputType>Exe</OutputType>           

我們隻需要添加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/