JNA无法读写Windows注册表,计数器值无法更新求助
问题描述
我编写的Java程序每日运行7-8小时,为避免程序崩溃后丢失计数器变量,尝试通过JNA读取和写入Windows注册表来持久化计数器值。但不管用管理员权限运行程序,还是改用HKEY_CURRENT_USER路径跳过权限限制,注册表中的计数器值始终停留在0,不会随程序运行递增。我不太熟悉Java,希望得到解决此问题的帮助。
相关代码如下:
import com.sun.jna.platform.win32.Advapi32; import com.sun.jna.platform.win32.Advapi32Util; import com.sun.jna.platform.win32.WinReg; import com.sun.jna.platform.win32.WinReg.HKEY; import com.sun.jna.platform.win32.WinReg.HKEYByReference; //Sets the data within registry in case of crash try { Advapi32Util.registrySetIntValue(WinReg.HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Session Manager\\Environment", "Tracked Counters", counter); } catch(Throwable e) { return null; } try { int counter = Advapi32Util.registryGetIntValue(WinReg.HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Session Manager\\Environment", "Tracked counters"); } catch(Throwable e) { return null; }
解决方法
1. 修复注册表键名大小写问题
Windows注册表键名区分大小写,你的代码中写入的键名是"Tracked Counters",但读取时用的是"Tracked counters"(最后一个单词首字母小写),这会导致读取不到已写入的值,每次都进入异常分支返回null,计数器始终保持初始的0。
修改读取代码的键名,保持和写入一致:
int counter = Advapi32Util.registryGetIntValue(WinReg.HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Session Manager\\Environment", "Tracked Counters"); // 统一键名大小写
2. 确认写入逻辑的时机与变量值
- 确保调用
registrySetIntValue时,counter已经是递增后的最新值,比如在计数器执行counter++操作后立即触发写入。 - 可以在写入前打印变量值,验证计数器确实在递增:
System.out.println("即将写入注册表的计数器值:" + counter); Advapi32Util.registrySetIntValue(WinReg.HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Session Manager\\Environment", "Tracked Counters", counter);
3. 改用更合适的注册表路径(可选)
HKEY_LOCAL_MACHINE\System\...\Environment是系统环境变量路径,修改需要管理员权限且易受系统操作影响。如果不需要全局共享计数器,建议改用HKEY_CURRENT_USER下的自定义专属路径,无需管理员权限:
// 写入操作 Advapi32Util.registrySetIntValue(WinReg.HKEY_CURRENT_USER, "Software\\MyApp\\Counters", "Tracked Counters", counter); // 读取操作 int counter = Advapi32Util.registryGetIntValue(WinReg.HKEY_CURRENT_USER, "Software\\MyApp\\Counters", "Tracked Counters");
4. 添加异常日志排查问题
原代码的catch块仅返回null,无法定位具体错误原因。建议打印异常详情,帮助排查权限、路径等问题:
try { Advapi32Util.registrySetIntValue(WinReg.HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Session Manager\\Environment", "Tracked Counters", counter); } catch(Throwable e) { e.printStackTrace(); // 打印异常堆栈信息 return null; }
内容的提问来源于stack exchange,提问作者Bobby Singer
相关产品推荐
相关产品推荐

