You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 7下ClickOnce发布后用户设置无法保留更新求助

.NET 7 ClickOnce发布后用户设置丢失的解决方案

问题根源

.NET 5+(包括.NET7)的ClickOnce用户设置存储路径依赖程序集的唯一标识,升级自.NET Framework 4.7.2后,程序集标识(如强名称、哈希值)变化,导致系统无法识别旧的user.config文件,每次修改设置都会生成新的存储文件夹。


一、配置强名称签名(保持程序集标识一致)

VS2022中.NET7项目的强名称签名选项位置已调整,操作步骤:

  • 打开项目属性,切换到Signing标签页
  • 勾选Sign the assembly复选框
  • 点击Choose a strong name key file:
    • 若旧.NET4.7.2项目已使用强名称签名,导入原有的.snk密钥文件(必须与旧项目一致,否则仍无法识别旧设置)
    • 若旧项目未签名,新建一个.snk文件并留存,后续所有发布版本必须使用该文件,确保程序集标识稳定

二、迁移旧用户设置(针对已出现路径变化的情况)

如果已经生成新的设置文件夹,可通过手动或代码方式迁移旧设置:

手动迁移

  1. 找到旧设置路径:C:\Users\[用户名]\AppData\Local\[发布者名]\[应用名]_Url_[旧随机串]\[旧版本号]
  2. 复制该文件夹内的user.config文件到新的设置文件夹(路径格式类似,仅随机串/版本号不同)

代码自动迁移

在应用启动时添加逻辑,读取旧设置并写入新配置:

Imports System.Configuration
Imports System.IO

Private Sub MigrateLegacySettings()
    ' 获取当前设置的路径模板
    Dim currentConfigPath = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath
    ' 替换为旧路径的标识(需根据实际旧路径修改[旧随机串]和[旧版本号])
    Dim legacyConfigPath = currentConfigPath.Replace("[新随机串]", "[旧随机串]").Replace("[新版本号]", "[旧版本号]")

    If File.Exists(legacyConfigPath) Then
        Dim legacyConfig = ConfigurationManager.OpenMappedExeConfiguration(
            New ExeConfigurationFileMap With {.ExeConfigFilename = legacyConfigPath},
            ConfigurationUserLevel.None
        )

        ' 遍历旧设置项,同步到当前设置
        For Each setting As KeyValueConfigurationElement In legacyConfig.AppSettings.Settings
            If My.Settings.Properties.Contains(setting.Key) Then
                My.Settings(setting.Key) = setting.Value
            End If
        Next

        My.Settings.Save()
    End If
End Sub

将上述方法放在主窗体的Form_Load事件或应用启动入口处调用。


三、确保ClickOnce发布标识一致

  • 发布项目时,在Publish设置中,保持Product name、Publisher name与旧项目完全一致
  • 检查Application identity中的名称设置,避免因应用标识变更导致存储路径变化

四、替代方案:自定义设置存储

若强名称签名方案不适用,可放弃默认的My.Settings,改用自定义固定路径存储设置:

Imports System.IO
Imports System.Text.Json

Public Class AppSettings
    ' 定义需要存储的设置项
    Public Property WindowLocation As Point
    Public Property LastOpenedFile As String
    Public Property Theme As String = "Light"

    ' 保存设置到固定路径
    Public Sub Save()
        Dim configDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "YourAppName")
        Directory.CreateDirectory(configDir)
        Dim configPath = Path.Combine(configDir, "appsettings.json")
        
        File.WriteAllText(configPath, JsonSerializer.Serialize(Me, New JsonSerializerOptions With {.WriteIndented = True}))
    End Sub

    ' 加载设置
    Public Shared Function Load() As AppSettings
        Dim configDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "YourAppName")
        Dim configPath = Path.Combine(configDir, "appsettings.json")
        
        If File.Exists(configPath) Then
            Return JsonSerializer.Deserialize(Of AppSettings)(File.ReadAllText(configPath))
        End If
        Return New AppSettings()
    End Function
End Class

使用时,在应用启动调用AppSettings.Load()获取设置,关闭时调用Save()保存,不受ClickOnce发布版本影响。


内容的提问来源于stack exchange,提问作者Glen Attwood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:25:40