ConfigurationManager.OpenMappedExeConfiguration.GetSection()
本文关键字:GetSection OpenMappedExeConfiguration ConfigurationManager | 更新日期: 2023-09-27 18:04:11
首先,让我提前为这个很长的问题道歉——对那些坚持到最后的人致敬!
我有c#/。. NET 3.5类库,它没有安装在GAC中,因为类库是另一个程序(ArcMap.exe)的加载项。该程序实际上从启动时的存档中提取.dll到用户的本地设置'应用程序数据文件夹下的文件夹,但我能够在运行时使用this.GetType().Assembly.Location
获得其位置。
在库中,我有一个名为CustomConfigSection
的类,它在.config文件中被引用。
库有一个方法LoadConfigSection()
的类,它使用ConfigurationManager.OpenMappedExeConfiguration()
从.config文件(存储在用户的应用程序数据文件夹中)读取并返回CustomConfigSection
——或者它应该。发生的是GetSection()
抛出一个讨厌的ConfigurationErrorsException
,说它找不到包含我的CustomConfigSection
的程序集。
恼人的是,这是工作两天前。我想是Windows更新把它弄坏了。我已经回过头来尝试了以前版本的代码,我知道这些代码工作得很好,但无济于事。环境发生了变化,不是我的代码发生了变化,但现在其他机器上也发生了变化,所以不只是我发生了变化!
下面是一个示例。config文件:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="customConfigSection" type="TestExeConfigurationFileMapAddin.CustomConfigSection, TestExeConfigurationFileMapAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<customConfigSection>
<customConfigCollection>
<customConfig name="asdf" />
<customConfig name="1234" />
<customConfig name="jlkjjkljj" />
</customConfigCollection>
</customConfigSection>
</configuration>
和我用来阅读它的代码(正如我在2天前提到的工作完美):
private CustomConfigSection LoadConfigSection()
{
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
configFileMap.ExeConfigFilename = m_userConfigFilePath;
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
CustomConfigSection configSection = config.GetSection("customConfigSection") as CustomConfigSection;
return configSection;
}
m_userConfigFilePath
是.config文件的有效路径,Configuration
对象的HasFile
属性为true。
下面是我得到的错误,在启用Fusion组件绑定日志记录后:
System.Configuration.ConfigurationErrorsException: An error occurred creating the configuration section handler for customConfigSection: Could not load file or assembly 'TestExeConfigurationFileMapAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. (C:'Documents and Settings'...'Application Data'TestExeConfigurationFileMapAddin'test.config line 4) ---> System.IO.FileNotFoundException: Could not load file or assembly 'TestExeConfigurationFileMapAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
File name: 'TestExeConfigurationFileMapAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
at System.Configuration.TypeUtil.GetTypeWithReflectionPermission(IInternalConfigHost host, String typeString, Boolean throwOnError)
at System.Configuration.MgmtConfigurationRecord.CreateSectionFactory(FactoryRecord factoryRecord)
at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere)
Assembly manager loaded from: C:'WINDOWS'Microsoft.NET'Framework'v2.0.50727'mscorwks.dll
Running under executable C:'Program Files'ArcGIS'Desktop10.0'Bin'ArcMap.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = ...
LOG: DisplayName = TestExeConfigurationFileMapAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///C:/Program Files/ArcGIS/Desktop10.0/Bin/
LOG: Initial PrivatePath = NULL
Calling assembly : System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:'Program Files'ArcGIS'Desktop10.0'Bin'ArcMap.exe.Config
LOG: Using machine configuration file from C:'WINDOWS'Microsoft.NET'Framework'v2.0.50727'config'machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Program Files/ArcGIS/Desktop10.0/Bin/TestExeConfigurationFileMapAddin.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/ArcGIS/Desktop10.0/Bin/TestExeConfigurationFileMapAddin/TestExeConfigurationFileMapAddin.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/ArcGIS/Desktop10.0/Bin/TestExeConfigurationFileMapAddin.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/ArcGIS/Desktop10.0/Bin/TestExeConfigurationFileMapAddin/TestExeConfigurationFileMapAddin.EXE.
--- End of inner exception stack trace ---
at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSection(String configKey, Boolean getLkg, Boolean checkPermission)
at System.Configuration.Configuration.GetSection(String sectionName)
at TestExeConfigurationFileMapAddin.Form1.LoadConfigSection() in C:'CSProjects'TestExeConfigurationFileMapAddin'TestExeConfigurationFileMapAddin'Form1.cs:line 46
at TestExeConfigurationFileMapAddin.Form1.LoadConfig() in C:'CSProjects'TestExeConfigurationFileMapAddin'TestExeConfigurationFileMapAddin'Form1.cs:line 28
和Fusion失败绑定日志本身:
*** Assembly Binder Log Entry (7/29/2011 @ 12:46:02 PM) ***
The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.
Assembly manager loaded from: C:'WINDOWS'Microsoft.NET'Framework'v2.0.50727'mscorwks.dll
Running under executable C:'Program Files'ArcGIS'Desktop10.0'Bin'ArcMap.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = ...
LOG: DisplayName = TestExeConfigurationFileMapAddin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///C:/Program Files/ArcGIS/Desktop10.0/Bin/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
Calling assembly : System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:'Program Files'ArcGIS'Desktop10.0'Bin'ArcMap.exe.Config
LOG: Using machine configuration file from C:'WINDOWS'Microsoft.NET'Framework'v2.0.50727'config'machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Program Files/ArcGIS/Desktop10.0/Bin/TestExeConfigurationFileMapAddin.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/ArcGIS/Desktop10.0/Bin/TestExeConfigurationFileMapAddin/TestExeConfigurationFileMapAddin.DLL.
LOG: Attempting download of new URL file:///C:/Program Files/ArcGIS/Desktop10.0/Bin/TestExeConfigurationFileMapAddin.EXE.
LOG: Attempting download of new URL file:///C:/Program Files/ArcGIS/Desktop10.0/Bin/TestExeConfigurationFileMapAddin/TestExeConfigurationFileMapAddin.EXE.
LOG: All probing URLs attempted and failed.
显然ConfigurationManager
正在寻找包含我的CustomConfigSection
从错误的位置组装-至于为什么这只开始发生最近我不知道,但我确实安装了一堆Windows更新2-3天前。我用的是32位的Windows XP Pro SP3。
虽然没有完全理解所有这些术语的含义,但是Fusion日志给了我希望,我可能能够更改加载上下文或策略,以强制它从正确的位置加载程序集。这是真的吗?如果是,又是怎么回事?
使用Assembly.LoadFrom()
并处理AssemblyResolve
事件是关键——这个答案中的代码示例为我解决了这个问题。