【问题标题】:ApplicationSettingsBase.Upgrade() Not Upgrading User Settings after Recompiling with .NET 4.0ApplicationSettingsBase.Upgrade() 使用 .NET 4.0 重新编译后不升级用户设置
【发布时间】:2011-02-12 21:54:34
【问题描述】:

我有一个 C# 程序,它使用标准 ApplicationSettingsBase 来保存其用户设置。这在 .NET 3.5 下运行良好。并且每当创建我的程序的新版本时,提供的 Upgrade() 方法将正确“重新加载”这些设置。

最近,我用 .NET 4.0 重新编译了程序。我的程序的版本号也增加了。但是,当我运行这个版本时,Upgrade() 似乎没有检测到任何以前的版本设置,也没有“重新加载”它们。它开始是空白的。

作为测试,我再次重新编译,回到 .NET 3.5。而这一次,Upgrade() 方法又开始工作了。

有没有办法让Upgrade() 在切换框架时工作?还有什么我想念的吗?

【问题讨论】:

    标签: c# .net .net-4.0


    【解决方案1】:

    我遇到了完全相同的问题,我再次测试了几次,从 .NET 3.5 重新编译到 .NET 4.0。

    不幸的是,我的解决方案是在 vb.net 中,但我相信您可以使用众多转换程序之一在 c# 中看到这一点,例如 http://www.developerfusion.com/tools/convert/vb-to-csharp/

    它涉及枚举 %AppData%\CompanyName 中的所有文件夹,以在您希望升级的版本的文件夹名称中找到最新的 user.config 文件.

    我发现,即使我完全没有更改任何其他设置或代码!

    我之前的所有 .NET 4.0 版本都保留了相同的文件夹名称并成功升级。将旧的 user.config 文件(和版本文件夹名称)从旧文件夹复制到在 .NET 4.0 下创建的新文件夹结构(使用旧版本文件夹名称)可以解决问题 - 现在将升级。

    本示例假设您有一个名为 IUpgraded 的用户设置,默认情况下设置为 False(稍后设置为 True),以检查设置是否为初始设置默认值与否 - 您可以使用您创建的任何其他变量。该示例显示从版本 1.2.0.0 升级到更高版本,您可以通过更改 lastVersion 的值进行更改。

    代码将放置在最新 (.NET 4.0) 应用程序版本的表单加载事件的顶部:

    Imports System
    Imports System.IO
    
    If Not My.Settings.IUpgraded Then 'Upgrade application settings from previous version
        My.Settings.Upgrade()
        'The following routine is only relevant upgrading version 1.2.0.0
        If Not My.Settings.IUpgraded Then 'enumerate AppData folder to find previous versions
            Dim lastVersion As String = "1.2.0.0" 'version to upgrade settings from
            Dim config_initial As System.Configuration.Configuration = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.PerUserRoamingAndLocal)
            Dim fpath As String = config_initial.FilePath
            For x = 1 To 3 'recurse backwards to find root CompanyName folder
                fpath = fpath.Substring(0, InStrRev(fpath, "\", Len(fpath) - 1))
            Next
            fpath = fpath.Substring(0, Len(fpath) - 1) 'remove trailing backslash
            Dim latestConfig As FileInfo 'If not set then no previous info found
            Dim di As DirectoryInfo = New DirectoryInfo(fpath)
            If di.Exists Then
                For Each diSubDir As DirectoryInfo In di.GetDirectories(lastVersion, SearchOption.AllDirectories)
                    If InStr(diSubDir.FullName, ".vshost") = 0 Then 'don't find VS runtime copies
                        Dim files() As FileInfo = diSubDir.GetFiles("user.config", SearchOption.TopDirectoryOnly)
                        For Each File As FileInfo In files
                            Try
                                If File.LastWriteTime > latestConfig.LastWriteTime Then
                                    latestConfig = File
                                End If
                            Catch
                                latestConfig = File
                            End Try
                        Next
                    End If
                Next
            End If
            Try
                If latestConfig.Exists Then
                    Dim newPath As String = config_initial.FilePath
                    newPath = newPath.Substring(0, InStrRev(newPath, "\", Len(newPath) - 1))
                    newPath = newPath.Substring(0, InStrRev(newPath, "\", Len(newPath) - 1))
                    newPath &= lastVersion
                    If Directory.Exists(newPath) = False Then
                        Directory.CreateDirectory(newPath)
                    End If
                    latestConfig.CopyTo(newPath & "\user.config")
                    My.Settings.Upgrade() 'Try upgrading again now old user.config exists in correct place
                End If
            Catch : End Try
        End If
        My.Settings.IUpgraded = True 'Always set this to avoid potential upgrade loop
        My.Settings.Save()
    End If
    

    【讨论】:

    • +1 我已经实现了这个解决方案,因为我们已经从 .NET 2.0 升级到了 .NET 4.0。一个小问题 - 如果文件夹以 . 结尾,di.Exists 无法正确检测到该文件夹​​,因此必须首先使用 this solution 之类的内容对其进行规范化。
    • 感谢您帮助我知道这不是我维护的代码的错。您可能为我节省了检查和重新检查的时间(超出了我已经花费的时间)。
    【解决方案2】:

    这里是代码。

    public static class SettingsUpdate
    {
        public static void Update()
        {
            try
            {
                var a = Assembly.GetExecutingAssembly();
    
                string appVersionString = a.GetName().Version.ToString();
    
                if( UserSettings.Default.internalApplicationVersion != appVersionString )
                {
                    var currentConfig = ConfigurationManager.OpenExeConfiguration( ConfigurationUserLevel.PerUserRoamingAndLocal );
                    var exeName = "MyApplication.exe";
                    var companyFolder = new DirectoryInfo( currentConfig.FilePath ).Parent.Parent.Parent;
    
                    FileInfo latestConfig = null;
    
                    foreach( var diSubDir in companyFolder.GetDirectories( "*" + exeName + "*", SearchOption.AllDirectories ) )
                    {
                        foreach( var file in diSubDir.GetFiles( "user.config", SearchOption.AllDirectories ) )
                        {
                            if( latestConfig == null || file.LastWriteTime > latestConfig.LastWriteTime )
                            {
                                latestConfig = file;
                            }
                        }
                    }
    
                    if( latestConfig != null )
                    {
                        var lastestConfigDirectoryName = Path.GetFileName( Path.GetDirectoryName( latestConfig.FullName ) );
    
                        var latestVersion = new Version( lastestConfigDirectoryName );
                        var lastFramework35Version = new Version( "4.0.4605.25401" );
    
                        if( latestVersion <= lastFramework35Version )
                        {
                            var destinationFile = Path.GetDirectoryName( Path.GetDirectoryName( currentConfig.FilePath ) );
                            destinationFile = Path.Combine( destinationFile, lastestConfigDirectoryName );
    
                            if( !Directory.Exists( destinationFile ) )
                            {
                                Directory.CreateDirectory( destinationFile );
                            }
    
                            destinationFile = Path.Combine( destinationFile, latestConfig.Name );
    
                            File.Copy( latestConfig.FullName, destinationFile );
                        }
                    }
    
                    Properties.Settings.Default.Upgrade();
                    UserSettings.Default.Upgrade();
                    UserSettings.Default.internalApplicationVersion = appVersionString;
                    UserSettings.Default.Save();
                }
            }
            catch( Exception ex )
            {
                LogManager.WriteExceptionReport( ex );
            }
        }
    }
    

    希望对你有帮助:)

    【讨论】:

      【解决方案3】:

      当 Settings1.Upgrade() 无法正常工作时,可能会尝试删除以前的用户配置文件并重试。

      在我的情况下,Release 和 Debug 版本不相关,然后升级似乎失败,因为在与 debug/release 输出相关的同一目录中的版本之间存在冲突。

      清除所有以前的用户配置文件 (appdata\local....) 似乎可以解决问题,调用 Upgrade() 有效,此处提出的解决方法有效。

      我希望它对你有用。

      【讨论】:

      • 当我说删除以前的版本是为了清理垃圾。完成后,尝试第一个版本,然后修改用户设置,对源代码稍作修改,然后再次调试。检查设置是否仍然存在。
      猜你喜欢
      • 1970-01-01
      • 2017-07-22
      • 1970-01-01
      • 2023-03-16
      • 2016-06-23
      • 1970-01-01
      • 2011-05-01
      • 2016-05-02
      • 1970-01-01
      相关资源
      最近更新 更多