Windows_Registry

**登錄檔**（英語：Registry，中國大陸譯作**註冊表**，台灣、港、澳譯作**登錄檔**）是 Microsoft Windows 操作系統和其應用程式中的一個重要的層次型資料庫，用於儲存系統和應用程式的設定資訊。

早在 Windows 3.0 推出 OLE 技術的時候，登錄檔就已經出現。但是，從 Windows 95 開始，登錄檔才真正成為 Windows 使用者經常接觸的內容，並在其後的作業系統中繼續沿用至今。隨後推出的 Windows NT 是第一個從系統級別廣泛使用登錄檔的作業系統。

## 歷史

### 前身

最初，Windows 系統及應用程式的資訊被儲存在字尾名為 ini 的文字檔案中，這就是登錄檔的前身。但是這麼做有著致命弱點：因為每一個程式都會新安裝一個或多個 ini 檔案，來儲存程序資訊，導致資訊的分布極為零亂；而且在 16 位元系統下，ini 檔案的大小必須在 64KB 之內。所以 ini 檔案被認為不便於使用和管理。

### 發布與發展

在最早出現於 Windows 3.0 的 OLE 技術出現後，微軟為了存放系統中大量的軟體組件資訊，組織了一個 reg.dat 的資料庫來存放這些資訊。當時的登錄編輯程式為 16 位元版本的 regedit.exe，功能較弱。

後來開發的 Windows NT 則更進一步使用相同的檔案格式來存放系統的組態資訊，以取代原有的 ini 檔案。該系統為每一個使用者在使用者目錄下建立了一個自身的登錄檔空間，而系統的設定被存放在系統資料夾中。由於 Windows NT 是一個 32 位元作業系統，regedit.exe 被升級為 regedt32.exe，並增加了對權限的設定功能。

在 Windows 95 中，登錄檔首次得到廣泛套用，逐漸淘汰了原有的 ini 檔案。程式在安裝時，不再將資料寫入 ini 檔案，而直接寫入登錄檔。為了最大限度相容舊程式，部份原來用於讀寫 ini 檔案的專門 API 函式仍然可用，但現在是存取登錄檔（寫入或讀取）。Windows 95 為了保持和 Windows 3.x 系列的相容性，登錄檔的架構與 Windows NT 不同，為此專門開發了另一個 32 位元版本的 regedit.exe，它沒有設定權限的功能。

在 Windows 2000 中，由於 Windows 95 家族已經深入人心，regedit.exe 也得到廣泛套用，相反 regedt32.exe 的介面相對比較醜陋，因此微軟將 windows 95 系列的 regedit.exe 拿過來用。但由於移植過來的 regedit.exe 仍沒有權限設定的功能，regedt32.exe 仍然保留在系統中用作權限設定。

到 Windows XP 和 Windows Server 2003 中，regedit.exe 已經增加了權限的功能，regedit32.exe 由於失去作用而被剔除。同時，這個版本的登錄檔是 64 位元的，這導致了一些相容性問題，少數可以執行在舊版本 Windows 的程式在 Windows XP 中無法運作。

### 64 位元 Windows 的登錄檔

64 位元 Windows 中的登錄檔結構大致與 32 位元版本相同，但 32 位元程式的資訊被放在 HKEY\_LOCAL\_MACHINE\SOFTWARE\Wow6432Node 而不是 HKEY\_LOCAL\_MACHINE\SOFTWARE（64 位元程式的資訊放於此處）。

## 資料結構

登錄檔由鍵（key，或稱「項」）、子鍵（subkey，子項）和值項（value）構成。一個鍵就是樹狀資料結構中的一個節點，而子鍵就是這個節點的子節點，子鍵也是鍵。一個值項則是一個鍵的一條內容，由名稱（name）、資料類型（datatype）以及資料（data）組成。一個鍵可以有一個或多個值，每個值的名稱各不相同，如果一個值的名稱為空，則該值為該鍵的預設值。

在登錄編輯程式（Regedit.exe）中，資料結構顯示如下，其中，**command** 鍵是 **open** 鍵的子鍵，**(預設)** 表示該值是預設值，值名稱為空，其資料類型為 **REG\_SZ**，資料值為 **%systemroot%\system32\NOTEPAD.EXE "%1**

以上資訊的意義是：txt 類型的檔案在右鍵清單里的「開啟」一項使用的程式是「NOTEPAD.EXE」，即用記事本打開檔案。

### 資料類型

登錄檔的資料類型主要有以下五種：

此外，登錄檔還有其他的資料類型，但是均不常用：

* REG\_DWORD\_BIG\_ENDIAN - DWORD 的大頭版本，下面同理
* REG\_DWORD\_LITTLE\_ENDIAN
* REG\_FULL\_RESOURCE\_DESCRIPTOR
* REG\_QWORD - DWORD 的四字（64 位）版本
* REG\_FILE\_NAME

### 登錄檔的分支結構

登錄檔有五個一級分支，下面是這五個分支的名稱及作用：

### 登錄檔的儲存方式

Windows NT 系列作業系統和 Windows 9x 系列的儲存方式有很大區別。登錄檔被分成多個檔案儲存，稱為 Registry Hives，每一個檔案被稱為一個組態單元。

在早期的 Windows 3.x 系列中，登錄檔僅包含一個 reg.dat 檔案，所存放的內容後來演變為 HKEY\_CLASSES\_ROOT 分支。

Windows NT 家族的組態單元檔案：

* 假設 Windows 安裝於本機磁碟 (C)，則在 Windows XP 以前，檔案存放於 C:\WINNT\SYSTEM32\CONFIG，而 XP 及以後則存放於 C:\WINDOWS\SYSTEM32\CONFIG

Windows 9x 家族的設定檔

## 編輯登錄檔

### 使用登錄編輯程式

Microsoft 公司不建議使用者自行更改登錄檔，因為如果對登錄檔進行了不當修改，就有可能造成 Windows 系統的某些功能失效，甚至導致系統崩潰。但是，Microsoft 公司仍然在 Windows 中提供了登錄編輯程式，它位於 %systemroot%\regedit.exe。在 Windows NT 中使用的則是介面有所不同的 REGEDT32.exe。而在 Windows 2000 中，兩個程式同時存在於系統中。部份的原因是 Windows 2000 版本的 regedit.exe 尚不支援對登錄檔資料設定安全性。但在 Windows XP 及以後的作業系統中，regedit.exe 已經能夠支援登錄檔安全設定了，因此 REGEDT32.exe 失去了存在的必要。不過它仍被保留，只是該程式執行時僅僅會自動呼叫 regedit.exe。

除了編輯本台電腦上登錄檔資料之外，登錄編輯程式亦可以通過檔案清單下的「載入組態單元」清單項編輯直接編輯檔案系統上的登錄檔資料檔案。該功能可以允許使用者打開檔案系統中的 RegHive 檔案，並將其中的資料對映到 HKEY\_USERS 或者 HKEY\_LOCAL\_MACHINE 項下的一個子項之中。

### 使用命令列工具（CLI）

Windows 內建了一個管理登錄檔的命令列工具 ——**reg**。只需在命令提示字元中執行並指定參數，即可以命令列的形式對登錄檔進行各項管理操作。支援的操作有增刪改查、匯入匯出登錄檔檔案（reg 檔案）、匯入匯出或載入組態單元（RegHive）等。

### 使用指令碼

在 Windows 98 以後的作業系統中，增加了一個手稿語言直譯器，可以用來執行一些系統任務。它可以支援 VBScript 和 JavaScript 兩種手稿語言，都提供了存取登錄檔的功能。某些病毒就利用這一點通過修改登錄檔進行傳播。

### 使用第三方或自行編寫的軟體

存取登錄檔的系統功能對編程人員是開放的，因此有許多軟體都有讀寫登錄檔的功能。事實上，Windows 平台下開發的軟體幾乎都在不同程度上修改登錄檔，以便儲存一些在程式多次執行之間需要保留的資訊，以及讓軟體可以通過某種特定方式（例如，右鍵清單）啟動。也有一些軟體是專門開發出來對登錄檔進行最佳化和設定的。

### 使用 reg 檔案

reg 檔案也是一種修改登錄檔的方式。在登錄編輯程式中，使用者可以通過「檔案」清單中的「匯出」清單項來備份登錄檔中的某些專案到一個 reg 檔案之中；之後使用者可以再次通過「匯入」清單項將這些專案還原。reg 檔案本身也在系統中被關聯到 regedit.exe，因此直接雙擊打開 reg 檔案也會起到將其中的專案匯入到登錄檔中的效果。

而事實上，reg 檔案是根據一定格式編寫的純文字檔案。因此，熟練的使用者可以直接使用文字編輯器（比如記事本）來建立自己的 reg 檔案，這樣做無需在登錄檔中根據路徑一級一級地存取，而且可以直接對大量專案進行批次修改。這些檔案還可以被分發給非專業的使用者，說明他們快速地完成登錄檔的編輯，以減少出錯的可能。

### Registry APIs

Windows SDK 提供了存取登錄檔的介面。建立或打開的鍵，必須作為當前已經打開的鍵的子鍵。HKEY\_LOCAL\_MACHINE, HKEY\_CLASSES\_ROOT, HKEY\_USERS, HKEY\_CURRENT\_USER 等預定義的鍵總是已經打開。使用 RegOpenKeyEx 打開鍵；使用 RegCreateKeyEx 建立鍵。登錄檔允許最大 512 層子鍵深度。通過一個登錄檔 API 呼叫允許一次打開或建立 32 層深度的登錄檔的子鍵。 RegCloseKey 關閉已經打開的鍵，把資料寫回登錄檔。RegFlushKey 把記憶體中快取的登錄檔已修改資料寫回到硬碟上，因此代價高昂，要慎重呼叫。

RegSetValueEx 把一個值項與其資料關聯到一個鍵上。RegDeleteVaule 從鍵上刪除一個值項。RegDeleteKey 刪除一個鍵，但直到關閉相應的登錄檔控制代碼（handle）才真正完成刪除操作。

RegEnumKeyEx 列舉一個鍵下的所有子鍵。RegEnumValue 列舉一個鍵下的所有值項。RegQueryValueEx 取得一個值項的資料。

RegSaveKeyEx 可以把一個鍵及所有子鍵儲存到一個檔案中。RegLoadKey 把一個登錄檔檔案裝入到系統的登錄檔，RegUnLoadKey 把系統登錄檔恢復到原狀態。

## 缺點

評論家將 Windows 95 的登錄檔視作「單點故障」，因為不當使用「登錄編輯程式」可能會造成嚴重的問題，甚至可能需要重新安裝作業系統。無法保證能夠順利解決因不當使用「登錄編輯程式」所造成的問題。您必須自行承擔使用「登錄編輯程式」的風險。建議您在編輯登錄前，先行備份。

### 分散與集中之爭

關於分散的文字檔案和集中的登錄檔兩種軟體組態方式的優劣，目前仍有爭論。主流作業系統中，Linux 作業系統一直使用單獨的文字檔案來存放組態資訊。而 Windows 平台下基於.NET 框架的軟體對登錄檔的依賴性也大大減弱。事實上，.NET 軟體通常使用純文字的 XML（稱為 app.config）檔案而不是登錄檔進行組態，這在某種意義上是向當初的 ini 文字組態方式的一種回歸。部份可攜式軟體支持者認為，集中式的登錄檔要求軟體需要進行專門的安裝步驟才可以正常執行，而單獨的文字設定檔則可以不需要安裝，只要將軟體的檔案目錄拷貝過來就可以使用；當不再需要軟體的時候，除刪除相關檔案外對於登錄檔也需要進行移除步驟，才有可能不在系統中留下痕跡（很多軟體即使提供了移除步驟，仍然會留下痕跡），如果使用文字設定檔，則能做得更乾淨。但是，文字組態方式導致某些系統軟體的組態較為困難且缺乏統一的介面（如 Linux 中的情況），也是不爭的事實，儘管現在已經有很多軟體可以方便進行系統設定，但仍存在標準不夠統一的問題。

著名開源軟體 Fetchmail 的作者 Eric S. Raymond 在《UNIX 編程藝術》一書中有如下敘述：

> 對比 terminfo 資料庫和 Windows 登錄檔，我們發現登錄檔出名地容易受到錯誤程式碼的破壞。這可能會使整個系統都無法使用。即使系統沒有癱瘓，但如果破壞本身干擾了專用的登錄檔編輯工具，恢復工作就會很困難。
> 
> 

從 2000 年以來部份惡性病毒如熊貓燒香等的破壞情形看，的確存在「破壞本身干擾登錄編輯程式」的問題。在某些情況下，病毒程式會監視系統處理程序列表，並強行關閉名為 regedit 的任何程式。這使得受損使用者難以直接通過編輯登錄檔進行恢復。

登錄檔是 Windows 作業系統的核心，越來越多的駭客程式將攻擊物件轉向了登錄檔。一些程式（尤其是惡意程式），為了達到隨系統自動啟動的目的，會在登錄檔建立啟動項，因此監視登錄檔能夠有效地預防該類惡意程式的攻擊。

## 注釋

## 參考資料

* Windows XP 專業版從入門到精通（中文版），Mark Minasi 著，王珺、屈馬瓏等譯，ISBN 7-5053-7569-5
* Unix 編程藝術（簡體中文版），Eric S. Raymond 著，姜宏 何源 蔡曉俊 譯，電子工業出版社 ISBN 7-121-02116-1

## 參見

* Microsoft Windows