C++ EXE加载C#程序集时ConfigurationManager静态调用抛空异常求助
问题根因
默认的ConfigurationManager静态类加载配置时,会读取入口程序对应的配置文件,也就是当前场景里C++主程序Application.exe对应的Application.exe.config,而你把配置放在了myDll.dll.config中,所以静态方法读取到的配置为空。你之前调用OpenMappedExeConfiguration是手动指定配置路径读取的独立配置对象,不会修改ConfigurationManager静态类的默认加载行为,因此NLog等依赖ConfigurationManager静态方法的第三方库无法读到配置。
可行解决方案
方案1:新增主程序配置文件(最简单,零代码改动)
将myDll.dll.config的内容复制一份,重命名为Application.exe.config,放到和Application.exe同目录下即可。如果C++主程序本身已经有Application.exe.config,只需要把你的配置节点合并到该文件中即可,所有依赖默认配置的组件都会自动生效。
方案2:运行时修改AppDomain默认配置路径(通用,适配所有第三方库)
在C#代码被调用的最早期(必须在首次访问ConfigurationManager任何静态成员之前执行),修改当前AppDomain的默认配置文件指向,同时清空配置缓存,代码示例如下:
using System.Reflection; using System.Configuration; using System.IO; // 放在C#入口逻辑最开始执行 string dllConfigPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "myDll.dll.config"); // 修改AppDomain默认配置文件路径 AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", dllConfigPath); // 清空ConfigurationManager已加载的配置缓存 Type configManagerType = typeof(ConfigurationManager); BindingFlags staticNonPublic = BindingFlags.Static | BindingFlags.NonPublic; configManagerType.GetField("s_initState", staticNonPublic)?.SetValue(null, 0); configManagerType.GetField("s_configSystem", staticNonPublic)?.SetValue(null, null); // 清空客户端配置路径缓存 Type clientConfigPathsType = Assembly.GetAssembly(typeof(ConfigurationManager)) .GetType("System.Configuration.ClientConfigPaths"); clientConfigPathsType.GetField("s_current", staticNonPublic)?.SetValue(null, null);
执行完成后,后续所有调用ConfigurationManager静态方法的逻辑(包括第三方库)都会读取myDll.dll.config的配置。
方案3:单独给NLog指定配置文件(仅解决NLog问题)
如果只有NLog出现配置加载问题,不需要适配其他第三方库,可以手动加载NLog配置:
using NLog; using System.IO; string configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "myDll.dll.config"); LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(configPath);
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

