【发布时间】:2021-12-01 12:13:34
【问题描述】:
我有 Linux 运行服务的背景,第一次在 Microsoft 环境中工作。我敢肯定,许多领域的代码都可以改进,第一步是获得一个正在运行的服务。我参考了很多帖子和文档,但与运行 django 应用程序的 linux 环境相比,我还不能完全理解 Microsoft 服务和 dotnet 的交互方式。
我使用 Visual Basic for Mac 作为开发,dotnet 5.0 C# 环境来构建一个服务,该服务侦听目录以创建新文件,然后运行包含文件信息的脚本。我部署到具有 dotnet 5.0 环境的 Windows 10 x-64。我可以编译一个 .exe 并在目标机器上运行,它工作正常。然后我使用 sc.exe 构建服务,无论我是从服务管理器 GUI 还是从 Powershell 运行,服务都会超时。我试图弄清楚如何让服务继续运行。该服务将写入我的日志文件,如果将新文件添加到目标目录,它甚至会处理该文件,但它总是会超时并出现以下错误:
Error 1053: the service did not respond to the start or control request in a timely fashion
我的步骤和代码如下:
使用 Visual Studio for Mac 创建辅助服务。
我的Program.cs 是从模板构建的,并添加了一些其他现在为空的方法,但我认为会很有用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace MyService
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
//config.AddJsonFile("custom_settings.json");
})
.ConfigureLogging(logging =>
{
//builder.AddFile("logs/app-{Date}.json"), isJson: true);
})
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
}
}
接下来是Worker.cs:
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using HttpClientSample;
namespace MyService
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
public override async Task StartAsync(CancellationToken cancellationToken)
{
string path = @"C:\log.txt";
string startText = "Start" + Environment.NewLine;
File.AppendAllText(path, startText);
await ExecuteAsync(cancellationToken);
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
string path = @"C:\log.txt";
string stopText = "Stop" + Environment.NewLine;
File.AppendAllText(path, stopText);
await base.StopAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
string path = @"C:\log.txt";
string writeText = "Execute Async" + Environment.NewLine;
File.AppendAllText(path, writeText);
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = @"C:\files\";
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Created += OnCreated;
watcher.Filter = "*.*";
watcher.EnableRaisingEvents = true;
File.AppendAllText(path, "watcher engaged.");
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("worker running at: {time}", DateTimeOffset.Now);
try
{
await Task.Delay(1000, stoppingToken);
}
catch (OperationCanceledException)
{
break;
}
}
}
private static void OnCreated(object sender, FileSystemEventArgs e)
{
string path = @"C:\log.txt";
string writeText = $"e: {e}";
File.AppendAllText(path, writeText);
MyProgram myProgram = new MyProgram(e.FullPath);
}
}
}
然后我在 MyProgram 中进行处理,一切正常。
对于服务,我首先使用以下命令编译以更正运行时:dotnet publish -c Release -r win10-x64。然后我将发布文件夹通过 FTP 传输到 Windows 10 机器,将 .exe 作为管理员配置文件运行,它工作正常,然后通过以下文件从文件创建服务:sc.exe create myService binPath= "C:\path\to\executable.exe"。然后我继续从服务管理器或使用sc.exe start myService 的 Powershell 运行此服务。大约 60 秒后,我收到 1053 错误。
我不明白保持服务运行需要什么。我尝试过的步骤如下:
- 我已确保在构建服务时指向 exe。
- 我已经按照几个网站的建议通过注册表增加了超时时间:here。
- 我在 Event Viewer 中检查了 dotnet 或服务管理器问题,但无法找到问题的原因。
- 我已尝试使用本地系统帐户和管理员帐户来运行服务,但仍然超时。
- 我已将 InstallUtil 视为 sc.exe 的建议替代品,但我还没有尝试过。我不确定这个工具有多大的不同?
- 尝试通过服务管理器运行此服务时,使用 WindowsService 与 BackgroundService 会有所不同吗?
- 程序是否需要执行某些信号或返回值才能让服务知道继续运行?已经实现了 Task.delay() 并为 StartTask 和 ExecuteTask 方法返回值。
任何有关故障排除、解决问题或改进我的帖子的建议都将不胜感激。谢谢!
【问题讨论】:
标签: c# .net windows .net-core windows-services