`

Java操作Windows注册表实例

阅读更多
Microsoft Windows 9x、Windows CE、Windows NT和Windows 2000中使用的中央分层数据库,用于存储为一个或多个用户、应用程序和硬件设备配置系统所必需的信息。
Microsoft Windows 9x、Windows CE、Windows NT和Windows 2000中使用的中央分层数据库,用于存储为一个或多个用户、应用程序和硬件设备配置系统所必需的信息。

注册表包含 Windows 在运行期间不断引用的信息,例如,每个用户的配置文件、计算机上安装的应用程序以及每个应用程序可以创建的文档类型、文件夹和应用程序图标的属性表设置、系统上存在哪些硬件以及正在使用哪些端口。

注册表取代了 Windows 3.x 和 MS-DOS 配置文件(例如,Autoexec.bat 和 Config.sys)中使用的绝大多数基于文本的 .ini 文件。虽然几个 Windows 操作系统都有注册表,但这些操作系统的注册表有一些区别。

如果您对以上的内容还不了解,那么您可能需要阅读一下这篇文章《Microsoft Windows 注册表说明》,可以从参考资料中找到,同时还可以找到它的英文原文"Description of the Microsoft Windows registry"。

如果您理解上面的内容就可以往下继续了。

回页首
使用Preferences API
Preferences API并不是为访问Windows注册表而设计的,这是值得指出的一点。

我们之所以会有上面的误解是由于Sun的Windows版本的JDK在实现Preferences API时使用了Windows注册表作为存储库,即我们用Preferences API存储的数据会保存到Windows注册表中,这样Preferenes API也就有了访问Windows注册表的能力。但是换到其它的平台或其它厂商的JDK实现又会怎么样呢?这个问题是和Preferences API的实现相关的,我们没有办法回答。

如果程序不关心存储库的细节,只是要找一个存放数据的地方,那么Preferences API很合适。

Preferences API也是有局限的,请您考虑两个问题:

一个Java软件,这次我在Sun的JDK上运行并使用Preferences API保存了我的个人喜好,下次我在IBM的JDK上运行,这时我的个人喜好还可以通过Preferences API得到吗?可能可以也可能不可以,这时的行为是由Sun和IBM的Preferences API实现决定的。(在相同的JDK实现上可以使用Preferences API来在不同的程序间共享数据)
一个Java软件需要让用户设置是否和操作系统一起启动,类似的需求还很多。这类需求就是要求Java程序有真正的和相关操作系统协同的能力。这种能力不是Preferences API的设计目标。

如果您对Preferences API还不了解,那么您可能需要阅读一下这篇文章《用Preferences API存储对象》,可以从参考资料中找到。

回页首
使用JNI
Windows操作系统提供了操作注册表的API,因此用JNI将Java和这些API连接起来我们就获得了用Java操作注册表的能力。这说起来有些简单,实现起来却需要处理大量的细节。幸运的是这样的工作已经有人做了,我们要感谢他们。下面我们就来看看其中的一个包。

com.ice.jni.registry包是通过JNI(Java native interface)实现的Windows注册表操作API,可以用来访问、修改和导出Windows注册表。现在这个包已经公开了,可以放心的使用而不必担心license的问题,并且包括一个构建好的DLL和Java、C的源代码。它可以在Java 1.1和更高的版本上工作。

如果您向我一样也对JNI感兴趣,那么这也是学习JNI的很好的示例。

下面详细的描述一下这个包中的类,数量不是很多:

HexNumberFormat 用来格式化和分析十六进制整数。
RegBinaryValue 表示类型为REG_BINARY的注册表值。REG_BINARY是指任意形式的二进制数。
RegDWordValue 表示类型为REG_DWORD的注册表值。REG_DWORD是指一个32位的整数。根据该整数的字节序不同又分为REG_DWORD_LITTLE_ENDIAN和REG_DWORD_BIG_ENDIAN。在Windows中REG_DWORD和REG_DWORD_LITTLE_ENDIAN有相同的含义。
RegistryValue 表示任意类型的注册表值,这是一个抽象类,不能被实例化。
RegMultiStringValue 表示类型为REG_MULTI_SZ的注册表值。REG_MULTI_SZ是一个null-terminated的字符串的序列。
RegStringValue 表示类型为REG_SZ和REG_EXPAND_SZ的注册表值。REG_SZ是指一个null-terminated的字符串,REG_EXPAND_SZ是指一个含有未展开的环境变量的null-terminated的字符串。
Registry 这个类定义了定级项(Key),包括HKEY_CLASSES_ROOT、HKEY_CURRENT_CONFIG、HKEY_CURRENT_USER、HKEY_DYN_DATA、HKEY_LOCAL_MACHINE、HKEY_PERFORMANCE_DATA和HKEY_USERS。还定义了错误代码,这些错误代码会包含在RegistryException中。最后是一些工具方法,如dumpHexData、exportRegistryKey、getErrorMessage、getTopLevelKey、openSubkey、parseArgumentString、parseArgumentVector、splitString和usage。
RegistryKey 定义了注册表的一个表项(Key)和相关的一些操作。

如果您需要了解更多的细节,请查阅参考资料中的JNIRegistry的Java doc、Registry和Registry Reference。

RegistryKey的方法概要:

方法 简短描述
void closeKey() 关闭该subkey。 
RegistryKey connectRegistry(java.lang.String hostName) 连接远程主机hostName的注册表。 
RegistryKey createSubKey(java.lang.String subkey, java.lang.String className) 创建和打开该key的subkey,具有写权限。 
RegistryKey createSubKey(java.lang.String subKey, java.lang.String className, int access) 创建和打开该key的subkey,具有指定的权限。 
int decrDoubleWord(java.lang.String valueName) 该方法将消减REG_DWORD的值。 
void deleteSubKey(java.lang.String subKey) 删除该subkey。 
void deleteValue(java.lang.String valueName) 删除一个命名的值。 
static java.lang.String expandEnvStrings(java.lang.String exString) 展开exString中的环境变量。 
void export(java.io.PrintWriter out, boolean descend) 导出key。 
void finalize() 重载了的finalize()方法,确保能够关闭key。 
void flushKey() 确保这个key被写到磁盘,对性能有一定的影响。 
java.lang.String getDefaultValue() 得到该key的默认值。 
java.lang.String getFullName() 得到key的全名。 
int getMaxSubkeyLength() 得到所有subkey名称的最大长度。 
int getMaxValueDataLength() 得到所有subkey值的最大长度。 
int getMaxValueNameLength() 得到所有值的名称的最大长度。 
java.lang.String getName() 得到该key的名称。 
int getNumberSubkeys() 得到subkey的数量。 
int getNumberValues() 得到值的数量。 
java.lang.String getStringValue(java.lang.String valueName) 得到REG_SZ或REG_EXPAND_SZ的值。 
RegistryValue getValue(java.lang.String valueName) 得到valueName的值。 
boolean hasDefaultValue() 判断该key是否有默认值。 
boolean hasOnlyDefaultValue() 判断该key是否只有默认值。 
int incrDoubleWord(java.lang.String valueName) 该方法将增强REG_DWORD的值。 
java.util.Enumeration keyElements() 枚举该key的subkey的名称。 
RegistryKey openSubKey(java.lang.String subkey) 打开该key的subkey,具有读权限。 
RegistryKey openSubKey(java.lang.String subKey, int access) 打开该key的subkey,具有指定的权限。 
java.lang.String regEnumKey(int index) 得到该key在index处的subkey。 
java.lang.String regEnumValue(int index) 得到该key在index处的subkey的值。 
void setCreated(boolean created) 设置该key的created状态。 
void setValue(RegistryValue value) 设置该key的值。 
void setValue(java.lang.String valueName, RegistryValue value) 设置valueName的值。 
java.util.Enumeration valueElements() 枚举该key的值的名称。 
boolean wasCreated() 判断该key是被opened还是被created和opened。 


最后我们来看一个代码示例:

package org.solol.test;

import com.ice.jni.registry.NoSuchKeyException;
import com.ice.jni.registry.RegStringValue;
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryException;
import com.ice.jni.registry.RegistryKey;

/**
 * @author solo L
 *
 */
public class JNIRegistryTest {

  /**
   * @param args
   */
  public static void main(String[] args) {
    //创建注册表项并设置相应的值
    try {
      RegistryKey software = Registry.HKEY_LOCAL_MACHINE.openSubKey("SOFTWARE");

      RegistryKey subKey = software.createSubKey("SubKeyName", "");

      subKey.setValue(new RegStringValue(subKey, "subKey1", "subKey1Value"));
      subKey.setValue(new RegStringValue(subKey, "subKey2", "subKey2Value"));
      subKey.closeKey();
    } catch (NoSuchKeyException e) {
      e.printStackTrace();
    } catch (RegistryException e) {
      e.printStackTrace();
    }
  
    //打开注册表项并读出相应的值
    try {
      RegistryKey software = Registry.HKEY_LOCAL_MACHINE.openSubKey("SOFTWARE");
      RegistryKey subKey = software.openSubKey("SubKeyName");
      String subKey1Value = subKey.getStringValue("subKey1");
      String subKey2Value = subKey.getStringValue("subKey2");
      System.out.println(subKey1Value);
      System.out.println(subKey2Value);
      subKey.closeKey();
    } catch (NoSuchKeyException e) {
      e.printStackTrace();
    } catch (RegistryException e) {
      e.printStackTrace();
    }   
  }
}
创建的注册表项如图所示

分享到:
评论

相关推荐

    java 读取注册表(源码 + jar + dll)

    在Java编程环境中,有时我们需要与操作系统进行交互,例如读取或修改Windows注册表中的信息。在Java标准库中并没有提供直接操作注册表的API,但可以通过一些第三方库来实现这一功能。这里提到的"java 读取注册表...

    基于Java的实例源码-注册表操作类 jared.zip

    "基于Java的实例源码-注册表操作类 jared.zip" 提供了一个用Java实现的注册表操作类,这对于理解如何在Java应用程序中与Windows注册表交互非常有帮助。下面将详细介绍这个知识点。 首先,Windows注册表是一个存储...

    java下操作注册表方法优质资料.doc

    JNI 允许 Java 代码调用本地(操作系统特定)代码,从而能够直接操作 Windows API 来操作注册表。不过,这将丧失 Java 的跨平台特性,并且需要编写 C/C++ 代码与 Java 代码交互。 总结来说,Java 通过 `java.util....

    JRegistry-1.8java操作注册表最新资料(推荐).rar

    JRegistry库就是专为此目的设计的,版本1.8提供了对Windows注册表的简便访问和操作。在这个压缩包中,你将找到关于如何使用JRegistry进行注册表操作的最新资料,包括一个推荐的实用工具类。 JRegistry库允许Java...

    registry.jar java读写注册表的开源库

    `registry.jar`是一个专门为Java设计的开源库,它允许开发者在Java应用程序中方便地访问和修改Windows注册表。这个库名为`registry3.1.3.jar`,包含了源代码,使得开发者可以深入理解其内部工作原理,同时也提供了`...

    java串口编程小实例

    阅读文档将有助于解决可能出现的问题,比如在Windows上可能需要修改注册表,而在Linux上可能需要添加运行时权限。 这个小实例是一个很好的起点,可以帮助初学者快速掌握Java串口编程的基本原理和操作。通过实践和...

    利用JAVA向注册表里写信息

    尽管Preferences API并非专为访问Windows注册表而设计,但在Sun的Windows版JDK实现中,它使用注册表作为存储库。这意味着通过Preferences API存储的数据会被保存到Windows注册表中,从而使得Preferences API具备了...

    reglib:使用JNI在Java中使用Windows注册表

    1. **JNI接口定义**:在Java层,`reglib`定义了一系列的接口,这些接口对应了Windows注册表的操作,如读取、写入、删除键值等。例如,`RegOpenKeyEx`、`RegSetValueEx`等方法,它们在Java类中声明,但没有具体实现。...

    java远程调用rmi实例

    本实例将深入讲解如何使用Java RMI在Linux环境中启动远程服务,并在Windows环境下进行操作。 首先,理解RMI的基本原理:RMI系统由两部分组成,客户端和服务器端。服务器端暴露远程接口,客户端通过引用这个远程接口...

    文件操作程序实例

    总结来说,"文件操作程序实例"和"Windows注册表编辑"是IT专业人士必须掌握的基本技能。它们涵盖了系统层面的数据管理和配置管理,是开发和维护软件系统的关键环节。了解并熟练运用这些知识,将有助于提升问题解决...

    JAVA上百实例源码以及开源项目源代码

    Java二进制IO类与文件复制操作实例 16个目标文件 内容索引:Java源码,初学实例,二进制,文件复制 Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系...

    JavaScript修改注册表实例代码

    ### 知识点 #### JavaScript修改注册表能力 ...该实例代码提供了一种操作注册表的技术途径,展示了如何修改特定的注册表项来控制浏览器行为和安全设置,但同时也提醒了操作者必须小心谨慎,避免产生不可预见的副作用。

    h_JAVA 2应用编程150例.rar

    实例140 访问Windows注册表 514 第13章 Java配置与集成 523 实例141 J2SDK的安装配置 524 实例142 使用第三方包 525 实例143 安装配置Tomcat 526 实例144 安装配置Apache 528 实例145 安装配置WebLogic 529 实例146 ...

    java获取硬盘序列号的两种方法

    在Windows操作系统中,可以利用WMI接口来获取硬件信息,包括硬盘序列号。以下是如何使用Java通过WMI获取硬盘序列号的步骤: 1. 引入依赖:由于Java标准库不直接支持WMI操作,你需要引入第三方库,如`com.sun.jna`...

    用JAVA读取硬盘序列号

    在Java代码中,首先需要引入`java.lang.management`包,然后获取`OperatingSystemMXBean`实例: ```java import java.lang.management.ManagementFactory; import com.sun.management.OperatingSystemMXBean; ...

    java实现360悬浮球

    Swing组件基于轻量级的Java对象,不依赖于底层操作系统,因此跨平台兼容性良好。在这个项目中,Swing被用来创建悬浮球的窗口以及相关的交互元素。 2. **JFrame**: JFrame是Swing中的顶级容器,用于创建窗口应用。在...

    jRegistryKey-bin-1.4.0版本

    在Java编程中,处理操作系统级别的任务往往需要特定的工具或库,例如与Windows注册表进行交互。jRegistryKey是一个专门为Java开发者设计的开源库,允许他们在Java应用程序中方便地读取、写入和管理Windows注册表键值...

    java调用ocx控件,jacob,jar和dll文件

    需要注意的是,由于Jacob是基于JNI(Java Native Interface)的,所以可能存在一些兼容性问题,比如不同版本的Java和Windows,或者64位和32位系统的差异。在实际应用中,可能需要根据具体环境调整配置。 Apache标签...

    java 缓存系统实战(安装和实例代码)

    以下是关于 Memcached 缓存系统、Java 缓存框架以及实例代码的详细说明: 1. **Memcached 基础** - **Cache 定义**:Cache 通常被用来协调不同速度设备之间的数据传输,包括硬件级别的 CPU Cache 和软件层面的...

Global site tag (gtag.js) - Google Analytics