How can I write System preferences with Java? Can

2019-08-04 00:13发布

问题:

How can I write system preferences with Java, using Preferences.systemRoot()?

I tried with:

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

But I got this error message:

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)

I would like to do this, because I want to install an embedded JavaDB database, and let multiple users on the computer to use the same database with the application.

How to solve this? Can I invoke UAC and do this as Administrator from Java? And if I log in as Administrator when writing, can I read the values with my Java application if I'm logged in as a User?

回答1:

You cannot write to any arbitrary registry location from java preferences - all preferences are stored under a subkey Software\Javasoft\Prefs. With user preferences mapping to the HKEY_CURRENT_USER hive, and system mapping to the HKEY_LOCAL_MACHINE hive.

To write to the registry, you could use the windows "REG" command line tool. This page details other ways of modifying the registry. including use of .reg files.

I had the same need - to write to the registry from java - I solved it by writing a small .NET command line utility to do it.

The Sun Windows JDK does ship with generic code to write to arbitrary portions of the registry (WindowsPreferences), but it's not public. This article describes how to access this class using reflection.



回答2:

You can't edit Preferences.systemRoot() if User Account Control is turned on. Seems like Microsoft went and broke it. There is a workaround here, but it's not straightforward.



回答3:

So I had this same issue, so I opened an issue with Oracle: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7043176

I was able to work around it myself, by writing a custom implementation of AbstractPreferences and a corresponding PreferencesFactory. What I did was on Windows have the system preferences write to the application data directory defined in the registry by: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Common AppData

I used Runtime.getRuntime().exec("reg query \""+key+ "\" /v \""+value+"\"") to get that (works even with UAC turned on).

That evaluates to "C:\ProgramData" on Windows 7 and "C:\Documents and Settings\All Users\Application Data" on XP. I added a subdirectory called "JavaPreferences" and wrote an implementation that uses a properties file as the backend.

As a side note, I had a similar issue with system preferences on Linux because the installer for the JRE was not run by root so I didn't have access to "/etc/.java". A ended up picking another custom directory and granting permissions for that.