使用 Java 读取/写入 Windows 注册表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/62289/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read/write to Windows registry using Java
提问by
How is it possible to read/write to the Windows registry using Java?
如何使用 Java 读取/写入 Windows 注册表?
回答by Epaga
Yes, using the java.util.Preferences API, since the Windows implementation of it uses the Registry as a backend.
是的,使用 java.util.Preferences API,因为它的 Windows 实现使用注册表作为后端。
In the end it depends on what you're wanting to do: storing preferences for your app is what the Preferences does just great. If you're wanting to actually change registry keys not having to do with your app, you'll need some JNI app, as described by Mark (shameless steal here):
最后,这取决于您想要做什么:为您的应用程序存储首选项是首选项做得很好的地方。如果您想实际更改与您的应用程序无关的注册表项,您将需要一些 JNI 应用程序,如 Mark 所述(此处无耻的窃取):
From a quick google: Check the WinPack for JNIWrapper. It has full Windows Registry access support including Reading and Writing.
The WinPack Demo has Registry Viewer implemented as an example.
Check at http://www.teamdev.com/jniwrapper/winpack/#registry_access
And...
There is also try JNIRegistry @ http://www.trustice.com/java/jnireg/
There is also the option of invoking an external app, which is responsible for reading / writing the registry.
从一个快速的谷歌:检查 JNIWrapper 的 WinPack。它具有完整的 Windows 注册表访问支持,包括读取和写入。
WinPack Demo 以注册表查看器为例。
检查http://www.teamdev.com/jniwrapper/winpack/#registry_access
和...
还有试试 JNIRegistry @ http://www.trustice.com/java/jnireg/
还有调用外部应用程序的选项,该应用程序负责读取/写入注册表。
回答by Mark Ingram
From a quick google:
从快速谷歌:
Check the WinPack for JNIWrapper. It has full Windows Registry access support including Reading and Writing.
The WinPack Demo has Registry Viewer implemented as an example.
Check at http://www.teamdev.com/jniwrapper/winpack/#registry_access
检查 JNIWrapper 的 WinPack。它具有完整的 Windows 注册表访问支持,包括读取和写入。
WinPack Demo 以注册表查看器为例。
检查 http://www.teamdev.com/jniwrapper/winpack/#registry_access
And...
和...
There is also try JNIRegistry @ http://www.trustice.com/java/jnireg/
还有试试 JNIRegistry @ http://www.trustice.com/java/jnireg/
There is also the option of invoking an external app, which is responsible for reading / writing the registry.
还有调用外部应用程序的选项,该应用程序负责读取/写入注册表。
回答by Vinko Vrsalovic
The Preferences API approach does not give you access to all the branches of the registry. In fact, it only gives you access to where the Preferences API stores its, well, preferences. It's not a generic registry handling API, like .NET's
Preferences API 方法不允许您访问注册表的所有分支。事实上,它只允许您访问 Preferences API 存储其首选项的位置。它不是通用的注册表处理 API,如 .NET 的
To read/write every key I guess JNI or an external tool would be the approach to take, as Mark shows.
读/写每个键,我想 JNI 或外部工具将是采用的方法,正如 Mark 所示。
回答by Ignat
There are few JNDI service providers to work with windows registry.
很少有 JNDI 服务提供者可以使用 Windows 注册表。
One could observe http://java.sun.com/products/jndi/serviceproviders.html.
人们可以观察http://java.sun.com/products/jndi/serviceproviders.html。
回答by Alex Argo
I've done this before using jRegistryKey. It is an LGPL Java/JNI library that can do what you need. Here's an example of how I used it to enabled Registry editing through regedit and also the "Show Folder Options" option for myself in Windows via the registry.
我在使用jRegistryKey之前已经这样做了。它是一个 LGPL Java/JNI 库,可以满足您的需求。这是我如何使用它通过 regedit 启用注册表编辑以及通过注册表在 Windows 中为自己启用“显示文件夹选项”选项的示例。
import java.io.File;
import ca.beq.util.win32.registry.RegistryKey;
import ca.beq.util.win32.registry.RegistryValue;
import ca.beq.util.win32.registry.RootKey;
import ca.beq.util.win32.registry.ValueType;
public class FixStuff {
private static final String REGEDIT_KEY = "Software\Microsoft\Windows\CurrentVersion\Policies\System";
private static final String REGEDIT_VALUE = "DisableRegistryTools";
private static final String REGISTRY_LIBRARY_PATH = "\lib\jRegistryKey.dll";
private static final String FOLDER_OPTIONS_KEY = "Software\Microsoft\Windows\CurrentVersion\Policies\Explorer";
private static final String FOLDER_OPTIONS_VALUE = "NoFolderOptions";
public static void main(String[] args) {
//Load JNI library
RegistryKey.initialize( new File(".").getAbsolutePath()+REGISTRY_LIBRARY_PATH );
enableRegistryEditing(true);
enableShowFolderOptions(true);
}
private static void enableShowFolderOptions(boolean enable) {
RegistryKey key = new RegistryKey(RootKey.HKEY_CURRENT_USER,FOLDER_OPTIONS_KEY);
RegistryKey key2 = new RegistryKey(RootKey.HKEY_LOCAL_MACHINE,FOLDER_OPTIONS_KEY);
RegistryValue value = new RegistryValue();
value.setName(FOLDER_OPTIONS_VALUE);
value.setType(ValueType.REG_DWORD_LITTLE_ENDIAN);
value.setData(enable?0:1);
if(key.hasValue(FOLDER_OPTIONS_VALUE)) {
key.setValue(value);
}
if(key2.hasValue(FOLDER_OPTIONS_VALUE)) {
key2.setValue(value);
}
}
private static void enableRegistryEditing(boolean enable) {
RegistryKey key = new RegistryKey(RootKey.HKEY_CURRENT_USER,REGEDIT_KEY);
RegistryValue value = new RegistryValue();
value.setName(REGEDIT_VALUE);
value.setType(ValueType.REG_DWORD_LITTLE_ENDIAN);
value.setData(enable?0:1);
if(key.hasValue(REGEDIT_VALUE)) {
key.setValue(value);
}
}
}
回答by Alex Argo
The WinPack Demo has Registry Viewer implemented as an example.
Check at http://www.jniwrapper.com/winpack_features.jsp#registry
WinPack Demo 以注册表查看器为例。
BTW, WinPack has been moved to the following address:
顺便说一句,WinPack 已移至以下地址:
回答by Peter Smith
回答by Oleg Ryaboy
You don't actually need a 3rd party package. Windows has a reg utility for all registry operations. To get the command format, go to the DOS propmt and type:
您实际上并不需要第 3 方软件包。Windows 有一个用于所有注册表操作的 reg 实用程序。要获取命令格式,请转到 DOS 提示并键入:
reg /?
You can invoke regthrough the Runtime class:
您可以通过 Runtime 类调用reg:
Runtime.getRuntime().exec("reg <your parameters here>");
Editing keys and adding new ones is straightforward using the command above. To read the registry, you need to get reg's output, and it's a little tricky. Here's the code:
使用上面的命令编辑键和添加新键很简单。要读取注册表,您需要获取reg的输出,这有点棘手。这是代码:
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
/**
* @author Oleg Ryaboy, based on work by Miguel Enriquez
*/
public class WindowsReqistry {
/**
*
* @param location path in the registry
* @param key registry key
* @return registry value or null if not found
*/
public static final String readRegistry(String location, String key){
try {
// Run reg query, then read output with StreamReader (internal class)
Process process = Runtime.getRuntime().exec("reg query " +
'"'+ location + "\" /v " + key);
StreamReader reader = new StreamReader(process.getInputStream());
reader.start();
process.waitFor();
reader.join();
String output = reader.getResult();
// Output has the following format:
// \n<Version information>\n\n<key>\t<registry type>\t<value>
if( ! output.contains("\t")){
return null;
}
// Parse out the value
String[] parsed = output.split("\t");
return parsed[parsed.length-1];
}
catch (Exception e) {
return null;
}
}
static class StreamReader extends Thread {
private InputStream is;
private StringWriter sw= new StringWriter();
public StreamReader(InputStream is) {
this.is = is;
}
public void run() {
try {
int c;
while ((c = is.read()) != -1)
sw.write(c);
}
catch (IOException e) {
}
}
public String getResult() {
return sw.toString();
}
}
public static void main(String[] args) {
// Sample usage
String value = WindowsReqistry.readRegistry("HKCU\Software\Microsoft\Windows\CurrentVersion\"
+ "Explorer\Shell Folders", "Personal");
System.out.println(value);
}
}
回答by Tom Anderson
As has been noted, the Preferences API uses the registry to store preferences, but cannot be used to access the whole registry.
如前所述,首选项 API 使用注册表来存储首选项,但不能用于访问整个注册表。
However, a pirate called David Croft has worked out that it's possible to use methods in Sun's implementation of the Preferences API for reading the Windows registry from Java without JNI. There are some dangers to that, but it is worth a look.
然而,一个叫 David Croft 的盗版者发现,可以使用 Sun 的 Preferences API 实现中的方法从 Java 读取 Windows 注册表,而无需 JNI。这有一些危险,但值得一看。
回答by gousli
Here's a modified version of Oleg's solution. I noticed that on my system (Windows server 2003), the output of "reg query" is not separated by tabs ('\t'), but by 4 spaces.
这是 Oleg 解决方案的修改版本。我注意到在我的系统(Windows Server 2003)上,“reg query”的输出不是由制表符('\t')分隔,而是由 4 个空格分隔。
I also simplified the solution, as a thread is not required.
我还简化了解决方案,因为不需要线程。
public static final String readRegistry(String location, String key)
{
try
{
// Run reg query, then read output with StreamReader (internal class)
Process process = Runtime.getRuntime().exec("reg query " +
'"'+ location + "\" /v " + key);
InputStream is = process.getInputStream();
StringBuilder sw = new StringBuilder();
try
{
int c;
while ((c = is.read()) != -1)
sw.append((char)c);
}
catch (IOException e)
{
}
String output = sw.toString();
// Output has the following format:
// \n<Version information>\n\n<key> <registry type> <value>\r\n\r\n
int i = output.indexOf("REG_SZ");
if (i == -1)
{
return null;
}
sw = new StringBuilder();
i += 6; // skip REG_SZ
// skip spaces or tabs
for (;;)
{
if (i > output.length())
break;
char c = output.charAt(i);
if (c != ' ' && c != '\t')
break;
++i;
}
// take everything until end of line
for (;;)
{
if (i > output.length())
break;
char c = output.charAt(i);
if (c == '\r' || c == '\n')
break;
sw.append(c);
++i;
}
return sw.toString();
}
catch (Exception e)
{
return null;
}
}
}