註冊表

註冊表（Registry，中國大陸譯作-{zh-hans:註冊表;zh-hant:註冊表;}-，港澳臺譯作-{zh-hant:登錄檔;zh-hans:登錄檔;}-）是 Microsoft Windows 操作系統和其應用程序中的一個重要的 層次型數據庫，用於存儲系統和應用程序的底層設置信息。
總的來說，註冊表包含了 Microsoft Windows 操作系統上的信息、設置、選項和安裝的硬件。例如，安裝程序時包含程序位置、版本和啟動程序方式等設置的子項會被添加到註冊表中。
早在 Windows 3.0推出OLE技術的時候，註冊表就已經出現，但主要用於存儲 組件對象模型 的組件的配置信息。但是，從Windows 95開始，註冊表擴展了其用途以集中化合理化的管理INI文件中的信息，真正成為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，或稱“項”）和值（value）構成。一個鍵就是樹狀數據結構中的一個節點，而子鍵就是這個節點的子節點，子鍵也是鍵。一個值項則是一個鍵的一條屬性，由名稱（name）、數據類型（datatype）以及數據（data）組成。一個鍵可以有一個或多個值，每個值的名稱各不相同，如果一個值的名稱為空，則該值為該鍵的默認值。
在註冊表編輯器（Regedit.exe）中，數據結構顯示如下，其中，command鍵是open鍵的子鍵，(默認)表示該值是默認值，值名稱為空，其數據類型為REG_SZ，數據值為%systemroot%\system32\NOTEPAD.EXE "%1
以上信息的意義是：txt類型的文件在右鍵菜單裡的“-{zh-hans:打開; zh-hant:開啟;}-”一項使用的程序是“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編程藝術》一書中有如下敘述：
從2000年以來部分惡性病毒如熊貓燒香等的破壞情形看，的確存在“破壞本身干擾註冊表編輯器”的問題。在某些情況下，病毒程序會監視系統進程列表，並強行關閉名為regedit的任何程序。這使得受損用戶難以直接通過編輯註冊表進行恢復。
註冊表是Windows操作系統的核心，越來越多的黑客程序將攻擊對象轉向了註冊表。一些程序（尤其是惡意程序），為了達到隨系統自動啟動的目的，會在註冊表創建啟動項，因此監控註冊表能夠有效地預防該類惡意程序的攻擊。

**註釋**

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

**參見**
 Microsoft Windows