【问题标题】:How can I write System preferences with Java? Can I invoke UAC?如何使用 Java 编写系统首选项?我可以调用 UAC 吗?
【发布时间】:2010-05-29 17:16:16
【问题描述】:

如何使用 Java 编写系统首选项,使用 Preferences.systemRoot()

我试过了:

Preferences preferences = Preferences.systemRoot();
preferences.put("/myapplication/databasepath", pathToDatabase);

但我收到此错误消息:

2010-maj-29 19:02:50 java.util.prefs.WindowsPreferences openKey
VARNING: Could not open windows registry node Software\JavaSoft\Prefs at root 0x80000002. Windows RegOpenKey(...) returned error code 5.
Exception in thread "AWT-EventQueue-0" java.lang.SecurityException: Could not open windows registry node Software\JavaSoft\Prefs at root 0x80000002: Access denied
    at java.util.prefs.WindowsPreferences.openKey(Unknown Source)
    at java.util.prefs.WindowsPreferences.openKey(Unknown Source)
    at java.util.prefs.WindowsPreferences.openKey(Unknown Source)
    at java.util.prefs.WindowsPreferences.putSpi(Unknown Source)
    at java.util.prefs.AbstractPreferences.put(Unknown Source)
    at org.example.install.Setup$2.actionPerformed(Setup.java:43)

我想这样做,因为我想安装一个嵌入式 JavaDB 数据库,并让计算机上的多个用户与应用程序一起使用同一个数据库。

如何解决这个问题?我可以调用 UAC 并以 Java 管理员身份执行此操作吗?如果我在写入时以管理员身份登录,如果我以用户身份登录,我可以使用我的 Java 应用程序读取这些值吗?

【问题讨论】:

    标签: java windows uac preferences securityexception


    【解决方案1】:

    您不能从 java 首选项写入任意注册表位置 - 所有首选项都存储在子键 Software\Javasoft\Prefs 下。用户首选项映射到 HKEY_CURRENT_USER 配置单元,系统映射到 HKEY_LOCAL_MACHINE 配置单元。

    要写入注册表,您可以使用 Windows 的“REG”命令行工具。 This page 详细介绍了修改注册表的其他方法。包括使用.reg 文件。

    我也有同样的需求 - 从 java 写入注册表 - 我通过编写一个小的 .NET 命令行实用程序来解决它。

    Sun Windows JDK 附带通用代码以写入注册表的任意部分 (WindowsPreferences),但它不是公开的。 This article 描述了如何使用反射访问这个类。

    【讨论】:

    • 所以我不能在Software\Javasoft\PrefsPreferences.systemRoot() 上写字,是不是只针对Preferences.userRoot()?我在哪里写它并不重要,我只想为每个用户提供它,还是Preferences.systemRoot()没有用?
    • 所有根都写在 Syftware\JavaSoft\Prefs 下。用户 root 写入注册表的用户部分,系统 root 写入系统(即需要管理员权限)。无论哪种方式,您都不能在 Software\javasoft\prefs 上方写入。为此,请参阅我的答案的第二部分。
    • 啊,谢谢。所以问题是:当我没有以管理员身份登录时,如何将系统根写入Software\Javasoft\Prefs(需要管理员权限)?是否可以使用 UAC 或类似技术(即 java 技术)? 或者,如果我以管理员身份写入系统根目录,我可以以用户身份读取这些值吗?
    • 您始终可以以用户身份读取系统根目录,因此以管理员身份登录并写入,您的用户可以读取。要以管理员身份编写,您当然需要管理员权限。 Windows 可以授予 MSI 安装程序提升的管理员权限,因此您可以将您的应用程序安装为可以写入系统首选项(HKLM 配置单元)的 MSI。我过去使用过 AdvancedInstaller,有一个免费版本可用。
    【解决方案2】:

    如果用户帐户控制已打开,您将无法编辑 Preferences.systemRoot()。似乎微软去打破了它。有一个解决方法here,但并不简单。

    【讨论】:

    • “微软好像把它搞砸了。” UAC 是微软为数不多的真正有效的安全举措之一。不要没有它就离开家。
    • 确实如此,但提高安全性往往会破坏事情。
    【解决方案3】:

    所以我遇到了同样的问题,所以我向 Oracle 提出了一个问题: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7043176

    我可以自己解决这个问题,方法是编写 AbstractPreferences 的自定义实现和相应的 PreferencesFactory。我所做的是在 Windows 上通过以下方式将系统首选项写入注册表中定义的应用程序数据目录: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Common AppData

    我使用Runtime.getRuntime().exec("reg query \""+key+ "\" /v \""+value+"\"") 来获得它(即使打开了 UAC 也可以使用)。

    在 Windows 7 上计算为“C:\ProgramData”,在 XP 上计算为“C:\Documents and Settings\All Users\Application Data”。我添加了一个名为“JavaPreferences”的子目录并编写了一个使用属性文件作为后端的实现。

    附带说明一下,我在 Linux 上的系统偏好设置方面遇到了类似的问题,因为 JRE 的安装程序不是由 root 运行的,所以我无权访问“/etc/.java”。 A 最终选择了另一个自定义目录并为此授予权限。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      • 2018-01-18
      • 1970-01-01
      • 2011-10-16
      • 1970-01-01
      • 2022-10-01
      • 1970-01-01
      相关资源
      最近更新 更多