简体   繁体   English

ApplicationSettingsBase.Upgrade() 使用 .NET 4.0 重新编译后不升级用户设置

[英]ApplicationSettingsBase.Upgrade() Not Upgrading User Settings after Recompiling with .NET 4.0

I have a C# program that is using the standard ApplicationSettingsBase to save its user settings.我有一个 C# 程序,它使用标准的ApplicationSettingsBase来保存其用户设置。 This was working fine under .NET 3.5.这在 .NET 3.5 下运行良好。 And the provided Upgrade() method would properly "reload" those settings whenever a new version of my program was created.每当创建新版本的程序时,提供的Upgrade()方法都会正确“重新加载”这些设置。

Recently, I recompiled the program with .NET 4.0.最近,我用.NET 4.0 重新编译了程序。 My program's version number also increased.我的程序的版本号也增加了。 But, when I run this version, Upgrade() doesn't seem to to detect any previous version settings, and does not "reload" them.但是,当我运行这个版本时, Upgrade()似乎没有检测到任何以前的版本设置,也没有“重新加载”它们。 It starts blank.它开始空白。

As a test, I recompiled yet again, going back to .NET 3.5.作为测试,我再次重新编译,回到 .NET 3.5。 And this time, the Upgrade() method started working again.这一次, Upgrade()方法再次开始工作。

Is there a way to allow Upgrade() to work when switching frameworks?有没有办法在切换框架时允许Upgrade()工作? Is there something else I am missing?还有什么我想念的吗?

I had exactly the same problem, and again I tested this several times from .NET 3.5 recomplied to .NET 4.0.我遇到了完全相同的问题,我再次从 .NET 3.5 重新编译到 .NET 4.0 进行了多次测试。

Unfortunately, my solution is in vb.net, but I'm sure you can use one of the many conversion programs to see this in c# such as http://www.developerfusion.com/tools/convert/vb-to-csharp/不幸的是,我的解决方案是在 vb.net 中,但我相信您可以使用众多转换程序之一在 c# 中看到这一点,例如http://www.developerfusion.com/tools/convert/vb-to-csharp /

It involves enumerating through all the folders in %AppData%\\CompanyName to find the latest user.config file in a folder name of the version you wish to upgrade from.它涉及枚举%AppData%\\CompanyName 中的所有文件夹,以在您希望升级的版本的文件夹名称中找到最新的user.config文件。

I found that recompiling my app to .NET 4.0 under Visual Studio 2010 would create a new folder of name %AppData%\\CompanyName\\AppName.exe_Url_blahbahblah even though I had changed absolutely no other settings or code at all!我发现在 Visual Studio 2010 下将我的应用程序重新编译到 .NET 4.0 会创建一个名为%AppData%\\CompanyName\\AppName.exe_Url_blahbahblah的新文件夹,即使我完全没有更改其他设置或代码!

All my previous releases prior to .NET 4.0 retained the same folder name and upgraded successfully.我在 .NET 4.0 之前的所有以前版本都保留了相同的文件夹名称并成功升级。 Copying the old user.config file (and version folder name) from the old folder into the new folder structure created under .NET 4.0 (with the old version folder name) fixes the problem - it will now upgrade.将旧的 user.config 文件(和版本文件夹名称)从旧文件夹复制到在 .NET 4.0 下创建的新文件夹结构(使用旧版本文件夹名称)修复了问题 - 现在将升级。

This example assumes you have a user setting named IUpgraded which is set to False by default (and later set to True) to check to see if the settings are initial defalt values or not - you may use any other variable you created instead.此示例假设您有一个名为IUpgraded的用户设置,该设置默认设置为False (稍后设置为 True)以检查设置是否为初始默认值 - 您可以改用您创建的任何其他变量。 The example shows upgrading from version 1.2.0.0 to something later which you can change by changing the value of lastVersion .该示例显示了从版本 1.2.0.0 升级到更高版本的内容,您可以通过更改lastVersion的值来更改该版本

The code is to be placed at the top of the form Load event of your latest (.NET 4.0) application version:该代码将放置在最新 (.NET 4.0) 应用程序版本的表单 Load 事件的顶部:

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

Here is the code.这是代码。

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 );
        }
    }
}

May this will help you :)可能这会帮助你:)

When Settings1.Upgrade() doesn't work as you espected, may try to delete previous user config files and try again.当 Settings1.Upgrade() 没有像您预期的那样工作时,可以尝试删除以前的用户配置文件并重试。

In my case, Release and Debug versions are not correlative, then upgrade seems to fails because there is a conflict between versions in same directory related to debug/release outputs.在我的情况下,发布和调试版本不相关,然后升级似乎失败,因为与调试/发布输出相关的同一目录中的版本之间存在冲突。

Clearing all previous user config files (appdata\\local....) seems to solve the problem, calling Upgrade() works and the workaround proposed here works.清除所有以前的用户配置文件 (appdata\\local....) 似乎解决了问题,调用 Upgrade() 工作并且这里提出的解决方法工作。

I hope it works for you.我希望这个对你有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 保存用户范围的设置(ApplicationSettingsBase) - Saving user scoped settings (ApplicationSettingsBase) 升级到.Net 4.0后的AccessViolationException - AccessViolationException after upgrade to .Net 4.0 .NET ApplicationSettingsBase我每次加载时都应该调用Upgrade()吗? - .NET ApplicationSettingsBase Should I call Upgrade() every time I load? 如何使用ApplicationSettingsBase将自定义类保存到用户设置? - How do I save a custom class to user settings using ApplicationSettingsBase? 设置升级后如何删除以前的用户设置? - How to remove previous user settings after settings upgrade? C# 动态 JObject 在升级到 .NET 4.0 后不起作用 - C# dynamic JObject not working after upgrading to .NET 4.0 升级到VS 2010和.NET 4.0后LINQ停止工作 - LINQ stopped working after upgrade to VS 2010 and .NET 4.0 .NET Framework升级后(.NET 4.0至.NET 4.5.1)的DLL冲突 - DLL's conflict after .NET framework upgrade (.NET 4.0 to .NET 4.5.1) 将Visual Studio 2017中的.NET Framework从4.0升级到4.6.1后,C#API项目中发生错误 - ERROR in C# API project after upgrading .NET framework from 4.0 to 4.6.1 in Visual Studio 2017 从 .net 4.0 升级到 4.6.1 后 WiX 工具集构建失败:无法加载 MSBuild 包装器? - WiX toolset build fails after upgrading from .net 4.0 to 4.6.1: Cannot load MSBuild wrapper?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM