0

当它是一个 clickonce 程序时,它可以工作,但后来我制作了一个 appxpackage 并将其导出为 windows 商店的百年应用程序,并且升级不再起作用。

现在我在 App.xaml.cs

protected override void OnStartup(StartupEventArgs e) {
   if (myprog.Properties.Settings.Default.UpgradeRequired)
   {    
      myprog.Properties.Settings.Default.Upgrade();
      myprog.Properties.Settings.Default.UpgradeRequired = false;
      myprog.Properties.Settings.Default.Save();
   }

使用 UpgradeRequired 作为用户设置中的布尔值。那是正确的地方吗?

我在每次版本更新时都会重置设置。现在我有几个这样的目录

C:\Users\me\AppData\Local\progname\prog.exe_Url_randomChars

每个都有几个不同版本的程序设置。因此,升级后会创建另一个,而不是当前版本的 xxxx 子文件夹。

和以前一样,在每个版本发布时,我都会在程序集信息中增加版本,即程序集版本、文件版本,现在我在 AppxManifest.xml 中有相同的数字。我按照建议将版本的最后一个数字组保持为 0,然后增加第三个数字组。

有什么我想念的吗?

4

3 回答 3

1

UWP 和桌面桥应用需要将其设置存储在 ApplicationData.LocalSettings 中:

https://docs.microsoft.com/en-us/windows/uwp/design/app-settings/store-and-retrieve-app-data#local-app-data

于 2018-04-18T23:08:03.080 回答
0

您可以将以前的 user.config 文件加载到当前设置中。这只是一种解决方法,可用于转换到 ApplicationData.LocalSettings。

public static void Init()
{
    if (myprog.Properties.Settings.Default.UpgradeRequired)
    {    
        LoadPreviousSettings(myprog.Properties.Settings.Default);
        myprog.Properties.Settings.Default.UpgradeRequired = false;
        myprog.Properties.Settings.Default.Save();
    }
}

private static void LoadPreviousSettings(params ApplicationSettingsBase[] applicationSettings)
{
    const string companyName = "YOUR_COMPANY_NAME_HERE";
    var userConfigXml = GetUserConfigXml(companyName);
    Configuration config = ConfigurationManager.OpenExeConfiguration(
        ConfigurationUserLevel.PerUserRoamingAndLocal);
    foreach (ApplicationSettingsBase setting in applicationSettings)
    {
        try
        {
            // loads settings from user.config into configuration
            LoadSettingSection(setting, config, userConfigXml);
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("userSettings");
        }
        catch (FileNotFoundException)
        {
            // Could not import settings.
            // Perhaps user has no previous version installed
        }
        setting.Reload();
    }

}

private static void LoadSettingSection(ApplicationSettingsBase setting, Configuration config, XDocument userConfigXml)
{
    string appSettingsXmlName = setting.ToString();
    var settings = userConfigXml.XPathSelectElements("//" + appSettingsXmlName);
    config.GetSectionGroup("userSettings")
        .Sections[appSettingsXmlName]
        .SectionInformation
        .SetRawXml(settings.Single().ToString());
}

private static XDocument GetUserConfigXml(string companyName)
{
    var localPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + $@"\{companyName}";
    // previous package folder
    var previousLocal = GetDirectoryByWriteTime(localPath, 1);
    // previous version, e.g. 1.2.0
    var prevousVersion = GetDirectoryByWriteTime(previousLocal, 0);
    // application settings for previous version
    return XDocument.Load(prevousVersion + @"\user.config");
}

private static string GetDirectoryByWriteTime(string path, int order)
{
    var direcotires = new DirectoryInfo(path).EnumerateDirectories()
        .OrderBy(d => d.LastWriteTime)
        .Reverse()
        .ToList();
    if (direcotires.Count > order)
    {
        var previous = direcotires[order];
        return previous.FullName;
    }
    throw new FileNotFoundException("Previous config file not found.");
}
于 2020-10-13T14:47:40.153 回答
0

这里有一个有效的答案

基本上,您需要使用 UWP 创建一个重复版本ApplicationData.Settings,然后在应用程序的开头加载它。当您的设置是字符串、布尔值等时,这非常简单。但如果您有独特的设置,则不是这样。

要详细说明链接中的答案,当您有由自定义类型/类组成的设置时,在创建 UWP 的重复版本时,您可以使用 Newtonsoft.Json 序列化自定义设置:

try
{
    ApplicationData.Current.LocalSettings.Values[value.Name] = value.PropertyValue;
}
catch
{
    string serialised = JsonConvert.SerializeObject(value.PropertyValue);
    ApplicationData.Current.LocalSettings.Values[value.Name] = serialised;
}

然后在加载您的自定义设置时:

if (s.Name == "MyCustomSetting")
{
    var deserialised = JsonConvert.DeserializeObject<MyCustomClass>((string)setting.Value);
    s.PropertyValue = deserialised;
}
于 2020-11-20T10:31:42.037 回答