You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 Core Worker Service发布为Windows服务时连接字符串未初始化错误

.NET 8 Worker Service 作为Windows服务运行时数据库连接字符串未初始化问题

问题现象

开发的.NET 8 Core Worker Service在Visual Studio调试/Release模式下可正常读写数据库,但发布为Windows Server服务运行时,日志抛出System.InvalidOperationException: The ConnectionString property has not been initialized错误,触发点是首次调用LOGGING上下文查询服务最后运行时间的操作。已确认appsettings.json连接字符串格式正确,同时在Program.cs和DbContext类中配置了连接字符串,不清楚调试与服务运行的核心差异,请求排查指导。

相关代码片段

Program.cs

// Program.cs相关代码
Environment.SetEnvironmentVariable("APP_BASE_DIRECTORY",
    WindowsServiceHelpers.IsWindowsService() ? AppContext.BaseDirectory : Directory.GetCurrentDirectory());

var host = Host.CreateDefaultBuilder(args)
    .UseWindowsService()
    .UseSerilog((context, services, configuration) => configuration
        .ReadFrom.Configuration(context.Configuration)
        .ReadFrom.Services(services))
    .ConfigureServices((hostContext,services) =>
    {
        services.AddHostedService<Worker>();
        services.AddDbContext<DRADPRES>(options =>
        options.UseSqlServer(hostContext.Configuration.GetConnectionString("DRADPRESCON")));
        services.AddDbContext<LOGGING>(options =>
         options.UseSqlServer(hostContext.Configuration.GetConnectionString("DRADPRESCON")));
        services.AddDbContext<PS360>(options =>
         options.UseSqlServer(hostContext.Configuration.GetConnectionString("PS360CON")));
        services.AddHttpClient();
        services.AddTransient<IEmailSender, EmailSender>();
    })
    .Build();

await host.RunAsync();

appsettings.json

// appsettings.json相关配置
{
  "ConnectionStrings": {
    "DRADPRESCON":"Server=VSRADDLSQLRSHAO,57650;Database=DRADPRES;User=yRADPRES;Password=*******;TrustServerCertificate=True",
    "PS360CON":"Server=VSRADPPSSQLAO,50151;Database=Comm4;Trusted_Connection=True;TrustServerCertificate=True"
  }
}

LOGGING.cs DbContext

// LOGGING.cs上下文相关代码
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.UseSqlServer("Server=VSRADDLSQLRSHAO,57650;Database=DRADPRES;User=yRADPRES;Password=******;TrustServerCertificate=True");

排查与解决方案

核心问题分析

  1. DbContext配置冲突:LOGGING DbContext中重写的OnConfiguring方法硬编码了连接字符串,同时Program.cs又通过依赖注入配置了连接字符串。服务运行时可能出现配置加载优先级问题,若硬编码的连接字符串存在占位符(比如密码是******),就会导致初始化失败。
  2. 配置文件路径问题:Windows服务默认工作目录是C:\Windows\System32,而非程序发布目录。即使设置了APP_BASE_DIRECTORY,默认配置加载逻辑可能仍从当前工作目录读取文件,导致服务找不到正确的appsettings.json,进而无法读取连接字符串,只能使用硬编码的无效值。

具体修复步骤

  • 移除DbContext中的硬编码配置:删除LOGGING.cs中的OnConfiguring重写方法,完全依赖依赖注入的配置,避免冲突:
    public class LOGGING : DbContext
    {
        public LOGGING(DbContextOptions<LOGGING> options) : base(options)
        {
        }
    
        // 你的DbSet定义等其他代码
    }
    
  • 确保配置文件随发布复制:在Visual Studio中右键appsettings.json,设置复制到输出目录为始终复制,保证发布时配置文件和程序一起部署。
  • 显式指定配置文件路径(可选):若服务仍无法加载配置,可在Host.CreateDefaultBuilder中基于APP_BASE_DIRECTORY显式指定路径:
    var baseDir = Environment.GetEnvironmentVariable("APP_BASE_DIRECTORY");
    var host = Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((context, config) =>
        {
            config.SetBasePath(baseDir)
                  .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                  .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true)
                  .AddEnvironmentVariables();
        })
        .UseWindowsService()
        // 其他原有配置...
    
  • 指定服务工作目录:安装服务时,通过命令行指定服务工作目录为程序发布目录,避免默认使用System32:
    sc config YourServiceName WorkingDirectory= "C:\Path\To\Your\Service\Publish\"
    

调试与服务运行的核心差异

  • 工作目录不同:调试时工作目录是项目目录,服务默认是C:\Windows\System32,影响相对路径文件的读取。
  • 权限不同:服务默认使用LocalService等系统账户,调试时用当前登录用户账户,可能存在资源访问权限差异(但本次错误核心是连接字符串初始化问题)。
  • 配置加载逻辑:服务运行时环境变量、配置文件的加载优先级与调试模式略有差异,多配置源共存时易出现冲突。

内容的提问来源于stack exchange,提问作者Ishhh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:55:12