【问题标题】:.net core console application using TopShelf.net 核心控制台应用程序使用 TopShelf
【发布时间】:2019-09-26 00:02:48
【问题描述】:

我使用 TopShelf 创建了一个 .net 核心控制台应用程序。但是使用 docker (alpine-linux) 运行应用程序时出现错误。

Configuration Result:
    [Success] Name MyApp
    [Success] DisplayName MyApp
    [Success] Description My Application
    [Success] ServiceName MyApp
    Topshelf v4.1.0.177, .NET Framework v4.0.30319.42000
    Topshelf.Runtime.Windows.WindowsHostEnvironment Error: 0 : Unable to get parent process (ignored), System.DllNotFoundException: Unable to load shared library 'kernel32.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: Error loading shared library libkernel32.dll: No such file or directory
       at Topshelf.Runtime.Windows.Kernel32.CreateToolhelp32Snapshot(UInt32 dwFlags, UInt32 th32ProcessID)
       at Topshelf.Runtime.Windows.WindowsHostEnvironment.GetParent(Process child)
    Topshelf.HostFactory Error: 0 : The service terminated abnormally, System.PlatformNotSupportedException: ServiceController enables manipulating and accessing Windows services and it is not applicable for other operating systems.
       at System.ServiceProcess.ServiceController.GetServices()
       at Topshelf.Runtime.Windows.WindowsHostEnvironment.IsServiceListed(String serviceName)
       at Topshelf.Hosts.ConsoleRunHost.Run()
       at Topshelf.HostFactory.Run(Action`1 configureCallback)

如何解决这个问题?我需要将控制台应用程序作为 Windows 服务运行

【问题讨论】:

  • 如果您想将控制台应用程序作为 Windows 服务运行,this link 可能会对您有所帮助。
  • 错误的操作系统,这只能在 Windows 上运行。重复is here。 Linux 替代品is here.

标签: docker .net-core containers topshelf .net-core-configuration


【解决方案1】:

Topshelf documentation 非常具体:

要使用 Topshelf,您需要在 Windows 操作系统上运行。 Topshelf 的开发人员定期在 Windows 7 和 Windows Server 2008RC2 上进行测试。尽管它仍然可以在 Windows Server 2003 上运行,但只要安装了 .Net 3.5 sp1。

好消息是writing Linux daemons 比 Windows 服务更容易 - 它们基本上只是一个控制台应用程序,您可以在其中控制主循环。

如果我的问题陈述正确,您希望能够在 Windows 和 Docker 中运行一项服务。在这种情况下,似乎最简单的方法是在启动时检查您的操作系统环境,例如System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform() 或者将你的主要工作推迟到 Topshelf 或者以 Linux 风格运行。对于下面的示例,我安装了Microsoft.Extensions.Hosting 包并选择实现IHostedService(Topshelf 可以方便地重复使用)

public class YourHostedService : IHostedService, IDisposable
{
    private int executionCount = 0;
    private Timer _timer;

    public YourHostedService()
    {
    }

    public Task StartAsync(CancellationToken stoppingToken)
    {
        _timer = new Timer(DoWork, null, TimeSpan.Zero,
            TimeSpan.FromSeconds(5));

        return Task.CompletedTask;
    }

    private void DoWork(object state)
    {
        executionCount++;// this gets called every 5 seconds
    }

    public Task StopAsync(CancellationToken stoppingToken)
    {
        _timer?.Change(Timeout.Infinite, 0);
        return Task.CompletedTask;
    }

    public void Dispose() => _timer?.Dispose();
}

public class Program
{
    public static async Task Main(string[] args)
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            var rc = HostFactory.Run(x =>
            {
                var token = CancellationToken.None;
                x.Service<YourHostedService>(s =>
                {
                    s.ConstructUsing(name => new YourHostedService());
                    s.WhenStarted(tc => tc.StartAsync(token));
                    s.WhenStopped(tc => tc.StopAsync(token));
                });
                x.RunAsLocalSystem();

                x.SetDescription("TopShelf Host");
                x.SetDisplayName("YourHostedService");
                x.SetServiceName("YourHostedService");
            });
        }
        else
        {
            await Host.CreateDefaultBuilder(args)
                .ConfigureServices(builder =>
                {
                    builder.AddHostedService<YourHostedService>();
                })
                .RunConsoleAsync();
        }
    }
}

更多灵感可以借鉴from here。

UPD 因此,您的特定情况似乎也可以通过将任意(在这种情况下是您的)程序作为 Windows 服务运行来解决。 在这种情况下,您有一些不涉及编程而是配置编写的选项:

  1. Microsoft's own tool SrvAny 是 NT Resource Kit 的一部分:您基本上将其安装为虚拟服务并编辑注册表设置以指向您的 .exe
  2. 3rd party tool SrvStart:这个也比较容易上手,配置和上面差不多

【讨论】:

    【解决方案2】:

    Topshelf 不是 .NET Core 的好选择,因为 .Net Core 具有强大的构建 Windows 服务的工具。此外,TopShelf 仅支持 Windows。 请参阅示例:

    https://medium.com/@tocalai/create-windows-service-using-net-core-console-application-dc2f278bbe42

    https://codeburst.io/create-a-windows-service-app-in-net-core-3-0-5ecb29fb5ad0

    【讨论】:

      【解决方案3】:

      所以您的要求是将 dotnet core(哪个版本?)应用程序作为 Windows 服务运行。

      TopShelf 可能不是正确的工具,因为它支持 .NET Framework 4.0 或 Mono,而不是 dotnet 核心。

      由于您要运行 Windows 服务,因此将您的应用程序发布为 Linux Docker 映像没有任何意义!请改用sc create 和sc start 注册并启动您发布的可执行文件。

      【讨论】:

        猜你喜欢
        • 2018-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-20
        • 2020-07-31
        • 1970-01-01
        • 1970-01-01
        • 2021-12-23
        相关资源
        最近更新 更多