在调试会话之间持久化app.config中的数据

本文关键字:config 数据 app 持久化 调试 会话 之间 | 更新日期: 2023-09-27 18:05:30

所以,长话短说,我正在开发一个应用程序,它将利用一些可能在运行时通过应用程序本身更改的配置信息。出于这个目的,我考虑使用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"

(打印完全相同的输出)

两次运行都显示相同的第一次打印"Default user",尽管在第二次运行中我想获得"abc",表明信息没有在不同的应用程序执行之间持久化。

我承认这必须与Visual Studio处理。config文件的方式有关,但即使如此,我想知道如何纠正这种(讨厌的)行为?

在调试会话之间持久化app.config中的数据

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

一般来说,应用程序更改自己的app.config并不是一个好做法。如果您正在开发的应用程序可能由同一台PC上的多个用户使用,那么使用设置代替。这样每个用户都可以有自己的设置。

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

编辑保存设置:

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

  1. 使用调试器监视窗口调用Save()。要做到这一点,在观察窗口中放置一个表达式,如Settings.Default.Save(),并在每次要保存时刷新它。
  2. 你可以尝试使用计时器来调用Save每秒
  3. 你可以在设置改变后在代码中插入Save()调用。
  4. 您可以编写自定义设置提供程序或包装程序,每次更改后立即保存设置。

用户属性设置为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: ' '用户名' AppData '用户本地' ConsoleApplication4 ' ConsoleApplication4.exe_Url_acauylh2btl2j4ed0ilz0mujq5aomfmu ' 1.0.0.0

所以即使在你的应用中。config在多次运行应用程序后,您仍然会看到"默认用户":

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

User。配置,它将是用户的最后一个设置值。

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

当我第一次运行这段代码时输出是"Default User", "abc",第二次运行时输出是"abc" "abc"

也许你只是缺少了Save();

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

在调试会话之间持久化app.config中的数据

你必须写一个exe或脚本,你从PreBuild事件中触发,写User。配置设置返回到设置1。设置文件,然后内置到App.Config中。

我认为你不想这样做,因为用户。config覆盖了App.Config,第二次调试代码,你会得到"abc"abc"。

我很有信心只是Save()不见了。或者应用程序范围设置应该是只读的。

下面是我用来将一些东西保存回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();

希望这对你有帮助。

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

首先,从项目的Properties菜单中创建Settings文件。在解决方案资源管理器中右键单击项目,并选择"属性"。转到Settings选项卡并创建设置文件。创建文件后,您应该看到一个数据网格,您可以在其中输入Name/Type/Scope/Value。设置你想在这里使用的所有变量(我不确定你是否可以在运行时创建更多的变量,但我不这么认为)。

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

读取设置:

Properties.Settings.Default.SrcDir;

和保存设置:

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

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

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