【问题标题】:How create Windows Service from VS 2022 created gRPC server?如何从 VS 2022 创建的 gRPC 服务器创建 Windows 服务?
【发布时间】:2022-08-19 05:19:23
【问题描述】:

通过选择“ASP NET Core gRPC 服务”模板和 .Net 6 Core,我在 Visual Studio 2022 社区预览版中创建了一个 gRPC 服务器。我打算替换全部使用 WCF 的四个现有 .Net Framework Windows 服务。因此,我不是在寻找有关如何创建 Windows 服务的替代方法。

从 VS 2022 生成的代码创建了一个 program.cs(无 cmets),如下所示:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
var app = builder.Build();
app.MapGrpcService<GreeterService>();
app.MapGet(\"/\", () => \"Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909\");
app.Run();

我能找到的每个示例都与此 program.cs\ 的内容不匹配。此外,所有示例都包含生成的 startup.cs 文件。我的项目没有创建 startup.cs 文件。所有示例都显示,包括 NuGet 包 Microsoft.Extensions.Hosting.WindowsServices 和添加 UseWindowsServices 参数。

Host.CreateDefaultBuilder(args)
    .UseWindowsService()
    ...

我没有 Host 或 CreateDefaultBuilder 方法。我尝试添加该行:

builder.Host.UseWindowsService();

该程序在 VS 或命令行中运行时可以完美编译和运行。我可以使用 netstat 查看端口:

netstat -an | find \"6276\"
C:\\Users\\Steve>netstat -an | find \"6276\"
  TCP    127.0.0.1:6276         0.0.0.0:0              LISTENING
  TCP    [::1]:6276             [::]:0                 LISTENING

但是当我将它作为 Windows 服务运行时,它没有在识别的端口上侦听。

netstat -an | find \"6276\"
C:\\Users\\Steve>

我尝试了 .Net 6.0 和 .Net 7.0 preview 7,在后面选中和取消选中“不要使用顶级语句”。行为没有变化。

因此,显然 Visual Studio 更改了 gRPC 的模板输出,但还没有人使用它创建 Windows 服务……或者至少没有展示它是如何完成的。

有谁知道如何获取最新的 gRPC 模板并从中创建 Windows 服务?

  • ASP.NET Core 应用程序(包括 gRPC 服务器)应该托管在 Internet 信息服务器 (IIS) 中。它将提供您需要的所有 Windows 服务基础结构,并且随 Windows 一起提供。为什么不使用 IIS?
  • 来自 Microsoft:\“虽然 ASP.NET Core 6.0 应用程序可以托管在 Windows Server 上的 IIS 中,但目前无法在 IIS 中托管 gRPC 应用程序,因为某些 HTTP/2 功能不受支持\”
  • 那条线几岁了?
  • 不知道,但我在多个地方都见过它,而且我一直在到处寻找。还没有看到有人建议将其作为 IIS 的一部分。但我真的不希望它成为 IIS 的一部分,所以你能回答这个问题吗?
  • 尝试检查Event Viewer 以查找应用程序日志。配置windows服务主机时,会自动添加EventLogs provider。您可能还想配置调试日志级别。另外,如果你想得到一个普通的Main方法,在创建项目时检查Do not use top-level statements

标签: c# windows-services grpc


【解决方案1】:

这是一个由默认模板创建的最小应用程序的示例,几乎没有修改(参见代码 cmets)

项目文件

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" />
    <!-- Install additional packages -->
    <PackageReference Include="Grpc.AspNetCore.Server.Reflection" Version="2.40.0" />
    <PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
  </ItemGroup>

</Project>

程序.cs

using GrpcService1.Services;
using Microsoft.Extensions.Hosting.WindowsServices;

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

// Set WindowsServiceLifetime
builder.Host.UseWindowsService();

builder.Services.AddGrpc();

// Add reflection services
builder.Services.AddGrpcReflection();

var app = builder.Build();

app.MapGrpcService<GreeterService>();

// Map reflection endpoint
app.MapGrpcReflectionService();

app.Run();

现在在项目文件夹中打开cmd并执行

dotnet publish

publish 命令将生成 exe 文件(我假设您在 Windows 机器上工作,否则您将如何测试 Windows 服务??)。在我的机器上,exe 的路径是

"C:\github\junk\GrpcService1\bin\Debug\net6.0\publish\GrpcService1.exe"

现在打开 cmd 为行政人员并运行以下命令

sc.exe create "GrpcService" binpath="C:\github\junk\GrpcService1\bin\Debug\net6.0\publish\GrpcService1.exe"

打开Services 并启动GrpcService。现在安装并运行grpcui tool

grpcui -plaintext localhost:5000

grpcui 工具将打开 UI,您应该可以在其中看到 Greeter 服务

笔记:

  • 我使用了WebApplication.CreateBuilder(new WebApplicationOptions()),因为没有它,服务将无法启动。 Windows 事件查看器显示错误:

说明:进程因未处理的异常而终止。 异常信息:System.NotSupportedException:内容根已更改 从“C:\Windows\system32”到 “C:\github\junk\GrpcService1\bin\Debug\net6.0\publish”。改变 不支持使用 WebApplicationBuilder.Host 的主机配置。 请改用 WebApplication.CreateBuilder(WebApplicationOptions)。

找到解决方案here

  • 默认情况下,应用程序将在端口5000 上启动。如果要使用其他端口,请在创建服务时添加 --urls 参数
sc.exe create "GrpcService1" binpath="C:\github\junk\GrpcService1\bin\Debug\net6.0\publish\GrpcService1.exe --urls \"http://localhost:6276\""

【讨论】:

    猜你喜欢
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    相关资源
    最近更新 更多