【问题标题】:Persisting the data in app.config between debugging sessions在调试会话之间保留 app.config 中的数据
【发布时间】:2013-03-13 01:36:25
【问题描述】:

所以,长话短说,我正在开发一个应用程序,该应用程序将利用一些配置信息,这些信息可能会在运行时通过应用程序本身进行更改。出于我考虑使用Settings 类的目的。

问题在于,信息在应用程序的不同运行之间没有持久化:

运行 1)

Console.WriteLine(Settings.Default["User"]); //prints "Default user"
Settings.Default["User"] = "abc";
Console.WriteLine(Settings.Default["User"]); //prints "abc"

运行 2)

Console.WriteLine(Settings.Default["User"]); //prints "Default user"
Settings.Default["User"] = "abc";
Console.WriteLine(Settings.Default["User"]); //prints "abc"

都打印完全相同的输出

两次运行都显示相同的第一次打印“默认用户”,尽管在第二次运行时我想获得“abc”,这表明信息没有在不同的应用程序执行之间保留。

我承认这一定与 Visual Studio 处理 .config 文件的方式有关,但即便如此,我还是想知道如何纠正这种(讨厌的)行为?

【问题讨论】:

  • 您是否尝试在设置中调用Save (from MS)。或者为了更“精心”的努力,你可以做ConfigurationManager.OpenExeConfiguration(或OpenMappedExeConfiguration) - 然后SaveSaveAs(例如this

标签: c# visual-studio app-config


【解决方案1】:

默认情况下,App.config 不直接复制,而是将其内容放在输出文件夹的<assembly-name>.config 文件中。复印设置不适用于此操作。

通常,应用程序更改自己的 app.config 不是一个好习惯。如果您正在开发可能被同一台 PC 上的多个用户使用的应用程序,那么请改用use Settings。这样每个用户都可以有自己的设置。

对于服务和系统范围的设置,请考虑使用其他存储,例如单独的配置文件、注册表或数据库。

编辑关于保存设置:

使用设置类时,应调用 Save() 将其写入文件,否则关闭应用程序时将丢弃设置更改。如果您在开发过程中经常终止您的应用程序,并且它没有到达它的结束代码(您通常会调用 Save()),那么您有多种选择:

  1. 使用调试器监视窗口调用 Save()。为此,请将Settings.Default.Save() 之类的表达式放在监视窗口中,并在每次要保存时刷新它。
  2. 您可以尝试使用计时器每秒调用一次 Save。
  3. 您可以在设置更改后在代码中插入 Save() 调用。
  4. 您可以编写自定义设置提供程序或包装器,在每次更改后立即保存设置。

【讨论】:

  • 我的应用程序不会被多个用户使用。我只是想要一种在我的应用程序中加载/存储特定数据的快速方法。根据我的阅读,设置类就是为此目的而创建的(我相信这也是他们允许您通过设置类定义设置的原因)。所以我最初的问题仍然存在:在开发时,如何避免在执行运行之间丢失我保存在文件中的数据?
【解决方案2】:

此代码的 User 属性设置为 User 范围:

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(ConsoleApplication4.Settings1.Default["User"]); //prints "DefaultUser"
            ConsoleApplication4.Settings1.Default["User"] = "abc";
            Console.WriteLine(ConsoleApplication4.Settings1.Default["User"]);
            ConsoleApplication4.Settings1.Default.Save();
            Console.Read();
        }
    }
}

将设置保存到不知名的位置:

C:\Users\用户名\AppData\Local\ConsoleApplication4\ConsoleApplication4.exe_Url_acauylh2btl2j4ed0ilz0mujq5aomfmu\1.0.0.0

因此,即使在您的 app.config 中,您在多次运行应用程序后仍然会看到“默认用户”:

<userSettings>
    <ConsoleApplication4.Settings1>
        <setting name="User" serializeAs="String">
            <value>Default User</value>
        </setting>
    </ConsoleApplication4.Settings1>
</userSettings>

User.Config 中,它将是用户的最后设置值。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <userSettings>
        <ConsoleApplication4.Settings1>
            <setting name="User" serializeAs="String">
                <value>abc</value>
            </setting>
        </ConsoleApplication4.Settings1>
    </userSettings>
</configuration>

当我第一次运行这段代码时,输​​出是“默认用户”,“abc”,第二次运行输出是“abc”“abc”

也许只是您丢失了Save();

如果您的 App.Config 文件与程序一起存储在某处的 Program Files 下,普通用户(非管理员、非超级用户)将无法写入该文件。

在调试会话之间保留 app.config 中的数据

您必须编写从 PreBuild 事件触发的 exe 或脚本,该事件将 User.Config 设置写回 settings1.settings 文件,然后内置到 App.Config 中。

我认为您不想这样做,因为 User.config 会覆盖 App.Config 并且第二次调试代码时您会得到“abc”“abc”。

我非常有信心只是缺少Save()。或者应用程序范围设置应该是只读的。

【讨论】:

  • 很抱歉,也许只是您丢失了Save();。或者该应用程序范围应该是只读的。
【解决方案3】:

我不确定这与您的方法有何不同,但我使用设置文件解决了这个问题。

首先,从项目的“属性”菜单创建设置文件。右键单击解决方案资源管理器中的项目,然后选择“属性”。转到设置选项卡并创建设置文件。创建文件后,您应该会看到一个数据网格,您可以在其中输入名称/类型/范围/值。在此处设置您要使用的所有变量(我不确定您是否可以在运行时创建更多变量,但我不这么认为)。

现在,在代码中,您可以使用位于项目默认命名空间中的 Properties 类。

读取设置:

Properties.Settings.Default.SrcDir;

并保存设置:

Properties.Settings.Default.SrcDir = src;
Properties.Settings.Default.Save();

【讨论】:

    【解决方案4】:

    以下是我用来将某些内容保存回 app.config 文件的内容。

    //write the last run time to config
    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    
    if (config.AppSettings.Settings["LastRunTime"] == null)
    {
        config.AppSettings.Settings.Add("LastRunTime", DateTime.UtcNow.ToString());
    }
    else
    {
        config.AppSettings.Settings["LastRunTime"].Value = DateTime.UtcNow.ToString();
    }
    config.Save();
    

    希望这会有所帮助。

    【讨论】:

      【解决方案5】:

      也许您可以使用文件系统在两个文件之间创建符号链接,以便它实际编辑源中的文件。但是我想不出一个快速的解决方案让编译器不覆盖配置文件(从而删除链接)。

      至少这种方法不需要您编写解决方法。它也不会影响您要保存设置的方式(例如从默认范围更改为用户范围)。所以只有在开发时才有效

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-21
        • 1970-01-01
        • 2023-03-23
        • 2022-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多