使用Add-Type加载DLL时,如何设置ConfigurationManager.AppSettings值?
这个问题我之前处理过,核心原因很明确:ConfigurationManager.AppSettings默认读取的是当前运行进程的配置文件——也就是你用的PowerShell进程对应的powershell.exe.config(Windows PowerShell)或pwsh.exe.config(PowerShell Core),而不是类库自带的Class1.dll.config。所以直接把配置放在类库的.config文件里是没用的,下面给你几个可行的解决方案:
方案一:临时修改PowerShell进程的配置文件(适合快速测试)
这种方法需要修改PowerShell本身的配置文件,步骤如下:
- 先找到PowerShell的安装目录,在PowerShell里执行
$PSHOME就能得到路径。 - 进入该目录,找到对应的配置文件:
- Windows PowerShell:
powershell.exe.config - PowerShell Core:
pwsh.exe.config
- Windows PowerShell:
- 编辑这个文件(需要管理员权限),添加
appSettings节点:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="UserName" value="你的目标用户名" /> </appSettings> </configuration>
- 重启PowerShell,再运行你的调用脚本,此时类库就能读到配置值了。
方案二:在PowerShell会话中直接动态设置配置(最灵活,无需修改文件)
这种方法不需要改动任何配置文件,直接在PowerShell会话中临时注入配置项,关闭会话后自动失效,非常适合临时测试:
$dllFolder = "C:\...\bin\Debug" Add-Type -Path "$dllFolder\Class1.dll" # 加载System.Configuration程序集,用来操作配置 Add-Type -AssemblyName System.Configuration # 直接设置AppSettings的值 [System.Configuration.ConfigurationManager]::AppSettings["UserName"] = "你的目标用户名" # 如果是.NET Core/.NET 5+版本的类库,上面的方法可能不生效,可以试试下面的方式: # $config = [System.Configuration.ConfigurationManager]::OpenExeConfiguration([System.Reflection.Assembly]::GetExecutingAssembly().Location) # $config.AppSettings.Settings.Add("UserName", "你的目标用户名") # $config.Save() # [System.Configuration.ConfigurationManager]::RefreshSection("appSettings") $test = New-Object Class1 $test.X()
运行这段脚本后,类库的X()方法就能正确输出你设置的用户名了。
方案三:复制类库配置文件到PowerShell目录(临时测试快捷方式)
如果你已经有现成的Class1.dll.config,可以直接复制一份,重命名为PowerShell进程对应的配置文件名(powershell.exe.config或pwsh.exe.config),然后放到$PSHOME指向的目录里,重启PowerShell即可生效。这种方法本质和方案一一样,只是省去了手动编辑配置的步骤。
方案四:修改类库代码,支持外部传入配置(长期最佳实践)
上面的方法都是临时 workaround,从代码设计的角度来说,最靠谱的方式是让类库不要依赖配置文件,而是允许外部传入所需的参数,这样不管在什么环境调用都更灵活:
修改你的Class1代码:
public class Class1 { private readonly string _userName; // 新增带参数的构造函数,允许外部传入用户名 public Class1(string userName) { _userName = userName; } // 保留无参构造函数,兼容原有调用逻辑(可选) public Class1() { _userName = ConfigurationManager.AppSettings["UserName"]; } public void X() { Console.WriteLine(_userName); } }
然后在PowerShell中调用时直接传入用户名:
$dllFolder = "C:\...\bin\Debug" Add-Type -Path "$dllFolder\Class1.dll" $test = New-Object Class1("你的目标用户名") $test.X()
这种方式完全摆脱了对配置文件的依赖,符合依赖注入的设计原则,也让类库的复用性更强。
内容的提问来源于stack exchange,提问作者ca9163d9

