ConfigurationManager.OpenMappedExeConfiguration.GetSection () не работает (только что началось недавно)

Во-первых, позвольте мне заранее извиниться за чрезвычайно длинный вопрос - слава всем, кто дожил до конца!


У меня есть библиотека классов C # /. NET 3.5, которая не установлена ​​в GAC, поскольку библиотека классов является надстройкой к другой программе (ArcMap.exe). Программа фактически извлекает .dll из архива при запуске в папку в папке Local Settings \ Application Data пользователя, но я могу получить ее местоположение во время выполнения, используя this.GetType().Assembly.Location.

В библиотеке у меня есть класс CustomConfigSection, на который есть ссылка в файле .config.

В библиотеке есть класс с методом LoadConfigSection(), который читает из файла .config (хранящегося в папке данных приложения пользователя) с помощью 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, а свойство HasFile объекта Configuration имеет значение 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 дает мне надежду, что я смогу изменить контекст или политику загрузки, чтобы заставить ее загружать сборку из правильного места. Так ли это, и если да, то как?


person blah238    schedule 29.07.2011    source источник
comment
Были ли недавно изменены разрешения вашей учетной записи Windows? Я знаю, что это может показаться глупым вопросом, поскольку dll находится в области ваших документов и настроек, но недавно я обнаружил (Win7), что не являюсь владельцем моих документов и настроек.   -  person tomfumb    schedule 30.07.2011
comment
Насколько мне известно, нет, я все еще являюсь администратором на машине.   -  person blah238    schedule 30.07.2011
comment
Что ж, я получаю то же самое на машине Win7 x64, на которой, как я знаю, у меня есть полные права администратора и т. Д. И т. Д. Согласно этот пост Джона Ристы из 2009 г., вот как он должен работать - из-за ограничений безопасности в .NET сборка должна быть в путь поиска частной корзины хостингового приложения. Почему это работало раньше и больше никто не догадывается, но если это правда, я предполагаю, что обновление Windows ужесточило эту безопасность. Пожалуйста, дайте мне знать, если вы обнаружите то же самое со своей надстройкой.   -  person blah238    schedule 01.08.2011
comment
Я почти уверен, что обновление безопасности .NET Framework за июнь 2011 г. (MS11-039) было изменением, которое привело к тому, что это началось. Похоже, поставщику (ESRI) необходимо обновить свою программу, чтобы обеспечить повышенную безопасность. В любом случае, я пошел дальше и теперь использую XML (де) сериализацию вместо конфигурации .NET.   -  person blah238    schedule 02.08.2011


Ответы (1)


Ключевым моментом было использование Assembly.LoadFrom() и обработка события AssemblyResolve - пример кода в этот ответ решил проблему для меня. Я хотел бы услышать мнения экспертов о том, как это работает.

person blah238    schedule 02.08.2011