ConfigurationManager.OpenMappedExeConfiguration.GetSection() завершается ошибкой (только что начал происходить недавно)
Прежде всего, позвольте мне заранее извиниться за очень длинный вопрос - спасибо всем, кто дошел до конца!
У меня есть библиотека классов C#/.NET 3.5, которая не установлена в GAC, поскольку библиотека классов является надстройкой к другой программе (ArcMap.exe). Программа фактически извлекает.dll из архива при запуске в папку в папке Local Settings\Application Data пользователя, но я могу определить ее местоположение во время выполнения, используя this.GetType().Assembly.Location
,
В библиотеке у меня есть класс под названием CustomConfigSection
на который есть ссылка в файле.config.
В библиотеке есть класс с методом LoadConfigSection()
который читает из файла.config (хранится в папке Application Data пользователя), используя ConfigurationManager.OpenMappedExeConfiguration()
и возвращает 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
свойство это правда.
Вот ошибка, которую я получаю после включения ведения журнала привязки сборки 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 дает мне надежду на то, что я смогу изменить контекст или политику загрузки, чтобы заставить ее загружать сборку из правильного расположения. Это правда, и если да, то как?
1 ответ
С помощью Assembly.LoadFrom()
и обработка AssemblyResolve
Событие было ключевым - пример кода в этом ответе решил проблему для меня. Я хотел бы услышать мысли любых экспертов о том, как это работает.