2013年9月10日星期二

About operate with registry.jar windows registry problems, weLaikankana

Ado , directly on the code

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("成功"), "");
    }
}

went to look inside the registry , or distortion - ? Kun
If heroes busy schedule to spend a little air to come, under the code might help me change my needs are simple , remove from the registry all
installation program,
that is traversing "SOFTWARE \ \ Microsoft \ \ Windows \ \ CurrentVersion \ \ Uninstall"
all sub- key , remove the DisplayName property of each sub- key print out ( sub key names in Chinese, sub-key DisplayName property also includes Chinese )
I put glue bar code

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);
    }
}




------ Solution ------------------------------------ --------

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");//这个是正常结果


cause structural RegStringValue other RegistryValue type , it is the first with a no-argument constructor to initialize , and then setData 's .
The setData method of data is in the dll getStringValueData method to get this method directly to the value obtained by gbk encoding split , each byte into strong jchar.
for (i = 0; i uniBuf [i] = (jchar) strData [i];

RegistryValue getByteData method of direct return this.data.getBytes (); default character set is obtained by a byte array . default character set is generally file.encoding or UTF-8. place taken by utf8 if the java file encoding type is not utf8 then this method also garbled .
------ For reference only ----------------------- ----------------
  This reply was moderator deleted at 2011-04-16 09:38:08

------ For reference only ---------------------------------- -----
  This reply was moderator deleted at 2011-04-16 09:38:08

------ For reference only ---------------------------------- -----
http://download.csdn.net/source/3195805

modified registry.dll modify the content posted to the following . simply test it . literacy are no problem .


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;
}


content reference word line code fragment . slight modifications .
------ For reference only ---------------------- -----------------
last untested written. assume that the process of reading and writing are two opposite results are not the same code .
explained last read it. written when , java incoming jstring type a string of characters , when converted into the local garbage , so will not be found.
original local character conversion is as follows:

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;
}

Since the local character set are generally gbk. So by the above method , the direct reading utf-8 character form is not found in the local name of the corresponding key .

also thinking does not change dll. put it differently processed within the java Later considered viable.
original method is direct access to the incoming parameters utf-8 byte array and copy it to a new array , when a string is returned. gbk be desired string is encoded .
as " Chinese " two words for example , gbk code is 4 bytes [0xD6, 0xd0, 0xce, 0xc4], if there is a java string is utf-8 format , but only occupies 4 bytes, and this is exactly four bytes " Chinese " in gbk encoding it can be passed to this character to get to the name of " Chinese " keys . , but there is no such utf- 8 string. because under utf-8 encoding rules to save a byte character range 0000 0000-0000 007 F, ie D6 can not save a utf-8 bytes can be more than one byte , then the end result will more than 4 bytes.

Language messy ... laughed
------ For reference only --------------------------- ------------
use this dll to replace the original dll. Chinese would not turn . can be used directly

similar registryKey.createSubKey (" success" ) ;

------ For reference only ---------------------------------- -----

anyway, still very grateful to your ~
------ For reference only ------------------ ---------------------

can do this step is very good, the next test and found a new String (registryKey . getByteData ()) taken out of the data or distortion
, not for the code , also invited experts can talk about how this is going children ?
------ For reference only -------------------------------------- -
very good way
------ For reference only ------------------------------- --------

I am not expert . learning together can be a bit more code to paste it ? new String (registryKey.getByteData ()) in registryKey is how come. < br> ------ For reference only ---------------------------------------


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())));
// }
}
}
}


thank master code posted here ~
------ For reference only -------------------------- -------------
carefully watched , this thing really is only from the aspect of the C DLL to start with.

done in java , reading is not the problem can be solved . LZ provide RegistryUtil decode method is right in one way .

write DLL when no other way , ice library directly to UTF-8 encoding spread out , not from the Java side correction . Alas .
------ For reference only -------------------------------------- -

-
or distortion , my file.encoding is gbk of
but still very grateful to you , it is your most warm-hearted of ~
------ For reference only --------------------- ------------------
very grateful to 2nd floor and the landlord .

没有评论:

发表评论