1. 程式人生 > >Java讀取登錄檔總結之com.ice.jni.registry

Java讀取登錄檔總結之com.ice.jni.registry

com.ice.jni.registry包是Windows登錄檔API的Java本機介面。這使得Java程式可以非常方便的訪問,修改Windows的登錄檔資源。

下面重點演示如何讀取Windows的登錄檔。以Windows 7 x86為例。演示所用到的jar包和dll檔案請到一下網址下載

    點選下載

=====================================================================

【注】

登錄檔非常非常重要,如果操作不當,極有可能使系統崩潰。所以在操作之前,請備份完整的登錄檔資料。以備不時之需。

   備份方法

=====================================================================

將演示的方法包括:
方法一:
 java.util.Enumeration keyElements() 列舉該key的subkey的名稱,獲取指定節點的所有子節點
方法二:
  java.util.Enumeration valueElements() 列舉該key的值的名稱。
方法三: 
  java.lang.String getStringValue(java.lang.String valueName) 得到REG_SZ(字串值)或REG_EXPAND_SZ(可擴充字串值)的值。  
  
  
方法一:
 java.util.Enumeration keyElements() 列舉該key的subkey的名稱,獲取指定節點的所有子節點
測試結果:

程式碼:

        /**
	 * 返回[HKEY_LOCAL_MACHINE\SOFTWARE]下指定節點的所有子節點的名稱
	 * 
	 * @param keyName
	 *            指定的節點的名稱
	 * @return
	 * @throws NoSuchKeyException
	 * @throws RegistryException
	 */
	private static List<String> getSubKeyNames(String keyName)
			throws NoSuchKeyException, RegistryException {
		List<String> result = new ArrayList<String>();
		RegistryKey software = Registry.HKEY_LOCAL_MACHINE.openSubKey(SOFTWARE);
		if (keyName != null)
			software = software.openSubKey(keyName);
		@SuppressWarnings("unchecked")
		Enumeration<String> enumeration = software.keyElements();
		for (; enumeration.hasMoreElements();) {
			result.add(enumeration.nextElement());
		}
		return result;
	}
	
	// 測試
	public static void main(String[] args) throws Exception, RegistryException {
		List<String> result = getSubKeyNames("Clients");
		for(String str : result)
			System.out.println(str);
	}


控制檯:

Contacts
Mail
Media
StartMenuInternet

登錄檔:

註釋: keyElements()方法的返回值是Enumeration型別的資料,遍歷返回值就可以得到所有的subkey

====================================================================

方法二:  java.util.Enumeration valueElements() 列舉該key的值的名稱。程式碼:
        /**
	 * 得到某一節點所有的key
	 * @param keyName
	 * @return
	 * @throws Exception
	 */
	private static List<String> getValues(String keyName) throws Exception {
		List<String> result = new ArrayList<String>();
		RegistryKey software = Registry.HKEY_LOCAL_MACHINE.openSubKey(SOFTWARE);
		if (keyName != null)
			software = software.openSubKey(keyName);
		@SuppressWarnings("unchecked")
		Enumeration<String> enumeration = software.valueElements();
		for (; enumeration.hasMoreElements();) {
			result.add(enumeration.nextElement());
		}
		return result;
	}


	// 測試
	public static void main(String[] args) throws Exception, RegistryException {
		List<String> result = getValues("Android SDK Tools");
		for (String str : result)
			System.out.println(str);
	}

控制檯:
Path
StartMenuGroup

登錄檔:




注:在登錄檔中存放的是鍵值對的形式,這個方法可以得到當前節點所有的鍵值對中的key.然後再通過方法三,即可獲取每個key中的value


====================================================================

方法三: 
  java.lang.String getStringValue(java.lang.String valueName) 得到REG_SZ(字串值)或REG_EXPAND_SZ(可擴充字串值)的值。


程式碼:
        /**
	 * 獲取某一節點下,指定key的value值
	 * @param nodeName
	 * @param key
	 * @return
	 * @throws Exception
	 */
	private static String getValue(String nodeName, String key) throws Exception {
		RegistryKey software = Registry.HKEY_LOCAL_MACHINE.openSubKey(SOFTWARE);
		if (nodeName != null)
			software = software.openSubKey(nodeName);
		return software.getStringValue(key);
	}


	// 測試
	public static void main(String[] args) throws Exception, RegistryException {
		System.out.println(getValue("Android SDK Tools","Path"));
	}

控制檯:
D:\Program Files\Android-sdk

登錄檔:




注: (1) 此方法可獲取字串型別的鍵值.
    (2) 如果想得到某一節點下所有的鍵值對,則通過方法二和方法三即可得到.




得到節點的鍵值對


程式碼:
        /**
	 * 得到某一節點所有的key和value
	 * 
	 * @param nodeName
	 * @return
	 * @throws Exception
	 */
	private static Map<String, String> getKeyValue(String nodeName)
			throws Exception {
		Map<String, String> result = new HashMap<String, String>();
		RegistryKey software = Registry.HKEY_LOCAL_MACHINE.openSubKey(SOFTWARE);
		if (nodeName != null)
			software = software.openSubKey(nodeName);
		@SuppressWarnings("unchecked")
		Enumeration<String> enumeration = software.valueElements();
		for (; enumeration.hasMoreElements();) {
			String key = enumeration.nextElement();
			String value = software.getStringValue(key);
			result.put(key, value);
		}
		return result;
	}
	
        // 測試
	public static void main(String[] args) throws Exception, RegistryException {
		Map<String,String> result = getKeyValue("Android SDK Tools");
		for (Entry<String, String> entry : result.entrySet())
			System.out.println(entry.getKey()+":"+entry.getValue());
	}

控制檯:
StartMenuGroup:Android SDK Tools
Path:D:\Program Files\Android-sdk

登錄檔:




以上讀取登錄檔的方法非常容易使用。基本可以滿足需求。




====================================================================

====================================================================


附1:Java讀取本機安裝的資料庫資訊


package DBTest;


import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;


import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryKey;


/**
 * 通過登錄檔獲取本機安裝的資料庫資訊
 * @author Administrator
 *
 */
public class DBInfoUtil {


	private static final String SOFTWARE = "SOFTWARE";
	/*
	 * Oracle獲取版本資訊的key
	 */
	private static final String ORACLE_VERSION = "VERSION";
	private static final String ORACLE_SID = "ORACLE_SID";
	/*
	 * MySql獲取版本資訊的key
	 */
	private static final String MYSQL_VERSION = "Version";
	private static final String MYSQL_SID = "";


	/**
	 * 獲取本機資料庫的資訊
	 * 
	 * @return 每個資料庫的資訊封裝為一個List集合. <br>
	 *         List集合中依次為資料庫的名稱,版本,資料庫例項<br>
	 *         資料庫例項僅供參考
	 */
	public List<List<String>> getDBInfo() {
		List<List<String>> result = new ArrayList<List<String>>();
		/*
		 * 獲取SOFTWARE下所有的子節點
		 */
		List<String> softWareSubKeys = getSubKeyNames("");
		/*
		 * 在獲得的節點下查詢是否安裝資料庫
		 */
		for (String keyName : softWareSubKeys) {
			if (keyName.startsWith("ORACLE")) {
				result.add(getDBInfoFromKeyName(keyName));
			} else if (keyName.startsWith("MySQL")) {
				result.add(getDBInfoFromKeyName(keyName));
			}
		}
		return result;
	}


	/**
	 * 根據資料庫的名稱,獲取資料庫資訊
	 * 
	 * @param dbName
	 *            資料庫名稱
	 * @return
	 */
	private static List<String> getDBInfoFromKeyName(String dbName) {
		List<String> result = new ArrayList<String>();
		if (dbName.startsWith("ORACLE")) {
			result.add(dbName);
			result.add(getDBDataFromSubKey(dbName, ORACLE_VERSION));
			result.add(getDBDataFromSubKey(dbName, ORACLE_SID));
		} else if (dbName.startsWith("MySQL")) {
			result.add(dbName);
			result.add(getDBDataFromSubKey(dbName, MYSQL_VERSION));
			result.add(getDBDataFromSubKey(dbName, MYSQL_SID));
		}
		return result;
	}


	/**
	 * 從登錄檔的節點中獲取資料庫的資訊
	 * 
	 * @param keyName
	 * @param keyWord
	 * @return
	 */
	private static String getDBDataFromSubKey(String keyName, String keyWord) {
		/**
		 * 先檢查該節點下的鍵值對中有無oracleVersionKey
		 */
		String data = getdataByKeyWord(keyName, keyWord);
		if (data != null) {
			return data;
		}
		/**
		 * 如果不存在,然後獲取該節點下所有的節點
		 */
		List<String> subKeys = getSubKeyNames(keyName);
		if (subKeys != null) {
			for (String key : subKeys) {
				/**
				 * 對於每個節點,檢查是否存在oracleVersionKey
				 */
				data = getDBDataFromSubKey(keyName + "\\" + key, keyWord);
				if (data != null) {
					break;
				}
			}
		}
		return data;
	}


	/**
	 * 根據關鍵字獲取資料庫的某一資訊
	 * 
	 * @param keyName
	 * @param keyWord
	 * @return
	 */
	private static String getdataByKeyWord(String keyName, String keyWord) {
		try {
			RegistryKey software = Registry.HKEY_LOCAL_MACHINE
					.openSubKey(SOFTWARE);
			if (keyName != null)
				software = software.openSubKey(keyName);
			@SuppressWarnings("unchecked")
			Enumeration<String> enumeration = software.valueElements();
			for (; enumeration.hasMoreElements();) {
				String keyValue = enumeration.nextElement();
				if (keyValue.equalsIgnoreCase(keyWord)) {
					String result = software.getStringValue(keyValue);
					software.closeKey();
					return result;
				}
			}
			software.closeKey();
			return null;
		} catch (Exception e) {
			throw new RuntimeException("獲取資料庫版本或資料庫例項失敗");
		}
	}


	/**
	 * 返回[HKEY_LOCAL_MACHINE\SOFTWARE]下指定節點的所有子節點的名稱<br>
	 * 
	 * @param keyName
	 *            指定的節點的名稱<br>
	 *            若為空,則獲取[HKEY_LOCAL_MACHINE\SOFTWARE]下所有的子節點
	 * @return
	 */
	private static List<String> getSubKeyNames(String keyName) {
		try {
			List<String> result = new ArrayList<String>();
			RegistryKey software = Registry.HKEY_LOCAL_MACHINE
					.openSubKey(SOFTWARE);
			if (keyName != null)
				software = software.openSubKey(keyName);
			@SuppressWarnings("unchecked")
			Enumeration<String> enumeration = software.keyElements();
			for (; enumeration.hasMoreElements();) {
				result.add(enumeration.nextElement());
			}
			software.closeKey();
			return result;
		} catch (Exception e) {
			throw new RuntimeException("獲取子節點失敗");
		}
	}
}

附2:registry主要的方法







================================================================
Java讀取登錄檔的三種方法---------------------->檢視詳細內容
Java讀取登錄檔總結之Java API---------------->
Java讀取登錄檔總結之讀取的簡單方法------->
================================================================