简体   繁体   English

如何从 VS 2022 创建的 gRPC 服务器创建 Windows 服务?

[英]How create Windows Service from VS 2022 created gRPC server?

I've created a gRPC server in Visual Studio 2022 Community Preview by selecting the "ASP NET Core gRPC Service" template and.Net 6 Core.我通过选择“ASP NET Core gRPC Service”模板和 .Net 6 Core 在 Visual Studio 2022 Community Preview 中创建了一个 gRPC 服务器。 I intend to replace four existing.Net Framework Windows services who are all using WCF.我打算替换四个现有的.Net Framework Windows 服务,它们都使用 WCF。 So, I'm not looking for an alternative on how to create a Windows service.因此,我不是在寻找有关如何创建 Windows 服务的替代方法。

The code generated from VS 2022 creates a program.cs (sans comments) that looks like:从 VS 2022 生成的代码创建了一个 program.cs(无注释),如下所示:

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();

Every example I can find does not match this program.cs's contents.我能找到的每个示例都与这个 program.cs 的内容不匹配。 Additionally, all the examples include a generated startup.cs file.此外,所有示例都包含生成的 startup.cs 文件。 My project did not create a startup.cs file.我的项目没有创建 startup.cs 文件。 All the examples show including the NuGet package Microsoft.Extensions.Hosting.WindowsServices and adding a UseWindowsServices parameter.所有示例都显示,包括 NuGet package Microsoft.Extensions.Hosting.WindowsServices 并添加 UseWindowsServices 参数。

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

I don't have a Host or a CreateDefaultBuilder method.我没有 Host 或 CreateDefaultBuilder 方法。 I tried adding the line:我尝试添加该行:

builder.Host.UseWindowsService();

The program compiles and works perfectly when running in VS or the command line.该程序在 VS 或命令行中运行时可以完美编译和运行。 I can see the ports with netstat:我可以使用 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

But when I run it as a Windows Service, it is not listening on the identified port.但是当我将它作为 Windows 服务运行时,它没有在识别的端口上监听。

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

I tried.Net 6.0 and.Net 7.0 preview 7, checking and unchecking "Do not use top level statements" on the later.我试过 .Net 6.0 和 .Net 7.0 preview 7,在后面勾选和取消勾选“Do not use top level statements”。 No change in the behavior.行为没有变化。

So, apparently Visual Studio changed the template output for gRPC and nobody has created a Windows Service with it yet... or at least has not shown how it was done.因此,显然 Visual Studio 更改了 gRPC 的模板 output 并且没有人使用它创建 Windows 服务......或者至少没有显示它是如何完成的。

Does anyone know how to take the latest gRPC template and create a Windows Service from it?有谁知道如何获取最新的 gRPC 模板并从中创建 Windows 服务?

Here is an example of the minimal application created by the default template with a few modifications (see code comments)这是一个由默认模板创建的最小应用程序的示例,并进行了一些修改(参见代码注释)

The project file项目文件

<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>

The Program.cs程序.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();

Now open cmd in the project folder and execute现在打开项目文件夹中的 cmd 并执行

dotnet publish

The publish command will produce the exe file (I assume you are working on a Windows machine, otherwise how would you test Windows Service? ). publish命令将生成exe文件(我假设您正在使用 Windows 机器,否则您将如何测试 Windows 服务?)。 On my machine the path to exe is在我的机器上, exe的路径是

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

Now open cmd as Administrator and run the following command现在以管理员身份打开 cmd 并运行以下命令

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

Open Services and start the GrpcService .打开Services并启动GrpcService Now install and run grpcui tool :现在安装并运行grpcui 工具

grpcui -plaintext localhost:5000

The grpcui tool will open the UI where you should be able to see the Greeter service grpcui 工具将打开 UI,您应该可以在其中看到 Greeter 服务在此处输入图像描述

Notes:笔记:

  • I Used WebApplication.CreateBuilder(new WebApplicationOptions()) because without that the service won't start.我使用了WebApplication.CreateBuilder(new WebApplicationOptions())因为没有它,服务将无法启动。 The Windows Event Viewer shows the error: Windows 事件查看器显示错误:

Description: The process was terminated due to an unhandled exception.说明:进程因未处理的异常而终止。 Exception Info: System.NotSupportedException: The content root changed from "C:\Windows\system32" to "C:\github\junk\GrpcService1\bin\Debug\net6.0\publish".异常信息:System.NotSupportedException:内容根从“C:\Windows\system32”更改为“C:\github\junk\GrpcService1\bin\Debug\net6.0\publish”。 Changing the host configuration using WebApplicationBuilder.Host is not supported.不支持使用 WebApplicationBuilder.Host 更改主机配置。 Use WebApplication.CreateBuilder(WebApplicationOptions) instead.请改用 WebApplication.CreateBuilder(WebApplicationOptions)。

Found the solution here .这里找到了解决方案。

  • By default, the application will start on port 5000 .默认情况下,应用程序将在端口5000上启动。 If you wish to use another port add --urls argument when creating the service如果您希望在创建服务时使用另一个端口添加--urls参数
sc.exe create "GrpcService" binpath="C:\github\junk\GrpcService1\bin\Debug\net6.0\publish\GrpcService1.exe --urls \"http://localhost:6276\""

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM