.NET 8 Windows服务通过ProcessStartInfo安装后Serilog无法写日志
环境与基础配置
- .NET 8 Web API,部署在Windows Server 2022 Standard,服务以本地系统账户运行
- 发布命令:
dotnet publish --configuration Release --output publish --runtime win-x64 --self-contained=true
服务安装方式
通过ProcessStartInfo调用sc create命令安装服务:
var processInfo = new ProcessStartInfo { FileName = "cmd.exe", Arguments = $"/c sc create \"{envServiceName}\" binPath= \"\\\"{environmnetPath}\\publish\\MyApi.Api.exe\\\" --environment={environment}\" DisplayName= \"MyApi {environment} API Service\" start= auto", RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = false }; using var process = Process.Start(processInfo);
初始Serilog配置
Program.cs中配置:
builder.Host.UseSerilog((ctx, cfg) => cfg.ReadFrom.Configuration(ctx.Configuration));
appsettings.json配置:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "Serilog": { "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], "MinimumLevel": "Debug", "WriteTo": [ { "Name": "Console" }, { "Name": "File", "Args": { "path": "D:\\deployments\\logs\\myapp\\log-.txt", "rollingInterval": "Day" } } ], "Enrich": [ "FromLogContext", "WithMachineName" ], "Properties": { "ApplicationName": "Your ASP.NET Core App" } }, "AllowedHosts": "*" }
异常现象
- 直接用sc命令安装或双击启动exe文件,日志可正常生成
- 通过
ProcessStartInfo安装服务后,无日志输出,Serilog自诊断日志抛出异常:
Failed to write event through SerilogLogger: System.IO.FileNotFoundException: Could not load file or assembly 'System.Diagnostics.DiagnosticSource, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
File name: 'System.Diagnostics.DiagnosticSource, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
at Serilog.Extensions.Logging.SerilogLogger.PrepareWrite[TState](LogEventLevel level, EventId eventId, TState state, Exception exception, Func3 formatter)
at Serilog.Extensions.Logging.SerilogLogger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
尝试过的其他配置
直接在Program.cs中硬编码Serilog配置后,仅能看到Program.cs内的日志,无法捕获注入ILogger<MyClass>的业务类日志:
Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .WriteTo.Console() .WriteTo.File( path: Path.Combine("D:\\deployments\\logs\\myapp", "log-.txt"), rollingInterval: RollingInterval.Day, shared: true // Important for services ) .Enrich.FromLogContext() .Enrich.WithMachineName() .Enrich.WithProperty("ApplicationName", "Your ASP.NET Core App") .CreateLogger(); Log.Information("Environment:" + builder.Environment.EnvironmentName); builder.Host.UseWindowsService(); builder.Host.UseSerilog(Log.Logger);
1. 修复依赖缺失问题
- 检查发布目录下是否存在
System.Diagnostics.DiagnosticSource.dll,若缺失,重新发布项目(确保.NET 8 SDK为最新稳定版),或手动从NuGet包中提取对应版本的DLL放入发布目录 - 自包含发布时,确认
--runtime win-x64参数正确,避免跨平台依赖不匹配
2. 调整服务安装的工作目录
在ProcessStartInfo中设置工作目录为发布文件夹,确保服务启动时能正确加载所有依赖文件:
var processInfo = new ProcessStartInfo { FileName = "cmd.exe", Arguments = $"/c sc create \"{envServiceName}\" binPath= \"\\\"{environmnetPath}\\publish\\MyApi.Api.exe\\\" --environment={environment}\" DisplayName= \"MyApi {environment} API Service\" start= auto", RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = false, WorkingDirectory = Path.Combine(environmnetPath, "publish") // 指定工作目录为发布文件夹 }; using var process = Process.Start(processInfo);
3. 修正硬编码Serilog配置的问题
解决重复覆盖日志级别、未正确集成ASP.NET Core日志管道的问题:
Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning) // 明确覆盖ASP.NET Core框架日志 .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .WriteTo.File( path: Path.Combine("D:\\deployments\\logs\\myapp", "log-.txt"), rollingInterval: RollingInterval.Day, shared: true ) .Enrich.FromLogContext() .Enrich.WithMachineName() .Enrich.WithProperty("ApplicationName", "Your ASP.NET Core App") .CreateLogger(); try { Log.Information("Starting web host"); var builder = WebApplication.CreateBuilder(args); // 必须在添加其他服务前调用UseSerilog builder.Host.UseWindowsService(); builder.Host.UseSerilog(); // 自动使用全局配置的Log.Logger // 添加业务服务 builder.Services.AddControllers(); var app = builder.Build(); // 中间件配置 app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run(); } catch (Exception ex) { Log.Fatal(ex, "Host terminated unexpectedly"); } finally { Log.CloseAndFlush(); }
4. 验证目录权限
确保本地系统账户对D:\\deployments\\logs\\myapp目录拥有读写权限,避免因权限不足导致日志无法写入
内容的提问来源于stack exchange,提问作者Zippy

