配置管理器的使用

3

我编写了以下代码,以获取ConfigurationManager数据并更新它:

private static void UpdateConfigurationFile()
{
#if DEBUG
    string applicationName =
        Environment.GetCommandLineArgs()[0];
#else 
   string applicationName =
  Environment.GetCommandLineArgs()[0]+ ".exe";
#endif

    string exePath = System.IO.Path.Combine(
        Environment.CurrentDirectory, applicationName);

    // Get the configuration file. The file name has 
    // this format appname.exe.config.
    System.Configuration.Configuration config =
      ConfigurationManager.OpenExeConfiguration(exePath);

    string server = ConfigurationManager.AppSettings["server"];
}

在代码的末尾,服务器为空。
XML具有相应的服务器代码:
<applicationSettings>
    <forLiDAR.Properties.Settings>
        <setting name="Server" serializeAs="String">
            <value>localhost</value>
        </setting>

我做错了什么?


4
是因为区分大小写吗?例如,“Server”不等于“server”。 - Craig Shearer
1个回答

1

好的,我有一个解决方案来解决你的问题。

这不是你的错,因为VS存在一个已经持续多年的bug,很难解释清楚。

所以我们一步一步来:

  1. 通过右键单击项目并转到设置选项卡来添加设置-这是一个错误的路径,原因如下:

如果我们按照文档所说的做,只需要:

Properties.Settings.Default.Server = "Now I'm something different than localhost";
Properties.Settings.Default.Save();

不需要打开ExeConfigration或其他任何东西,只需要这两行代码!.NET就可以轻松地将新设置保存到配置文件中...除了它没有成功:)它会显示“配置系统初始化失败”! 因此,我们认为“好吧,他们在文档中没有涵盖所有内容..让我们添加我们认为缺少的部分..”,所以我们添加了以下内容:
var exePath = System.IO.Path.Combine(Environment.CurrentDirectory, "ConsoleApplication58.vshost.exe.config");
var config = ConfigurationManager.OpenExeConfiguration(exePath);
var oldSetting = config.AppSettings.Settings["Server"].Value;

我们会遇到另一个异常——这次是空引用。于是我们问:“怎么回事?!”通过调试,我们为“config.AppSettings.Settings”添加了观察器,看到.NET实际上试图告诉我们“没有勺子了…”(或者设置数量为0)。

因此,我们可以得出结论,这个垃圾肯定不能与使用AppConfig的应用程序一起使用,但它可以与使用WebConfig的应用程序一起使用——我没有测试过。

  1. 好吧…让我们尝试另一种方法,即从“添加新项”菜单中添加设置文件,其默认文件名将为“settings1.settings”,并将位于项目文件夹名称下而不是属性下。

所以我也做了这个,并测试了以下行:

var oldSetting = Settings1.Default.Server;
Settings1.Default.Server = "localhost2";
Settings1.Default.Save();

这个方法可行,但需要告诉你'Scope'必须是'user'而不是'Application'。如果是'Application',则该设置将没有setter。信息保存在该用户的AppData文件夹中,这是合理的。
当然,这意味着为了手动检查调试期间保存了什么,您需要转到应用程序的配置文件,该文件位于AppData文件夹中,而不是debug/bin文件夹中。
但这当然不是你想要的...
因为你想保存一个'application'范围的设置-对吗? 好吧..你不能-它们不是为此设计的。 您可以在此处阅读:https://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx 应用程序设置类不支持将设置保存到app.config文件中。这是非常明确的设计,以正确保护用户账户(例如Vista UAC)运行的应用程序没有写入安装文件夹的权限。
您可以使用ConfigurationManager类来更改系统设置。但最简单的解决方法是进入设置设计器并将设置范围更改为用户。如果这会带来问题(比如该设置与每个用户相关),您应该将选项功能放在一个单独的程序中,以便请求提升权限提示。或者放弃使用设置。
因此,最后我将尝试向您展示应用程序应该是什么样子:
namespace ConsoleApplication58
{
    class Program
    {
        static void Main(string[] args)
        {
            UpdateConfigurationFile();
        }

        private static void UpdateConfigurationFile()
        {
            var oldSetting = Settings1.Default.Server; //to get the current setting if you want..
            Settings1.Default.Server = "localhost2"; //to change the setting.
            Settings1.Default.Save(); //to save settings.
        }
    }
}

只要按照我的建议添加Settings1.Settings文件,appConfig就可能如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="ConsoleApplication58.Settings1" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
    </startup>

    <userSettings>
        <ConsoleApplication58.Settings1>
            <setting name="Server" serializeAs="String">
                <value>localhost</value>
            </setting>
        </ConsoleApplication58.Settings1>
    </userSettings>
</configuration>

作为评论中要求的,这是一个缺陷报告的链接:
在App.Config和ApplicationSettings中进行配置

1
请在此处发布您向Microsoft发送的Connect错误链接。因为如果您不是解决问题(永远不会修复错误)的一部分,那么您就是问题的一部分。 - John Saunders
我曾经也走过这条路,意识到这就是它设计的工作方式。从某种意义上讲,用户只应该更改自己的设置,而不是应用程序的默认设置...除非您想要“更改此计算机的所有用户的设置”。但无疑,这是一项几乎不可能进行单元测试的功能,除非您模拟或使用 ConfigurationManager。 - nbering
感谢您发送了一个错误报告。我的唯一评论是,您提到了“MSDN文档”,但没有提供链接。在互联网上,如果没有链接,它就不存在(即使有时候有链接也是如此)。 - John Saunders
抱歉,我没有看到 MSDN 的链接。 - John Saunders
@JohnSaunders 当然,这是链接:https://msdn.microsoft.com/zh-cn/library/bb397755(v=vs.110).aspx - G.Y
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接