在 Java 中操作 Windows 注册表

想做个东西,要获IE的代理设置,看网上介绍基本都是读取注册表的方式,没提到说借助于特定的 Win32 API。而 JDK 提供操作 Windows 的 API 也就是 Preferences,因为这个 API 也是跨平台的,所功能比较弱,在 Win32 下只能用来操作 HKCU\Software\JavaSoft 和 HKLM\Software\JavaSoft 下及子节点的数据。

自由访问注册表其他键的值光用 Java 是做不到的,必然方案就是 JNI,一开始也自己来实现这个 JNI 动态库,后来懒了一下,想着网上应该用现成的实现,Google 了一下,果然不出所望,就是 http://www.trustice.com/java/jnireg/index.shtml 下的 registry-3.1.3.zip(包含源代码)。可以利用它访问、修改、导出注册表项到文件等。解开 registry-3.1.3.zip,在 bin 目录中可以看到两个文件 ICE_JNIRegistry.dll 和 registry.jar,动态库就是本地代码实现。

com.ice.jni.registry.Registry.main() 就是 registry 的示例代码,动态库 ICE_JNIRegistry.dll 也是在这个类的静态块中被加载的,记得要把 ICE_JNIRegistry.dll 放在它能够被加载的位置上,比如你把 registry-3.1.3.zip 解压到 c:\registry-3.1.3,在命令行下你可以进入到这个目录中,并执行

c:\registry-3.1.3>java -cp registry.jar com.ice.jni.registry.Registry

就可以在 command: 提示符下输入命令操作注册表了,输入 help 会打印出所有能用指令:

keys regKey -- print the key names

values regKey -- print the value names

data regKey subKey -- print the key's data

string regKey subKey -- print REG_SZ key's string

setbin regKey subKey  binaryString -- set REG_BINARY

setdw regKey subKey int -- set REG_DWORD

setstr regKey subKey string -- set REG_SZ

setmulti regKey subKey semiColonString -- set REG_MULTI_SZ

delkey regKey subKey -- delete key 'subKey' of regKey

delval regKey subKey -- delete value 'subKey' of regKey

export regKey fileName -- export registry key to fileName

expand regKey valueName -- expand string value

!! -- repeats last command

$$ -- re-uses previous keyname

Predefined Key Prefixes: (e.g. $0-9)

   $0=HKLM\System\CurrentControlSet\control

   $1=HKLM\Software

   $2=HKLM\Software\Miscrosoft

   $3=HKLM\Software\Microsoft\Windows\CurrentVersion

   $4=HKLM\Software\Microsoft\Windows\CurrentVersion\ProfileList

   $5=HKCU\Software

   $6=HKCU\Software\Microsoft

   $7=HKCU\AppEvents

   $8=HKCU\AppEvents\Schemes

   $9=HKCU\AppEvents\Schemes

比如要读取 IE 是否启用代理设置就可以输入指令

command: data "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\" ProxyEnable

显示结果为:

Value 'ProxyEnable' is [type=4,name=ProxyEnable]

REG_DWORD '0' [x00000000]

'0' 表示未启用 IE 代理设置,如果启用了代理设置,通过其他几个字符串值可获取到具体的代理设置。如

command: data "%6\\Windows\\CurrentVersion\\Internet Settings\\" ProxyServer

Value 'ProxyServer' is [type=1,name=ProxyServer]

REG_SZ 'ftp=proxy.unmi.com:21;gopher=proxy.unmi.com:8080;http=proxy.unmi.com:8080;https=proxy.unmi.com:8080'

上面用了一个内置变量 %6 来代表 HKCU\Software\Microsoft。

其他的指令,大家可以尝试一下,这里我主要是关注于读取键值的操作,接下来呢,我们来看看自己写代码如何来获取键值。应好好的参考 Registry 类的实现。

我在 IE 中为不同协议设置了代理后,执行上面程序的输出为(如果要取出 http 代理设置就分隔进行字符串处理了):<

IE 是否启用了代理设置: true

IE 代理服务器是: ftp=proxy.unmi.com:21;gopher=proxy.unmi.com:8080;http=proxy.unmi.com:8080;https=proxy.unmi.com:8080

如果对所有服务器均使用相同的代理服务器设置后,执行上面程序的输出为(默认就是 http 代理设置了):

IE 是否启用了代理设置: true

IE 代理服务器是: proxy.unmi.com:80

大家可以继续挖掘 registry 的修改键值及创建子键的功能。

自己来补上一个在网上又一个读取 Windows 注册表的 JNI 实现:http://www.sf.net/projects/jregistrykey

本文链接 https://yanbin.blog/java-access-windows-registry/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

5 Comments
Inline Feedbacks
View all comments
star
16 years ago

请教一个问题,我用此包写入注册表的中文是乱码,不知道是什么原因?不知道你是否遇到过此问题?

隔叶黄莺
16 years ago

情况如何啊,C++中接收到了字符串要用到两个函数

1. GetStringUTFChars

2. WideCharToMultiByte

QQ里可以继续探讨,另外 registry-3.1.3 的源代码我还没有去看,不知道有没有对中文特别处理。

三人行,必有我师焉

registry,jregistrykey 读写中文键值都有问题。RegOpenKeyEx这个API很奇怪,即使使用了jstringToNative这种标准的中文处理函数,依然无法读取。

隔叶黄莺
15 years ago

1. GetStringUTFChars

2. WideCharToMultiByte

这两函数试这没有呢?

小成
小成
15 years ago

中文是个好大的问题,犯呀