VS2013用户范围应用设置Save后仍返回默认值如何解决
按优先级依次排查以下问题,基本能覆盖90%以上的同类故障:
首先确认设置作用域配置正确
右键项目 → 选择「属性」→ 切换到「设置」页,找到strLevDeci配置项,确认其范围列选中的是「用户」而非「应用程序」。应用程序范围的配置项是只读的,运行时赋值不会生效,调用Save()也不会持久化修改,读取时永远返回app.config里预置的默认值。如果配置错误,修改范围后重新生成项目再测试。排查是否存在静默的保存异常
很多时候配置文件写入权限不足、文件被占用的异常会被全局异常处理逻辑吞掉,没有任何提示。给保存逻辑加异常捕获,确认Save操作是否真的执行成功:try { string transSet = txtSetting.Text; Properties.Settings.Default.strLevDeci = transSet; Properties.Settings.Default.Save(); // 调试时可加这行,确认保存后内存中的值是否正确 System.Diagnostics.Debug.WriteLine($"保存后内存值:{Properties.Settings.Default.strLevDeci}"); } catch (Exception ex) { MessageBox.Show($"设置保存失败:{ex.Message}"); }用户范围配置默认存储在
C:\Users\<当前系统用户名>\AppData\Local\<你的程序集对应公司名>\<程序集标识哈希>\<程序版本号>\user.config路径下,如果程序放在系统盘受UAC保护的目录运行、或者开了程序兼容虚拟化,可能出现写入路径和读取路径不一致的问题,测试时可以把程序放到非系统保护目录(比如D盘自建文件夹)运行验证。排查程序集版本号自动变更问题
打开项目下的Properties/AssemblyInfo.cs文件,查看程序集版本配置:如果是[assembly: AssemblyVersion("1.0.*")]这类带通配符的写法,每次编译生成的程序集版本号都会变化,程序启动时只会匹配对应版本号目录下的user.config,找不到就会加载默认值,之前版本保存的配置不会自动读取。
解决方法有两种:- 把版本号改成固定值,比如
[assembly: AssemblyVersion("1.0.0.0")] - 增加跨版本升级配置的逻辑,在程序入口处添加如下代码,同时需要在设置页新增一个bool类型的用户范围配置
UpgradeRequired,默认值设为true:// 主窗体构造函数或者Program.Main方法里加 if (Properties.Settings.Default.UpgradeRequired) { Properties.Settings.Default.Upgrade(); Properties.Settings.Default.UpgradeRequired = false; Properties.Settings.Default.Save(); }
- 把版本号改成固定值,比如
排除Reload调用的干扰
你当前读取逻辑里第一行就调用了Reload(),这个方法会强制从磁盘重新加载配置文件,如果在Save操作还没完成磁盘写入时就调用Reload、或者其他逻辑里提前调用了Reset()方法重置配置,都会导致读取到默认值。测试阶段可以先去掉Reload()调用,保存完成后直接读取值,确认内存中的赋值和持久化是否正常。ClickOnce部署特殊问题排查
如果你是用ClickOnce方式部署程序,用户配置存储在ClickOnce独立缓存中,如果缓存损坏也会出现配置无法持久化的问题,可以手动删除对应AppData目录下的ClickOnce应用缓存,重新安装程序后测试。
内容的提问来源于stack exchange,提问作者R Kay

