System.Diagnostics.Process调用子控制台程序时读取父appsettings异常
问题:子进程调用时读取父进程的
appsettings.json而非自身配置 我有一个控制台程序ParentApp,需要通过System.Diagnostics.Process调用多个独立编译的子控制台程序ChildApp。单独运行ChildApp时可正常读取自身的appsettings.json,但被ParentApp调用时,ChildApp会忽略自身配置,读取ParentApp的appsettings.json。关键异常表现为:ChildApp输出的AppName为ParentApp,而非自身配置的AppToTest01。我对依赖注入不熟悉,无法定位问题原因。
代码片段
ParentApp 核心代码
using System.Diagnostics; var childProcess = new ProcessStartInfo { FileName = "ChildApp.exe", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true }; using var process = Process.Start(childProcess); process.WaitForExit(); var output = process.StandardOutput.ReadToEnd(); var error = process.StandardError.ReadToEnd(); Console.WriteLine("ChildApp输出:"); Console.WriteLine(output); if (!string.IsNullOrEmpty(error)) { Console.WriteLine("ChildApp错误:"); Console.WriteLine(error); }
ChildApp 核心代码
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; var host = Host.CreateDefaultBuilder(args) .ConfigureServices((context, services) => { services.AddSingleton(context.Configuration); }) .Build(); var config = host.Services.GetRequiredService<IConfiguration>(); var appName = config["AppName"]; Console.WriteLine($"当前应用名称:{appName}"); host.RunAsync();
ChildApp 的appsettings.json
{ "AppName": "AppToTest01" }
ParentApp 的appsettings.json
{ "AppName": "ParentApp" }
预期与实际输出
预期输出
当前应用名称:AppToTest01
实际异常输出
当前应用名称:ParentApp
问题原因
通过Process调用子进程时,子进程的工作目录默认继承父进程的工作目录。而Host.CreateDefaultBuilder默认会从当前工作目录加载appsettings.json,导致ChildApp启动时读取的是ParentApp目录下的配置文件,而非自身所在目录的文件。
解决办法
方案1:在父进程中指定子进程的工作目录
修改ParentApp的启动代码,将子进程的工作目录设置为ChildApp.exe所在的目录:
using System.Diagnostics; using System.IO; var childExePath = "ChildApp.exe"; // 获取ChildApp.exe的绝对目录 var childWorkingDir = Path.GetDirectoryName(Path.GetFullPath(childExePath)); var childProcess = new ProcessStartInfo { FileName = childExePath, WorkingDirectory = childWorkingDir, // 关键:指定子进程工作目录 UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true }; using var process = Process.Start(childProcess); process.WaitForExit(); var output = process.StandardOutput.ReadToEnd(); var error = process.StandardError.ReadToEnd(); Console.WriteLine("ChildApp输出:"); Console.WriteLine(output); if (!string.IsNullOrEmpty(error)) { Console.WriteLine("ChildApp错误:"); Console.WriteLine(error); }
方案2:在子进程中强制加载自身目录的配置文件
如果担心工作目录被意外修改,可以在ChildApp中手动指定配置文件路径,确保加载自身目录下的appsettings.json:
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System.IO; using System.Reflection; var host = Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, config) => { // 清除默认配置源,手动添加自身目录的配置文件 config.Sources.Clear(); var exeDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); config.AddJsonFile(Path.Combine(exeDir, "appsettings.json"), optional: false, reloadOnChange: true); }) .ConfigureServices((context, services) => { services.AddSingleton(context.Configuration); }) .Build(); var config = host.Services.GetRequiredService<IConfiguration>(); var appName = config["AppName"]; Console.WriteLine($"当前应用名称:{appName}"); host.RunAsync();
内容的提问来源于stack exchange,提问作者Savio Dias
相关产品推荐
相关产品推荐

