【问题标题】:Is this really a bug with ConfigurationManager.OpenExeConfiguration?这真的是 ConfigurationManager.OpenExeConfiguration 的错误吗?
【发布时间】:2017-02-17 08:12:43
【问题描述】:

ConfigurationManager.OpenExeConfiguration(string exePath)documentation 声明:

将指定的客户端配置文件作为配置打开 对象。

它还指出exePath 是“可执行(exe)文件的路径”

该方法应该在exePath指定的路径打开可执行文件的*.exe.config文件,如果“无法加载配置文件”将抛出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 方法的重载中的错误造成的吗?

在我在 MS Connect 上提出之前,我只是想要第二次也是 n 的意见。目前 Connect 已关闭。

添加:如果我用有效的exePath 调用OpenExeConfiguration 到一个真正的可执行文件(经过测试),并带有一个有效的.config 文件,那么它会读取但不解析文件.我必须为appSettings 部分请求xml 并自己解析它,使用此答案对AppSettings from custom files 的解决方法。这增加了我的怀疑,即此代码在此模式下不常用,已被接受为有效且未经审查,因此可能存在错误。

我敢肯定,新的 .NET Core 配置 API 只替换旧的 XML 配置 API 会引起很少的关注。

【问题讨论】:

  • 它是开源的,所以检查代码看它是否是设计使然。 referencesource.microsoft.com/#System.Configuration/System/…
  • @LexLi 我很想查看源代码,感谢提供链接,但如果它是设计使然,(a)它没有意义,并且(b)它应该被记录在案按照设计。事实上,我正在下载整个该死的框架,它只有 59MB。
  • .exe 没有.config 文件是完全正常的。所以,如果它按照你的想法工作,你怎么能用这个 api 创建一个呢?只需正确阅读说明:“无法加载” == 找到该文件,但其中包含乱码。功能,而不是错误。
  • @HansPassant,如果 .exe 没有 .config 文件,那么所讨论的方法肯定会以某种方式通知我。毕竟,文档让我理所当然地认为 .config 已被读取,并且我的代码可能会基于假设配置元素不存在而做出错误的决定。请参阅我的编辑,以了解更多错误行为。使用 .NET Core!

标签: c# .net configurationmanager .net-4.6 defects


【解决方案1】:

据我了解,您有两个担忧:

  1. 对于扩展名为“exe”以外的文件,OpenExeConfiguration 不会失败。

  2. 如果配置文件不存在,OpenExeConfiguration 不会失败。

我理解这两点,但我想说它们都是有争议的。

  1. 可执行文件不一定意味着带有 .exe 扩展名的文件。是的,在 Windows 上这通常是正确的,但让我们以 Linux 为例(我们可以这样做,因为 .NET 不仅限于 Windows)。我可以拥有任何扩展名(甚至是notes.txt)的可执行.NET文件,或者根本没有扩展名,没关系。我可以用“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
    

【讨论】:

  • 是的,但是这个旧的,pre Core 代码,并且没有机会提供配置文件路径,它必须被推断为exename.exe.config。据我所知,4.6 CLR 不会查找任何“notes.txt.config”类型的文件名。今天去调试一下,单步进入CLR代码。
【解决方案2】:

不确定是否可以称为错误,但

根据this参考

根据 http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/3943ec30-8be5-4f12-9667-3b812f711fc9 参数是exe的位置,然后方法查找 对应于该exe的配置(我猜的参数名称 exePath 现在有意义了!)。

它还提供了一种解决方法--

ExeConfigurationFileMap map = new ExeConfigurationFileMap { ExeConfigFilename = "EXECONFIG_PATH" };
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);

【讨论】:

  • 我只是添加验证路径是一个 ece 文件并且它确实有一个 *.exe.config 文件。
猜你喜欢
  • 1970-01-01
  • 2010-11-08
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
  • 2017-06-04
  • 1970-01-01
  • 2013-11-28
相关资源
最近更新 更多