更改装配/文件版本后保留用户的设置

时间:2014-05-29 01:00:44

标签: c# .net winforms settings versioning

背景
我有一个用C#编写的简单WinForms应用程序。我讨论了一段时间的部署解决方案,但最终决定放弃ClickOnce,因为一些约束条件具有至关重要的限制。

相反,我已经在应用程序的属性中修改了通过程序集/文件版本(我保持同步)对应用程序进行版本控制的简单解决方案。我通过安装项目(* .msi)进行部署。我将最新的程序集版本号在线存储在XML文件中,以及最新的安装程序文件。在运行时,我只需在线查看Application.ProductVersion对照最新版本,如果有更新,则打开更新对话框。

问题
到目前为止,这种方法运作良好,但我最近发现这种方法存在一个主要问题。更新应用程序的程序集版本后,将在AppData / Company / Product / Version / blahblahblah中创建用户的新设置文件(user.config)。这显然迫使用户重置新版本中的所有内容。

建议的解决方案
我不知道该怎么办。到目前为止,该应用程序只有1个版本,目前的用户群基本上是我可以乞求测试它的人,所以切换策略没什么大不了的。我考虑过了:

1。)编写我自己的设置系统,从而完全控制设置文件的存储和使用位置/方式 2.)重新考虑我的版本控制/更新策略,以便更新不基于程序集版本。我不确定如何做到这一点,但我的测试似乎表明即使构建和安装具有相同程序集版本的新版本仍然会破坏user.config。

我想我真正想知道是否有任何方法可以保留默认设置系统,因为它很容易使用,同时也适应我的部署策略。

2 个答案:

答案 0 :(得分:35)

使用内置的设置类,您只需在更改应用程序版本时随时升级设置。这是怎么做的: 在Settings.settings文件中,创建一个新设置 UpdateSettings type = bool Scope = User Value = True

在使用任何设置之前包含以下代码(它可以在每次运行应用程序时运行,因为这样可以更轻松地在调试程序中运行)

// Copy user settings from previous application version if necessary
if (MyApp.Properties.Settings.Default.UpdateSettings)
{
    MyApp.Properties.Settings.Default.Upgrade();
    MyApp.Properties.Settings.Default.UpdateSettings = false;
    MyApp.Properties.Settings.Default.Save();
}

运行新的应用程序版本时,UpdateSettings的默认值为True,并且不会使用任何旧设置。如果UpdateSettings为true,我们会从旧设置升级设置,然后保存在新的应用版本下。

答案 1 :(得分:3)

以下是我如何解决它。

在GUI应用程序中,通过执行

可以非常轻松地恢复设置
Properties.Settings.Default.Upgrade ();
Properties.Settings.Default.Reload ();
Properties.Settings.Default.NewVersionInstalled = false;
Properties.Settings.Default.Save ();

但是,我一直遇到的问题是,在安装新版本后,所有其他库都会丢失其设置。通过以下实现,该软件将运行AppDomain的所有程序集并恢复相应库的设置:

foreach(var _Assembly in AppDomain.CurrentDomain.GetAssemblies())
{
    foreach(var _Type in _Assembly.GetTypes())
    {
        if(_Type.Name == "Settings" && typeof(SettingsBase).IsAssignableFrom(_Type))
        {
            var settings = (ApplicationSettingsBase)_Type.GetProperty("Default").GetValue(null, null);
            if(settings != null)
            {
                settings.Upgrade();
                settings.Reload();
                settings.Save();
            }
        }
    }
}

我已经在GUI项目的App.xaml.cs中实现了代码,并且当新版本将“NewVersionInstalled”设置设置为true时,它将始终执行。

希望这有帮助!