我有一个使用标准ApplicationSettingsBase
的C#程序来保存其用户设置。这在.NET 3.5下工作正常。并且只要创建了我的程序的新版本,提供的Upgrade()
方法就会正确地“重新加载”这些设置。
最近,我用.NET 4.0重新编译了程序。我的程序的版本号也增加了。但是,当我运行此版本时,Upgrade()
似乎无法检测到任何先前的版本设置,并且不会“重新加载”它们。它开始是空白的。
作为测试,我再次重新编译,回到.NET 3.5。而这一次,Upgrade()
方法又开始工作了。
切换框架时是否有办法允许Upgrade()
工作?还有其他我想念的东西吗?
答案 0 :(得分:6)
我遇到了完全相同的问题,我再次从.NET 3.5重新编译到.NET 4.0进行了多次测试。
不幸的是,我的解决方案是在vb.net中,但我确信您可以使用众多转换程序之一在c#中查看此内容,例如http://www.developerfusion.com/tools/convert/vb-to-csharp/
它涉及枚举%AppData%\ CompanyName 中的所有文件夹,以在您要升级的版本的文件夹名称中查找最新的 user.config 文件
我发现在Visual Studio 2010下将我的应用程序重新编译到.NET 4.0会创建一个名为%AppData%\ CompanyName \ AppName.exe_Url_blahbahblah 的新文件夹,即使我完全没有更改其他设置或完全没有代码!
我在.NET 4.0之前的所有版本都保留了相同的文件夹名称并成功升级。将旧的user.config文件(和版本文件夹名称)从旧文件夹复制到在.NET 4.0下创建的新文件夹结构(使用旧版本文件夹名称)可以解决问题 - 它现在将升级。
此示例假设您有一个名为 IUpgraded 的用户设置,默认情况下设置为 False (稍后设置为True)以检查设置是否为初始设置是否取消值 - 您可以使用您创建的任何其他变量。该示例显示从版本1.2.0.0升级到更高版本,您可以通过更改 lastVersion 的值来更改。
代码将放在最新(.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
答案 1 :(得分:4)
这是代码。
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 );
}
}
}
这可以帮助你:)
答案 2 :(得分:0)
当Settings1.Upgrade()无法正常运行时,请尝试删除以前的用户配置文件,然后重试。
就我而言,发行版和调试版本不相关,因此升级似乎失败,因为同一目录中与调试/发行版输出相关的版本之间存在冲突。
清除所有以前的用户配置文件(appdata \ local ....)似乎可以解决问题,调用Upgrade()可以正常工作,并且这里提出的解决方法也可以正常工作。
我希望它对您有用。