利用JAVA向註冊表裡寫資訊

來源:互聯網
上載者:User

註冊表包含 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();       }                           }}
建立的登錄機碼:

輸出結果為:
subKey1Value
subKey2Value
參考資料
  • 用Preferences API儲存物件,這是一篇來自IBM的文章可以使您進一步瞭解Preferences API。
  • Microsoft Windows 註冊表說明
  • Description of the Microsoft Windows registry
  • 在JNIRegistry這裡可以下載到需要的包和原始碼。
  • 如果您想閱讀JNIRegistry的Java doc可以來這裡。
  • 在Registry和Registry Reference可以找到關於註冊表、註冊表函數、註冊表結構、註冊表元素大小限制和註冊表實值型別等大量的資訊。

 

 

說明:我的體會“第一步:把下載下來的jar包載入到工程內,第二步,把與jar包在一起的dll檔案拷貝到你jdk安裝目錄下/jre/bin檔案夾下”

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.