Это действительно ошибка с ConfigurationManager.OpenExeConfiguration?

В документации для ConfigurationManager.OpenExeConfiguration(string exePath) указано:

Открывает указанный файл конфигурации клиента как объект конфигурации.

Там же указано, что exePath — это «Путь к исполняемому (exe) файлу»

Предполагается, что метод открывает файл *.exe.config для исполняемого файла по пути, указанному exePath, и что ConfigurationErrorsException будет выдано, если «Файл конфигурации не может быть загружен».

В следующем коде используется путь к неисполняемому файлу, и каталог этого пути не содержит файлов *.exe.config. Тем не менее, код выполняется без каких-либо исключений и других признаков недопустимого аргумента.

var configs = Directory.GetFiles("C:\\NoConfig", "*.config");
Debug.Assert(configs.Length == 0);
File.WriteAllText("C:\\NoConfig\\notes.txt", "This is not an executable, and there is no .config file in its folder.");
var config = ConfigurationManager.OpenExeConfiguration("c:\\notes.txt");
Debug.Assert(config != null);

Тем не менее, теперь он постепенно устаревает для новой конфигурации .NET Core на основе JSON и в любом случае не будет пересматриваться или исправляться.

Итак, это из-за ошибки в этой перегрузке метода OpenExeConfiguration?

Я просто хотел 2-е и n-е мнение, прежде чем поднять его на MS Connect. И Connect в данный момент не работает.

ДОБАВЛЕНО: Если я вызываю OpenExeConfiguration с действительным exePath к реальному исполняемому файлу (проверенному) с действительным файлом .config, он читает, но не анализирует файл. Я должен запросить xml для раздела appSettings и проанализировать его самостоятельно, используя обходной путь из этого ответа на AppSettings из пользовательских файлов . Это усиливает мое подозрение, что этот код обычно не используется в этом режиме, считается рабочим, но не проверенным и, следовательно, может содержать ошибки.

Я уверен, что он получит мало внимания, так как новый API конфигурации .NET Core заменит только старый XML.


person ProfK    schedule 08.10.2016    source источник
comment
Это открытый исходный код, поэтому проверьте код, чтобы убедиться, что он разработан. referencesource.microsoft.com/#System.Configuration/System/   -  person Lex Li    schedule 08.10.2016
comment
@LexLi Мне очень интересно увидеть исходный код, спасибо за ссылку, но если это задумано, (а) это не имеет смысла и (б) это должно быть задокументировано так, как задумано. На самом деле я качаю весь долбаный фреймворк, он всего 59мб.   -  person ProfK    schedule 08.10.2016
comment
Совершенно нормально, что .exe не имеет файла .config. Итак, если это работает так, как вы думаете, как вы могли создать его с этим API? Просто правильно прочитайте описание: не удалось загрузить == файл найден, но он содержит тарабарщину. Фича, а не баг.   -  person Hans Passant    schedule 09.10.2016
comment
@HansPassant, если в .exe нет файла .config, конечно, рассматриваемый метод должен каким-то образом уведомить меня об этом. В конце концов, документы заставляют меня считать само собой разумеющимся, что .config был прочитан, и мой код может принимать ошибочные решения, основанные на предположении, что элементы конфигурации отсутствуют. Пожалуйста, смотрите мое редактирование, относящееся к дальнейшему ошибочному поведению. Внедряйте .NET Core!   -  person ProfK    schedule 09.10.2016


Ответы (2)


Итак, у вас есть две проблемы, как я понимаю:

  1. OpenExeConfiguration не дает сбоев для файлов с расширениями, отличными от «exe».

  2. OpenExeConfiguration не завершается ошибкой, если файл конфигурации еще не существует.

Я понимаю оба пункта, но я бы сказал, что оба они спорны.

  1. Исполняемый файл не обязательно означает файл с расширением .exe. Да, в Windows это обычно верно, но давайте возьмем, к примеру, Linux (и мы можем это сделать, потому что .NET не ограничивается только Windows). У меня может быть исполняемый .NET файл с любым расширением (даже notes.txt), или вообще без расширения, не важно. Я могу с радостью запустить этот файл с помощью «mono notes.txt», и он будет работать как обычно.

  2. Отсутствие файла конфигурации не является исключительным условием для объекта Configuration. У него даже есть свойство с именем HasFile, которое указывает, существует ли этот файл или нет. Я могу сделать следующее с вашим кодом:

    var config = ConfigurationManager.OpenExeConfiguration("c:\\notes.txt"); 
    // config.HasFile == false here
    config.AppSettings.Settings.Add("test", "test");
    config.Save(ConfigurationSaveMode.Full, true);
    // config.HasFile == true here, and file is written to disk
    
person Evk    schedule 08.10.2016
comment
Да, но этот старый код до Core и без возможности указать путь к файлу конфигурации должен выводиться как exename.exe.config. CLR 4.6, насколько мне известно, не будет искать имена файлов типа «notes.txt.config». Я собираюсь отлаживать его сегодня, вступая в код CLR. - person ProfK; 09.10.2016

Не уверен, можно ли это назвать ошибкой или нет, но

Согласно этой ссылке

Согласно http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/3943ec30-8be5-4f12-9667-3b812f711fc9 параметр — это расположение исполняемого файла, а затем метод ищет конфигурацию, соответствующую этот exe (я думаю, имя параметра exePath теперь имеет смысл!).

Это также дает обходной путь -

ExeConfigurationFileMap map = new ExeConfigurationFileMap { ExeConfigFilename = "EXECONFIG_PATH" };
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
person Miguel Sanchez    schedule 08.10.2016
comment
Я просто добавляю подтверждение того, что путь указан для файла .exe и у него есть файл *.exe.config. - person ProfK; 08.10.2016