废话不多说,直接上代码public class CopyOfRegistryManager2 {
public static void main(String[] args) throws NoSuchKeyException,
RegistryException {
RegistryKey registryKey = Registry.openSubkey(
Registry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
RegistryKey.ACCESS_READ); registryKey.createSubKey(RegistryUtil.decode("成功"), "");
}
}跑到注册表里面一看,还是乱码 -- 锟
如果哪位大侠百忙之中能够抽出一点空来的话,不妨帮我改下代码,我的需求很简单,从注册表中取出所有
安装程序的信息,
也就是遍历 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
的所有子键,取出每个子键的 DisplayName 属性打印出来(子键名有中文,子键的DisplayName属性也包含中文)
我把代码粘上吧package available.registry.test;import java.util.Enumeration;import available.registry.basic.RegistryUtil;import com.ice.jni.registry.NoSuchKeyException;
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryException;
import com.ice.jni.registry.RegistryKey;
import com.ice.jni.registry.RegistryValue;// 这个类使用了 registry.jar 中 jni 提供的功能!
public class RegistryManager {
private final Object o = new Object();
public static void main(String[] args) throws NoSuchKeyException,
RegistryException {
// 提示如何在命令行下使用 registry.jar 文件,参数到底是什么意思?
// Registry.usage("123"); // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
RegistryKey rootRK = Registry.openSubkey(
Registry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\",
RegistryKey.ACCESS_READ);
RegistryManager rm = new RegistryManager(); Enumeration<?> enums = rootRK.keyElements();
while (enums.hasMoreElements()) {
synchronized(rm.o) {
String childRKName = (String)enums.nextElement();
String childRKNameDecoded = RegistryUtil.decode(childRKName);
System.err.println("之后 " + childRKNameDecoded); rm.getDisplayAttr(rootRK, childRKNameDecoded);
}
}
} // “根键” 和 “枚举出来的子键名”
public synchronized void getDisplayAttr(RegistryKey rootRK, String childRKNameDecoded) throws NoSuchKeyException,
RegistryException {
RegistryKey childRK = null;
try {
childRK = rootRK.openSubKey(RegistryUtil.encode(childRKNameDecoded), RegistryKey.ACCESS_READ);
} catch (com.ice.jni.registry.NoSuchKeyException e) {
System.out.println(childRKNameDecoded + " 找不到这个键!");
}
if(childRK != null) {
// 获取子键的 DisplayName 属性的值
String subKeyName = RegistryUtil.decode(childRK.getName());
System.out.println("子键的名字为:" + subKeyName);
RegistryValue rv = null;
try {
rv = childRK.getValue("DisplayName");
} catch (com.ice.jni.registry.NoSuchValueException e) {
System.err.println("该子键没有这个 DisplayName 这个属性~");
}
if (rv != null) {
System.out.print(childRK.getName()+" 子键 DisplayName 属性的值为:");
String name = RegistryUtil.decode(new String(rv.getByteData()));
if(name == null) {
System.err.println("null");
} else if(name.equals("")) {
System.err.println("equals(\"\")");
} else {
System.err.println(name);
}
System.out.println();
}
}
}
}
package available.registry.basic;import java.io.UnsupportedEncodingException;public class RegistryUtil {
/**
* 将dll获取的字符串拼接回原来的形式.
* 因为dll内以前的方法只是单纯的将byte复制到java的char里
* if ( uniBuf != NULL )
{
for ( i = 0 ; i < len ; ++i )
uniBuf[i] = (jchar) buf[i];
result = (*env)->NewString( env, uniBuf, (jsize)len );
free( uniBuf );
}
return result; * @param str 从dll获取的字符串
* @return
* @throws UnsupportedEncodingException
*/
public static String decode(String str) {
String result = null;
char[] charbuf = str.toCharArray();
byte[] bytebuf = new byte[charbuf.length];
for(int i=0;i<charbuf.length;i++){
bytebuf[i] = (byte)charbuf[i];
}
try {
result = new String(bytebuf,"GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/**
* 相反要传入中文的字符来操作,需要修改中文为他所识别的乱码...即将中文按两字节一个,拆分开
* @param str
* @return
*/
public static String encode(String str) {
byte[] bytebuf = null;
try {
bytebuf = str.getBytes("GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
char[] charbuf = new char[bytebuf.length];
for(int i=0;i<bytebuf.length;i++){
charbuf[i] = (char)bytebuf[i];
}
return new String(charbuf,0,charbuf.length);
}
}
public static void main(String[] args) throws NoSuchKeyException,
RegistryException {
RegistryKey registryKey = Registry.openSubkey(
Registry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
RegistryKey.ACCESS_READ); registryKey.createSubKey(RegistryUtil.decode("成功"), "");
}
}跑到注册表里面一看,还是乱码 -- 锟
如果哪位大侠百忙之中能够抽出一点空来的话,不妨帮我改下代码,我的需求很简单,从注册表中取出所有
安装程序的信息,
也就是遍历 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
的所有子键,取出每个子键的 DisplayName 属性打印出来(子键名有中文,子键的DisplayName属性也包含中文)
我把代码粘上吧package available.registry.test;import java.util.Enumeration;import available.registry.basic.RegistryUtil;import com.ice.jni.registry.NoSuchKeyException;
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryException;
import com.ice.jni.registry.RegistryKey;
import com.ice.jni.registry.RegistryValue;// 这个类使用了 registry.jar 中 jni 提供的功能!
public class RegistryManager {
private final Object o = new Object();
public static void main(String[] args) throws NoSuchKeyException,
RegistryException {
// 提示如何在命令行下使用 registry.jar 文件,参数到底是什么意思?
// Registry.usage("123"); // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
RegistryKey rootRK = Registry.openSubkey(
Registry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\",
RegistryKey.ACCESS_READ);
RegistryManager rm = new RegistryManager(); Enumeration<?> enums = rootRK.keyElements();
while (enums.hasMoreElements()) {
synchronized(rm.o) {
String childRKName = (String)enums.nextElement();
String childRKNameDecoded = RegistryUtil.decode(childRKName);
System.err.println("之后 " + childRKNameDecoded); rm.getDisplayAttr(rootRK, childRKNameDecoded);
}
}
} // “根键” 和 “枚举出来的子键名”
public synchronized void getDisplayAttr(RegistryKey rootRK, String childRKNameDecoded) throws NoSuchKeyException,
RegistryException {
RegistryKey childRK = null;
try {
childRK = rootRK.openSubKey(RegistryUtil.encode(childRKNameDecoded), RegistryKey.ACCESS_READ);
} catch (com.ice.jni.registry.NoSuchKeyException e) {
System.out.println(childRKNameDecoded + " 找不到这个键!");
}
if(childRK != null) {
// 获取子键的 DisplayName 属性的值
String subKeyName = RegistryUtil.decode(childRK.getName());
System.out.println("子键的名字为:" + subKeyName);
RegistryValue rv = null;
try {
rv = childRK.getValue("DisplayName");
} catch (com.ice.jni.registry.NoSuchValueException e) {
System.err.println("该子键没有这个 DisplayName 这个属性~");
}
if (rv != null) {
System.out.print(childRK.getName()+" 子键 DisplayName 属性的值为:");
String name = RegistryUtil.decode(new String(rv.getByteData()));
if(name == null) {
System.err.println("null");
} else if(name.equals("")) {
System.err.println("equals(\"\")");
} else {
System.err.println(name);
}
System.out.println();
}
}
}
}
package available.registry.basic;import java.io.UnsupportedEncodingException;public class RegistryUtil {
/**
* 将dll获取的字符串拼接回原来的形式.
* 因为dll内以前的方法只是单纯的将byte复制到java的char里
* if ( uniBuf != NULL )
{
for ( i = 0 ; i < len ; ++i )
uniBuf[i] = (jchar) buf[i];
result = (*env)->NewString( env, uniBuf, (jsize)len );
free( uniBuf );
}
return result; * @param str 从dll获取的字符串
* @return
* @throws UnsupportedEncodingException
*/
public static String decode(String str) {
String result = null;
char[] charbuf = str.toCharArray();
byte[] bytebuf = new byte[charbuf.length];
for(int i=0;i<charbuf.length;i++){
bytebuf[i] = (byte)charbuf[i];
}
try {
result = new String(bytebuf,"GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/**
* 相反要传入中文的字符来操作,需要修改中文为他所识别的乱码...即将中文按两字节一个,拆分开
* @param str
* @return
*/
public static String encode(String str) {
byte[] bytebuf = null;
try {
bytebuf = str.getBytes("GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
char[] charbuf = new char[bytebuf.length];
for(int i=0;i<bytebuf.length;i++){
charbuf[i] = (char)bytebuf[i];
}
return new String(charbuf,0,charbuf.length);
}
}
解决方案 »
- JTabel多行选中的情况下,怎么获得JTable选中行的第一个值
- jxl想做一个通用的java文件,只需变化sql语句,导出的excel和sql语句查询结果像同
- 谁能详细解释一下这个小C#程序?
- J2SE新手提问超多,请大家帮忙。谢谢了。
- java 调用搜索引擎的问题
- 给分贴。旁人勿进。
- 请教各位前辈,如何通过编程将Excel中的数据导入的SqlServer2000中,有没有源代码,麻烦给一份。谢谢。
- 高分请教一个Socket编程服务器端的问题!
- MyEclipse出现错误,不能运行java程序,运行出来是由tomcat网页显示出来
- 关于equals算法的疑惑
- 一个简单的C/S试验程序,调试不通,求助。
- 提供一些java网页编程的例子吧~
jstring
strbufToJString( JNIEnv *env, char *buf, int len )
{
jstring encoding = (*env)->NewStringUTF(env, "gbk");
jclass strClass = (*env)->FindClass(env, "Ljava/lang/String;");
jmethodID ctorID = (*env)->GetMethodID(env, strClass, "<init>", "([BLjava/lang/String;)V");
jbyteArray bytes = (*env)->NewByteArray(env, len);
(*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)buf);
return (jstring)(*env)->NewObject(env, strClass, ctorID, bytes, encoding);
}char *
jStringToNewAscii( JNIEnv *env, jstring jstr )
{
char* rtn = NULL;
jclass clsstring = (*env)->FindClass(env, "java/lang/String");
jstring strencode = (*env)->NewStringUTF(env, "gbk");
jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode);
jsize alen = (*env)->GetArrayLength(env, barr);
jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
if (alen > 0)
{
rtn = (char*)malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = '\0';
}else{
rtn = (char*)malloc(1);
rtn[0] = '\0';
}
(*env)->ReleaseByteArrayElements(env, barr, ba, 0);
return rtn;
}
内容参考字网上的代码片段.稍作修改.
读上次解释过了.写入的时候,java传入了个jstring类型的字符串.转化为本地字符的时候乱码.所以会找不到.
原来的转化本地字符方法如下:char *
jStringToNewAscii( JNIEnv *env, jstring jStr )
{
int i;
int utfLen;
jboolean isCopy;
char *asciiBuf;
const char *utfBuf; utfLen = (*env)->GetStringUTFLength( env, jStr );
utfBuf = (*env)->GetStringUTFChars( env, jStr, &isCopy ); asciiBuf = malloc( utfLen + 2 );
if ( asciiBuf != NULL )
{
for ( i = 0 ; i < utfLen ; ++i )
asciiBuf[i] = utfBuf[i]; asciiBuf[i] = '\0'; (*env)->ReleaseStringUTFChars( env, jStr, utfBuf );
} return asciiBuf;
}由于本地字符集一般都是gbk.所以按上述方法,直接读取字符的utf-8形式,在本地是找不到所对应的键名的.也想着不改dll.换种方式在java内处理.后来考虑到不可行.
原方法是直接获取传入参数的utf-8字节数组并复制到一个新的数组,当一个字符串返回.可需要的字符串是gbk编码的.
以"中文"这两字为例,gbk编码是4个字节[0xD6,0xd0,0xce,0xc4],如果有一个java字符串是以utf-8格式保存,而且只占用4个字节,而且这四个字节刚好是"中文"的gbk编码.那就可以传入这个字符来取到名称为"中文"的键值.可是不存在这样的utf-8的字符串.因为根据utf-8的编码规则,以一个字节保存的字符范围为0000 0000 - 0000 007F,即D6不能以一个utf-8字节保存,可超过1个字节的话,最终结果也就超过了4字节.语言凌乱...见笑了
,不求代码,还请高手能说说这是怎么回事儿?
package available.registry.test;import java.io.UnsupportedEncodingException;
import java.util.Enumeration;import available.registry.basic.RegistryUtil;import com.ice.jni.registry.NoSuchKeyException;
import com.ice.jni.registry.NoSuchValueException;
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryException;
import com.ice.jni.registry.RegistryKey;
import com.ice.jni.registry.RegistryValue;public class CatchException {
public static void main(String[] args) throws NoSuchKeyException,
RegistryException {
RegistryKey registryKey = Registry.openSubkey(
Registry.HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
RegistryKey.ACCESS_READ);
Enumeration<?> enums = registryKey.keyElements();
// 360保险箱 0xB1A3 0xCFD5 0xCFE4
while(enums.hasMoreElements()) {
String childRKName = (String)enums.nextElement();
// if(childRKName.equals("360安全卫士")) {
RegistryKey rk = registryKey.openSubKey(childRKName, RegistryKey.ACCESS_READ);
RegistryValue rv = null;
try {
rv = rk.getValue("DisplayName");
} catch (NoSuchValueException e1) {
// 仅仅 catch 运行时异常的话会终止程序运行,只有具体到是哪种 Exception,才会继续执行~
e1.printStackTrace();
}
// 如果上句代码抛出异常,则这里的rv必定为null,不做处理的话必然会报空指针~
if(rv == null) continue;
String s = null;
try {
s = new String(rv.getByteData(), "GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println(s + " ====================== " +
RegistryUtil.decode(new String(rv.getByteData())));
// }
}
}
}
谢高手了,代码贴这儿~
String s = new String(rv.getByteData(), "utf-8");
byte[] tmp = new byte[s.length()];
for(int i=0;i<s.length();i++){
tmp[i] = (byte)s.toCharArray()[i];
}
s = new String(tmp,"gbk");//这个是正常结果
原因构造RegStringValue等RegistryValue类型的时候,是先用无参的构造方法初始化,然后再setData的.
而setData方法中的data是在dll中getStringValueData方法取得.该方法直接把取得的值按gbk编码拆分,每个字节强转为jchar.
for ( i = 0 ; i < dwBufSize ; ++i )
uniBuf[i] = (jchar) strData[i];RegistryValue 的getByteData方法中直接return this.data.getBytes();是按默认的字符集取得byte数组.默认字符集一般为file.encoding或者UTF-8.这里按utf8取.如果该java文件的编码类型不是utf8则这个方法也会乱码.
还是乱码的,我的file.encoding是 gbk的
不过还是很感谢你,就属你最热心肠了~