<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Administration on kenji.blog</title><link>http://kenji.blog/zh-tw/categories/administration/</link><description>Recent content in Administration on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 12:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/zh-tw/categories/administration/index.xml" rel="self" type="application/rss+xml"/><item><title>Windows 登錄檔的基礎知識與可程式化之安全編輯方法</title><link>http://kenji.blog/zh-tw/p/windows-registry-safe-programmable-editing/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/zh-tw/p/windows-registry-safe-programmable-editing/</guid><description>&lt;img src="http://kenji.blog/p/windows-registry-safe-programmable-editing/img/eyecatch.jpg" alt="Featured image of post Windows 登錄檔的基礎知識與可程式化之安全編輯方法" />&lt;h1 id="windows-登錄檔的基礎知識與可程式化之安全編輯方法">Windows 登錄檔的基礎知識與可程式化之安全編輯方法
&lt;/h1>&lt;p>在 Windows 作業系統中，「登錄檔（Registry）」是一個用來儲存系統和應用程式各種設定的龐大階層式資料庫。本文將從 Windows 登錄檔的基礎架構開始，非常詳細地解說如何使用 PowerShell 和 C# 進行可程式化且安全的登錄檔編輯方法。&lt;/p>
&lt;h2 id="1-簡介windows-登錄檔的歷史與演進">1. 簡介：Windows 登錄檔的歷史與演進
&lt;/h2>&lt;p>在 Windows 的早期版本（Windows 3.x 時代）中，系統與應用程式的設定主要儲存在 &lt;code>.ini&lt;/code>（初始化檔案）裡。然而，隨著每個應用程式的無數 INI 檔案散佈在整個系統中，管理變得極度繁雜。此外，由於 INI 檔案是基於純文字格式，難以儲存二進位資料，且不存在存取控制（安全性）的機制。檔案的解析速度也很慢，不適合用來儲存大規模的設定。&lt;/p>
&lt;p>為了根本解決這些問題，從 Windows NT 和 Windows 95 開始，正式採用了「登錄檔」作為集中式的設定資料庫。登錄檔是一個階層化的資料庫，提供強型別、二進位資料的支援，以及透過存取控制清單（ACL）達成的堅固安全性功能。這使得從作業系統核心到使用者空間的應用程式等所有元件，都能透過統一的介面（Win32 API 的 &lt;code>Reg*&lt;/code> 函式群）來讀寫設定。&lt;/p>
&lt;p>一直到現代的 Windows 11，登錄檔仍然持續作為作業系統的核心在運作。硬體配置、裝置驅動程式的載入順序、使用者的桌面環境、已安裝軟體的清單等，系統運作所需的所有中繼資料都集中在登錄檔中。&lt;/p>
&lt;h2 id="2-架構深層登錄檔-hive-的實體與記憶體對應">2. 架構深層：登錄檔 Hive 的實體與記憶體對應
&lt;/h2>&lt;p>登錄檔在邏輯上雖然看起來是一個巨大的樹狀結構，但在實體上是被分割成多個稱為「Hive」的檔案並儲存在磁碟上。這樣可以將整個系統的設定與使用者特定的設定分離，實現高效的讀取。&lt;/p>
&lt;p>主要的 Hive 檔案通常存在於 &lt;code>%SystemRoot%\System32\config&lt;/code> 目錄中。&lt;/p>
&lt;ul>
&lt;li>&lt;code>SYSTEM&lt;/code>: 作業系統啟動所需的重要設定（驅動程式、服務、開機設定等）。&lt;/li>
&lt;li>&lt;code>SOFTWARE&lt;/code>: 已安裝軟體之全系統設定。第三方應用程式的設定大多存放在這裡。&lt;/li>
&lt;li>&lt;code>SAM&lt;/code>: 安全性帳戶管理員 (Security Accounts Manager)（本機使用者帳戶與密碼雜湊）。&lt;/li>
&lt;li>&lt;code>SECURITY&lt;/code>: 本機安全性原則與權限指派。&lt;/li>
&lt;li>&lt;code>DEFAULT&lt;/code>: 預設使用者的設定檔（建立新使用者時的範本）。&lt;/li>
&lt;/ul>
&lt;p>使用者個別的 Hive 檔案則作為隱藏檔案存在於使用者的設定檔目錄中（例如：&lt;code>C:\Users\Username&lt;/code>）。&lt;/p>
&lt;ul>
&lt;li>&lt;code>NTUSER.DAT&lt;/code>: 該使用者的基本設定（HKCU 的大部分）。&lt;/li>
&lt;li>&lt;code>UsrClass.dat&lt;/code>: 該使用者的檔案副檔名關聯設定（存在於 &lt;code>AppData\Local\Microsoft\Windows&lt;/code> 中）。&lt;/li>
&lt;/ul>
&lt;p>這些檔案會在作業系統啟動時，由核心的「設定管理員 (Configuration Manager, CM)」對應到核心分頁集區記憶體中。設定管理員是處理登錄檔讀寫要求的核心模式元件。&lt;/p>
&lt;p>值得一提的是，並非所有登錄檔資料都存在於磁碟上。例如，&lt;code>HARDWARE&lt;/code> Hive 是揮發性（Volatile）的，完全不會儲存在磁碟上的檔案中。每次作業系統啟動，隨插即用（PnP）管理員偵測到硬體時，就會在記憶體中動態重建。&lt;/p>
&lt;p>此外，為了提高登錄檔的可靠性，最新的 Windows 實作了交易記錄（Transaction Logging）。對 Hive 檔案的變更不會直接寫入資料檔，而是會先記錄在交易記錄檔（&lt;code>.log1&lt;/code>, &lt;code>.log2&lt;/code>）中。這可以防止在寫入過程中發生意外斷電或系統當機時的資料損毀（Corruption），並以接近 ACID 特性的方式確保資料庫的完整性。&lt;/p>
&lt;h2 id="3-登錄檔機碼與值的階層結構">3. 登錄檔機碼與值的階層結構
&lt;/h2>&lt;p>登錄檔具有非常類似於檔案系統的階層結構。作為根節點的部分稱為「根機碼（Root Key）」或「Hive」，其下方會儲存「機碼（Key）」、「子機碼（Subkey）」，以及作為資料實體的「值（Value）」。可以將機碼想像成目錄，值想像成檔案，這樣會更容易理解。&lt;/p>
&lt;p>主要的根機碼分為以下 5 種：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>HKEY_LOCAL_MACHINE (HKLM)&lt;/strong>: 儲存適用於整部電腦（所有使用者）的系統設定與軟體設定。變更需要管理員權限。&lt;/li>
&lt;li>&lt;strong>HKEY_CURRENT_USER (HKCU)&lt;/strong>: 儲存目前登入使用者的專屬設定。事實上，這並不是一個獨立的資料庫，而只是指向 &lt;code>HKEY_USERS&lt;/code> 下方對應使用者 SID（安全性識別碼）機碼的符號連結（別名）。&lt;/li>
&lt;li>&lt;strong>HKEY_CLASSES_ROOT (HKCR)&lt;/strong>: 儲存檔案副檔名關聯、COM（元件物件模型）類別的登錄資訊，以及 Shell 擴充功能。這個機碼很特殊，是由設定管理員將 &lt;code>HKLM\SOFTWARE\Classes&lt;/code>（全系統）與 &lt;code>HKCU\Software\Classes&lt;/code>（目前使用者）合併後顯示的虛擬檢視。若有衝突，則優先使用使用者特定的設定（HKCU）。&lt;/li>
&lt;li>&lt;strong>HKEY_USERS (HKU)&lt;/strong>: 儲存系統上所有使用者設定檔（目前已載入記憶體中者）的設定。它是基於 SID 進行階層化。&lt;/li>
&lt;li>&lt;strong>HKEY_CURRENT_CONFIG (HKCC)&lt;/strong>: 目前硬體設定檔的相關設定。實體是指向 &lt;code>HKLM\SYSTEM\CurrentControlSet\Hardware Profiles\Current&lt;/code> 的連結。&lt;/li>
&lt;/ol>
&lt;p>將這個複雜的階層結構與連結關係視覺化如下：&lt;/p>
&lt;pre class="mermaid">
mindmap
root((&amp;#34;Windows 登錄檔&amp;#34;))
HKLM((&amp;#34;HKEY_LOCAL_MACHINE&amp;#34;))
SAM((&amp;#34;SAM (安全性帳戶)&amp;#34;))
SECURITY((&amp;#34;SECURITY&amp;#34;))
SOFTWARE((&amp;#34;SOFTWARE&amp;#34;))
SYSTEM((&amp;#34;SYSTEM&amp;#34;))
HARDWARE((&amp;#34;HARDWARE (揮發性)&amp;#34;))
HKCU((&amp;#34;HKEY_CURRENT_USER (連結)&amp;#34;))
AppEvents((&amp;#34;AppEvents&amp;#34;))
Console((&amp;#34;Console&amp;#34;))
Software((&amp;#34;Software&amp;#34;))
System((&amp;#34;System&amp;#34;))
HKCR((&amp;#34;HKEY_CLASSES_ROOT (合併檢視)&amp;#34;))
HKU((&amp;#34;HKEY_USERS&amp;#34;))
SID((&amp;#34;使用者 SIDs...&amp;#34;))
HKCC((&amp;#34;HKEY_CURRENT_CONFIG (連結)&amp;#34;))
&lt;/pre>
&lt;h2 id="4-登錄檔的資料型別詳細解說">4. 登錄檔的資料型別（詳細解說）
&lt;/h2>&lt;p>登錄檔的「值」各自都定義了嚴格的資料型別。當以程式化的方式操作登錄檔時，正確理解這些型別並以適當的型別寫入資料是不可或缺的。如果以錯誤的型別寫入，可能會導致應用程式擲回例外狀況，或成為作業系統功能停止運作的原因。&lt;/p>
&lt;ul>
&lt;li>&lt;strong>REG_SZ (字串值)&lt;/strong>: 最常見的資料型別。儲存以 NULL 結尾的 Unicode 字串（UTF-16LE）。用於檔案路徑、URL、UI 顯示名稱等。&lt;/li>
&lt;li>&lt;strong>REG_DWORD (32 位元整數值)&lt;/strong>: 32 位元（4 個位元組）的無號整數值。頻繁用於布林值（0=停用、1=啟用）、以毫秒為單位的逾時值、錯誤碼設定等。由於 Windows 是 Little-Endian 架構，因此在磁碟上會從低位元組開始依序儲存（例如：0x12345678 會儲存為 &lt;code>78 56 34 12&lt;/code>）。&lt;/li>
&lt;li>&lt;strong>REG_QWORD (64 位元整數值)&lt;/strong>: 64 位元（8 個位元組）的整數值。隨著 64 位元架構的普及，用來儲存龐大的數值（如磁碟配額、大容量記憶體的大小指定等）或指標大小的設定。&lt;/li>
&lt;li>&lt;strong>REG_MULTI_SZ (多字串值)&lt;/strong>: 連續儲存多個以 NULL 結尾的字串，並在最後再放置一個空的 NULL 結尾字元（雙 NULL）作為終止的形式。適合用來儲存陣列狀的資料，如 IP 位址清單、具相依性的服務清單、繫結順序等。&lt;/li>
&lt;li>&lt;strong>REG_EXPAND_SZ (可擴充字串值)&lt;/strong>: 包含未展開之環境變數字串（例如 &lt;code>%USERPROFILE%&lt;/code> 或 &lt;code>%SystemRoot%&lt;/code>）的特殊字串型別。當應用程式透過 &lt;code>RegQueryValueEx&lt;/code> API 讀取，或呼叫 &lt;code>ExpandEnvironmentStrings&lt;/code> API 時，作業系統會動態將其展開為實際的絕對路徑。&lt;/li>
&lt;li>&lt;strong>REG_BINARY (二進位值)&lt;/strong>: 任意的原始二進位資料流。會儲存加密過的密碼（如 LSA Secrets）、數位憑證、應用程式特定的複雜結構或序列化資料。&lt;/li>
&lt;li>&lt;strong>REG_NONE&lt;/strong>: 未定義型別的資料。非常罕見，但會用於加密金鑰的保留區域等。&lt;/li>
&lt;li>&lt;strong>REG_RESOURCE_LIST&lt;/strong> / &lt;strong>REG_FULL_RESOURCE_DESCRIPTOR&lt;/strong>: 裝置驅動程式用來記錄硬體資源（IRQ、I/O 連接埠、DMA 通道）分配資訊的進階核心專用型別。&lt;/li>
&lt;/ul>
&lt;h2 id="5-作業系統中登錄檔的數學模型與效能">5. 作業系統中登錄檔的數學模型與效能
&lt;/h2>&lt;p>由於登錄檔直接關係到作業系統的效能（尤其是開機時間和處理程序的初始化速度），其內部使用了稱為「Cell Index」、類似 B-Tree（B 樹）的進階資料結構來進行最佳化。&lt;/p>
&lt;h3 id="搜尋的時間複雜度-time-complexity">搜尋的時間複雜度 (Time Complexity)
&lt;/h3>&lt;p>搜尋登錄檔內特定機碼（路徑）的時間複雜度 $T_{\text{search}}$ 取決於樹狀結構的深度以及各階層中的節點數量。探索深度為 $d$ 的子機碼（例如：&lt;code>A\B\C\D&lt;/code> 則 $d=4$）時的複雜度，理論上可以建立如下的模型：&lt;/p>
$$
T_{\text{search}}(d, L) = \sum_{i=1}^{d} O(\log(C_i) \cdot L_i)
$$&lt;p>這裡的 $C_i$ 是深度 $i$ 的子節點（子機碼或值）數量，$L_i$ 是作為比較目標的字串長度（字元數）。在作為登錄檔實體的 Hive 檔案中，子機碼清單是以名稱的雜湊值或依字母順序排序的索引來保存。因此，它可以進行二元搜尋 $O(\log(C_i))$，而不是單純的線性搜尋 $O(C_i)$，即使一個機碼下存在數萬個子機碼，也能實現極快的存取速度。&lt;/p>
&lt;h3 id="儲存空間使用量-space-complexity">儲存空間使用量 (Space Complexity)
&lt;/h3>&lt;p>登錄檔的整體大小（在實體磁碟上的占用量）是計算各 Hive 的總和。&lt;/p>
$$
\text{Size}_{\text{Total}} = \sum_{h \in \text{Hives}} \left( N_{h} \times S_{\text{key\_metadata}} + \sum_{v \in h} S_{\text{value}}(v) \right) + S_{\text{overhead}}
$$&lt;p>$N_h$ 是 Hive $h$ 內的機碼數量，$S_{\text{key\_metadata}}$ 是每個機碼的中繼資料（最後寫入的時間戳記、安全性描述元的指標、父機碼的指標等）大小，$S_{\text{value}}(v)$ 則是值 $v$ 的有效負載大小。其中還包含了交易記錄檔或不再需要的空白單元（碎片化）所造成的額外負擔 $S_{\text{overhead}}$。如果登錄檔中長期放置不需要的資料（例如未完全解除安裝的軟體殘骸），這個空間占用就會增加，可能會壓迫作業系統的分頁集區記憶體，從而導致效能下降。&lt;/p>
&lt;h2 id="6-威脅系統穩固性的手動編輯風險與損毀機率">6. 威脅系統穩固性的手動編輯風險與損毀機率
&lt;/h2>&lt;p>使用登錄編輯程式（&lt;code>regedit.exe&lt;/code>）進行手工作業的編輯，應被視為系統管理的最後手段。登錄檔並沒有內建像一般文件編輯器那樣的「復原（Undo）」功能，對於值的變更或機碼的刪除，會立即透過設定管理員反映在系統上。&lt;/p>
&lt;p>特別是對於系統啟動不可或缺的關鍵機碼（例如：&lt;code>HKLM\SYSTEM\CurrentControlSet\Services&lt;/code> 底下的磁碟控制器驅動程式設定，或是 &lt;code>HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon&lt;/code> 的 &lt;code>Userinit&lt;/code> 值等），就算只是一個字元誤編或誤刪，都存在著導致作業系統發生藍白畫面（BSoD）而無法開機，或是停留在登入畫面無法繼續前進（黑畫面）的致命風險。&lt;/p>
&lt;h3 id="損毀機率的數學模型">損毀機率的數學模型
&lt;/h3>&lt;p>讓我們來考慮一下，如果隨機變更或刪除登錄檔內的機碼，發生系統故障的機率。假設讓系統正常運作不可或缺的關鍵機碼集合為 $C$，其總數為 $N_c = |C|$。登錄檔整體的機碼總數為 $N_{\text{total}}$。
若隨機刪除或破壞 $k$ 個機碼，則至少有一個關鍵機碼損毀的機率 $P_{\text{failure}}$，可透過取出不放回（Sampling without replacement）的機率計算表示如下：&lt;/p>
$$
P_{\text{failure}} = 1 - \frac{\binom{N_{\text{total}} - N_c}{k}}{\binom{N_{\text{total}}}{k}} = 1 - \prod_{i=0}^{k-1} \left( 1 - \frac{N_c}{N_{\text{total}} - i} \right)
$$&lt;p>登錄檔整體的機碼數量 $N_{\text{total}}$ 大約在數十萬到數百萬的數量級，而 $N_c$ 也存在數萬的數量級。在數學上，即使是隨機操作，只要 $k$ 增加，故障機率就會急遽上升。況且在現實的手動操作中，使用者並非「隨機」編輯，而是會刻意去操作與系統設定或軟體運作有直接關係的部位（例如看著教學網站進行），因此觸碰到關鍵機碼的機率會遠比上述的理論值還要高。&lt;/p>
&lt;h2 id="7-登錄檔的虛擬化與-wow64-架構">7. 登錄檔的虛擬化與 WOW64 架構
&lt;/h2>&lt;p>Windows 為了維持舊版應用程式的相容性，對登錄檔存取實作了幾種進階的「虛擬化（重新導向）」機制。如果在不了解這一點的情況下進行程式設計，將會成為引發重大 Bug 的原因。&lt;/p>
&lt;h3 id="uac-登錄檔虛擬化-registry-virtualization">UAC 登錄檔虛擬化 (Registry Virtualization)
&lt;/h3>&lt;p>從 Windows Vista 開始，引入了使用者帳戶控制（UAC）。當 Windows XP 時代所開發的舊應用程式（以標準使用者權限執行），嘗試寫入原本需要管理員權限的 &lt;code>HKLM\SOFTWARE&lt;/code> 等受保護機碼時，為了防止因存取遭拒（Access Denied）錯誤而當機，Windows 會悄悄地將該寫入操作重新導向至使用者設定檔內的虛擬存放區 &lt;code>HKCU\Software\Classes\VirtualStore\MACHINE\SOFTWARE&lt;/code>。讀取時，也會將原始位置與虛擬存放區合併後傳回。如此一來，應用程式就能在未偵測到錯誤的情況下繼續正常運作。
但是，如果要開發以程式化方式變更整個系統設定的工具，就必須在資訊清單檔案（Manifest file）中指定 &lt;code>&amp;lt;requestedExecutionLevel level=&amp;quot;requireAdministrator&amp;quot; /&amp;gt;&lt;/code> 來停用此虛擬化功能。&lt;/p>
&lt;h3 id="wow64-windows-32-bit-on-windows-64-bit-的重新導向">WOW64 (Windows 32-bit on Windows 64-bit) 的重新導向
&lt;/h3>&lt;p>在 64 位元版的 Windows（目前的主流）上執行舊的 32 位元應用程式時，為了避免 32 位元應用程式不小心覆寫了 64 位元原生的系統設定，或載入不相容的 64 位元 DLL，特定的登錄機碼會被自動隔離並重新導向。
例如，當 32 位元應用程式嘗試存取 &lt;code>HKLM\SOFTWARE\Vendor\App&lt;/code> 時，作業系統會透通地將其重新導向至 &lt;code>HKLM\SOFTWARE\WOW6432Node\Vendor\App&lt;/code>。&lt;/p>
&lt;pre class="mermaid">
flowchart TD
App32[&amp;#34;32 位元應用程式&amp;#34;]
App64[&amp;#34;64 位元應用程式&amp;#34;]
RegAPI[&amp;#34;登錄檔 API (Advapi32.dll)&amp;#34;]
CM[&amp;#34;設定管理員 (核心)&amp;#34;]
HKLM_Soft[&amp;#34;HKLM\SOFTWARE&amp;#34;]
HKLM_WOW64[&amp;#34;HKLM\SOFTWARE\WOW6432Node&amp;#34;]
App32 --&amp;gt;| RegOpenKeyEx() | RegAPI
App64 --&amp;gt;| RegOpenKeyEx() | RegAPI
RegAPI --&amp;gt; CM
CM --&amp;gt;| 如果是 64 位元處理程序 | HKLM_Soft
CM --&amp;gt;| 如果是 32 位元處理程序 (重新導向) | HKLM_WOW64
&lt;/pre>
&lt;p>從 PowerShell 指令碼或 C# 應用程式編輯登錄檔時，必須強烈意識到正在執行的處理程序本身是 32 位元還是 64 位元。否則，將會引發「明明已經寫入的設定卻在檔案總管中看不到（寫到其他地方去了）」這種棘手的問題。&lt;/p>
&lt;h2 id="8-透過-powershell-進行可程式化的安全編輯">8. 透過 PowerShell 進行可程式化的安全編輯
&lt;/h2>&lt;p>為了將手動編輯登錄檔的風險降到最低，現代的最佳實務是使用 PowerShell 指令碼將操作程式碼化（基礎架構即程式碼，Infrastructure as Code），以確保自動化、可重現性與可測試性。PowerShell 具備了「Registry Provider（登錄檔提供者）」，能以操作檔案系統（如 C: 磁碟機）完全相同的 Cmdlet（例如 &lt;code>Get-ChildItem&lt;/code>、&lt;code>Get-ItemProperty&lt;/code>、&lt;code>New-Item&lt;/code> 等）來透通地操作登錄檔。&lt;/p>
&lt;p>PowerShell 預設已經掛載了 &lt;code>HKLM:&lt;/code> 與 &lt;code>HKCU:&lt;/code> 這種專屬的 PSDrive（類似於磁碟機代號）。&lt;/p>
&lt;h3 id="基本的-crud-操作">基本的 CRUD 操作
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 1. 確認存在與否 (Read)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$keyPath&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;HKCU:\Software\MyCustomApp&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">-Not&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nb">Test-Path&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="nv">$keyPath&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># 2. 建立新機碼 (Create)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">New-Item&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="s2">&amp;#34;HKCU:\Software&amp;#34;&lt;/span> &lt;span class="n">-Name&lt;/span> &lt;span class="s2">&amp;#34;MyCustomApp&amp;#34;&lt;/span> &lt;span class="n">-Force&lt;/span> &lt;span class="p">|&lt;/span> &lt;span class="nb">Out-Null&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">Write-Host&lt;/span> &lt;span class="s2">&amp;#34;已建立機碼。&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 3. 寫入或更新值 (Update) - 將 1 寫入為 REG_DWORD&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Set-ItemProperty&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="nv">$keyPath&lt;/span> &lt;span class="n">-Name&lt;/span> &lt;span class="s2">&amp;#34;EnableDebug&amp;#34;&lt;/span> &lt;span class="n">-Value&lt;/span> &lt;span class="mf">1&lt;/span> &lt;span class="n">-Type&lt;/span> &lt;span class="n">DWord&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 4. 讀取值 (Read)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$debugFlag&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nb">Get-ItemProperty&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="nv">$keyPath&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="py">EnableDebug&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Write-Host&lt;/span> &lt;span class="s2">&amp;#34;目前的偵錯旗標: &lt;/span>&lt;span class="nv">$debugFlag&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 5. 刪除值 (Delete)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Remove-ItemProperty&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="nv">$keyPath&lt;/span> &lt;span class="n">-Name&lt;/span> &lt;span class="s2">&amp;#34;EnableDebug&amp;#34;&lt;/span> &lt;span class="n">-Force&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="實作範例-1開發環境的自動設定新增環境變數-path">實作範例 1：開發環境的自動設定（新增環境變數 PATH）
&lt;/h3>&lt;p>以下的指令碼是一個自動化的範例，可讓開發人員在設定新的 Windows 機器時，將自訂工具的目錄安全地新增至使用者環境變數 &lt;code>PATH&lt;/code> 中。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$envKey&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;HKCU:\Environment&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$newPath&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;C:\tools\bin&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 讀取目前的 PATH（抑制錯誤以確保安全取得）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$currentPathInfo&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nb">Get-ItemProperty&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="nv">$envKey&lt;/span> &lt;span class="n">-Name&lt;/span> &lt;span class="s2">&amp;#34;Path&amp;#34;&lt;/span> &lt;span class="n">-ErrorAction&lt;/span> &lt;span class="n">SilentlyContinue&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$currentPath&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nv">$currentPathInfo&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nv">$currentPathInfo&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="py">Path&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 使用正則表達式檢查是否已經包含&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nv">$currentPath&lt;/span> &lt;span class="o">-notmatch&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="no">regex&lt;/span>&lt;span class="p">]::&lt;/span>&lt;span class="n">Escape&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">$newPath&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># 如果結尾沒有分號則加上並進行合併&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nv">$currentPath&lt;/span> &lt;span class="o">-and&lt;/span> &lt;span class="nv">$currentPath&lt;/span> &lt;span class="o">-notmatch&lt;/span> &lt;span class="s2">&amp;#34;;$&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">$currentPath&lt;/span> &lt;span class="p">+=&lt;/span> &lt;span class="s2">&amp;#34;;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">$updatedPath&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nv">$currentPath&lt;/span> &lt;span class="p">+&lt;/span> &lt;span class="nv">$newPath&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># 以 REG_EXPAND_SZ 型別寫入（重要）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">Set-ItemProperty&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="nv">$envKey&lt;/span> &lt;span class="n">-Name&lt;/span> &lt;span class="s2">&amp;#34;Path&amp;#34;&lt;/span> &lt;span class="n">-Value&lt;/span> &lt;span class="nv">$updatedPath&lt;/span> &lt;span class="n">-Type&lt;/span> &lt;span class="n">ExpandString&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">Write-Host&lt;/span> &lt;span class="s2">&amp;#34;已更新 PATH 環境變數: &lt;/span>&lt;span class="nv">$newPath&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># 通知執行中的處理程序環境變數已變更 (WM_SETTINGCHANGE)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># 如此一來，不需重新開機即可反映在新的檔案總管等程式中&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">[&lt;/span>&lt;span class="no">Environment&lt;/span>&lt;span class="p">]::&lt;/span>&lt;span class="n">SetEnvironmentVariable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Path&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nv">$updatedPath&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="no">EnvironmentVariableTarget&lt;/span>&lt;span class="p">]::&lt;/span>&lt;span class="n">User&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">Write-Host&lt;/span> &lt;span class="s2">&amp;#34;PATH 已經新增過了。&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="實作範例-2在快顯功能表中新增自訂動作">實作範例 2：在快顯功能表中新增自訂動作
&lt;/h3>&lt;p>這個指令碼會在右鍵點擊特定的檔案或目錄時的快顯功能表中，新增一個「使用 My IDE 開啟」的獨立項目。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 在目錄背景（空白處）點擊右鍵時的功能表&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$menuPath&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;HKCR:\Directory\Background\shell\OpenWithMyIDE&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$commandPath&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$menuPath&lt;/span>&lt;span class="s2">\command&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">try&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># 建立功能表項目的父機碼&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">New-Item&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="nv">$menuPath&lt;/span> &lt;span class="n">-Force&lt;/span> &lt;span class="n">-ErrorAction&lt;/span> &lt;span class="n">Stop&lt;/span> &lt;span class="p">|&lt;/span> &lt;span class="nb">Out-Null&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># 在 (default) 值中設定顯示名稱&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">Set-ItemProperty&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="nv">$menuPath&lt;/span> &lt;span class="n">-Name&lt;/span> &lt;span class="s2">&amp;#34;(default)&amp;#34;&lt;/span> &lt;span class="n">-Value&lt;/span> &lt;span class="s2">&amp;#34;使用 My IDE 開啟&amp;#34;&lt;/span> &lt;span class="n">-Type&lt;/span> &lt;span class="n">String&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># 設定圖示（非必要）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">Set-ItemProperty&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="nv">$menuPath&lt;/span> &lt;span class="n">-Name&lt;/span> &lt;span class="s2">&amp;#34;Icon&amp;#34;&lt;/span> &lt;span class="n">-Value&lt;/span> &lt;span class="s2">&amp;#34;C:\Program Files\MyIDE\ide.exe,0&amp;#34;&lt;/span> &lt;span class="n">-Type&lt;/span> &lt;span class="n">String&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># 建立 command 子機碼，並設定要執行的命令列&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># %V 會展開為目前目錄的路徑變數&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">New-Item&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="nv">$commandPath&lt;/span> &lt;span class="n">-Force&lt;/span> &lt;span class="n">-ErrorAction&lt;/span> &lt;span class="n">Stop&lt;/span> &lt;span class="p">|&lt;/span> &lt;span class="nb">Out-Null&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">Set-ItemProperty&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="nv">$commandPath&lt;/span> &lt;span class="n">-Name&lt;/span> &lt;span class="s2">&amp;#34;(default)&amp;#34;&lt;/span> &lt;span class="n">-Value&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">`&amp;#34;&lt;/span>&lt;span class="s2">C:\Program Files\MyIDE\ide.exe&lt;/span>&lt;span class="se">`&amp;#34;&lt;/span>&lt;span class="s2"> &lt;/span>&lt;span class="se">`&amp;#34;&lt;/span>&lt;span class="s2">%V&lt;/span>&lt;span class="se">`&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span> &lt;span class="n">-Type&lt;/span> &lt;span class="n">String&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">Write-Host&lt;/span> &lt;span class="s2">&amp;#34;已新增快顯功能表項目。&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span> &lt;span class="k">catch&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">Write-Error&lt;/span> &lt;span class="s2">&amp;#34;登錄檔變更失敗。請確認是否以管理員權限執行。錯誤: &lt;/span>&lt;span class="nv">$_&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="從-powershell-存取登錄檔的內部序列">從 PowerShell 存取登錄檔的內部序列
&lt;/h3>&lt;p>以下為 PowerShell 指令碼變更登錄檔時，在作業系統內部的運作序列。&lt;/p>
&lt;pre class="mermaid">
sequenceDiagram
participant U as &amp;#34;管理員 / PowerShell&amp;#34;
participant PS as &amp;#34;登錄檔提供者 (.NET)&amp;#34;
participant CM as &amp;#34;設定管理員 (核心)&amp;#34;
participant Disk as &amp;#34;NTFS 上的 Hive 檔案&amp;#34;
U-&amp;gt;&amp;gt;PS: &amp;#34;Set-ItemProperty -Path ... -Value ...&amp;#34;
PS-&amp;gt;&amp;gt;PS: &amp;#34;解析路徑與驗證資料型別&amp;#34;
PS-&amp;gt;&amp;gt;CM: &amp;#34;NtSetValueKey (系統呼叫)&amp;#34;
CM-&amp;gt;&amp;gt;CM: &amp;#34;根據機碼 ACL 檢查存取權杖&amp;#34;
alt &amp;#34;授予存取權限 (管理員權杖)&amp;#34;
CM-&amp;gt;&amp;gt;CM: &amp;#34;在揮發性快取中配置單元&amp;#34;
CM-&amp;gt;&amp;gt;Disk: &amp;#34;排清至交易記錄檔 (.log1)&amp;#34;
Disk--&amp;gt;&amp;gt;CM: &amp;#34;記錄寫入成功&amp;#34;
CM-&amp;gt;&amp;gt;Disk: &amp;#34;延遲寫入至 Hive 資料檔 (背景)&amp;#34;
CM--&amp;gt;&amp;gt;PS: &amp;#34;STATUS_SUCCESS (0x00000000)&amp;#34;
PS--&amp;gt;&amp;gt;U: &amp;#34;命令已完成&amp;#34;
else &amp;#34;拒絕存取 (標準使用者)&amp;#34;
CM--&amp;gt;&amp;gt;PS: &amp;#34;STATUS_ACCESS_DENIED (0xC0000022)&amp;#34;
PS--&amp;gt;&amp;gt;U: &amp;#34;擲回 UnauthorizedAccessException&amp;#34;
end
&lt;/pre>
&lt;h2 id="9-透過-c-net-進行堅固的登錄檔存取">9. 透過 C# (.NET) 進行堅固的登錄檔存取
&lt;/h2>&lt;p>從 .NET 應用程式（如 C# 等）存取登錄檔時，會使用 &lt;code>Microsoft.Win32.Registry&lt;/code> 類別與 &lt;code>RegistryKey&lt;/code> 類別。
使用 C# 的最大優點在於：可透過強大的例外處理（&lt;code>try-catch&lt;/code>）進行堅固的錯誤處理、嚴格的型別檢查，以及能使用 &lt;code>RegistryView&lt;/code> 列舉明確指定 32 位元/64 位元的檢視畫面。&lt;/p>
&lt;p>以下是在 64 位元作業系統環境下，確實讀寫 64 位元端登錄檔（迴避 WOW6432Node 重新導向）的 C# 程式碼範例。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="nn">System&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="nn">System.Security&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="nn">Microsoft.Win32&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">RegistryEditor&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">static&lt;/span> &lt;span class="k">void&lt;/span> &lt;span class="n">Main&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// HKLM 底下的路徑 (需要管理員權限)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">string&lt;/span> &lt;span class="n">keyPath&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">@&amp;#34;SOFTWARE\MyEnterpriseApp\Settings&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 指定 RegistryView.Registry64 來開啟 64 位元原生檢視&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 使用 using 陳述式，確保登錄機碼的控制代碼 (非受控資源) 確實被 Dispose&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">try&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">using&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">RegistryKey&lt;/span> &lt;span class="n">baseKey&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">RegistryKey&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">OpenBaseKey&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">RegistryHive&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">LocalMachine&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">RegistryView&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Registry64&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 以寫入權限 (writable: true) 開啟機碼。若不存在則建立。&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">using&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">RegistryKey&lt;/span> &lt;span class="n">subKey&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">baseKey&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">CreateSubKey&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">keyPath&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">writable&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">subKey&lt;/span> &lt;span class="p">!=&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 寫入為 REG_DWORD 值&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">subKey&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">SetValue&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;MaxConnections&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="m">100&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">RegistryValueKind&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">DWord&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 寫入為 REG_SZ 值&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">subKey&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">SetValue&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;ApiEndpoint&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;https://api.example.com&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">RegistryValueKind&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">String&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 寫入為 REG_BINARY 位元組陣列&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">byte&lt;/span>&lt;span class="p">[]&lt;/span> &lt;span class="n">secretData&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="m">0x01&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="m">0x02&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="m">0x0A&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="m">0xFF&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">subKey&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">SetValue&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;BinarySecret&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">secretData&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">RegistryValueKind&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Binary&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;成功寫入登錄檔。&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">catch&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">UnauthorizedAccessException&lt;/span> &lt;span class="n">ex&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 未以管理員身分執行時經常發生&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">$&amp;#34;權限錯誤: 請「以系統管理員身分執行」程式。詳細: {ex.Message}&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">catch&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">SecurityException&lt;/span> &lt;span class="n">ex&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 被 .NET 的程式碼存取安全性 (CAS) 封鎖時&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">$&amp;#34;安全性例外狀況: {ex.Message}&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">catch&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">Exception&lt;/span> &lt;span class="n">ex&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// 其他非預期的 IO 錯誤等&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">Console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WriteLine&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">$&amp;#34;非預期的錯誤: {ex.Message}&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>開啟登錄機碼時，由作業系統傳回的「控制代碼（Handle）」，是會消耗記憶體與系統資源的非受控資源。因此，在 C# 程式設計中，使用 &lt;code>using&lt;/code> 區塊，或在 &lt;code>finally&lt;/code> 區塊內明確地呼叫 &lt;code>.Dispose()&lt;/code>（或 &lt;code>.Close()&lt;/code>）以確保防範控制代碼外洩，是一項鐵則。&lt;/p>
&lt;h2 id="10-登錄檔的備份與還原手法">10. 登錄檔的備份與還原手法
&lt;/h2>&lt;p>即使是透過指令碼或程式進行的自動化，在進行關鍵變更之前，取得備份絕對是不可或缺的。&lt;/p>
&lt;h3 id="透過-reg-檔案備份與匯入">透過 .reg 檔案備份與匯入
&lt;/h3>&lt;p>最古典且通用的方法就是匯出為 &lt;code>.reg&lt;/code> 檔案。這個檔案是具有獨特格式的文字型檔案，其結構如下：&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">Windows Registry Editor Version 5.00
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">[HKEY_CURRENT_USER\Software\MyCustomApp]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;#34;EnableDebug&amp;#34;=dword:00000001
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;#34;ApiEndpoint&amp;#34;=&amp;#34;https://api.example.com&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;#34;BinaryData&amp;#34;=hex:01,02,0a,ff
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;em>註：二進位資料是以接在 &lt;code>hex:&lt;/code> 後面、以逗號分隔的 16 進位數來表示。&lt;/em>&lt;/p>
&lt;p>您可以使用命令列工具 &lt;code>reg.exe&lt;/code>，在批次指令碼內實作自動備份。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmd" data-lang="cmd">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">REM 備份指定的機碼（也會遞迴匯出子機碼）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">reg export HKLM\SOFTWARE\MyEnterpriseApp C:\backup\myapp_backup.reg /y
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">REM 還原備份&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">reg import C:\backup\myapp_backup.reg
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="利用-powershell-的進階備份手法">利用 PowerShell 的進階備份手法
&lt;/h3>&lt;p>不僅僅是作為文字，我們還可以活用 PowerShell 的物件導向特性，將登錄檔的物件匯出並儲存為 XML 格式（CliXML）。這樣一來，在還原時就不必依賴字串的解析，並能在維持型別資訊的情況下進行處理。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 取得備份（將屬性儲存為 XML）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">Get-ItemProperty&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="s2">&amp;#34;HKCU:\Software\MyCustomApp&amp;#34;&lt;/span> &lt;span class="p">|&lt;/span> &lt;span class="nb">Export-Clixml&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="s2">&amp;#34;C:\backup\reg_backup.xml&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 還原的概念&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$backup&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nb">Import-Clixml&lt;/span> &lt;span class="n">-Path&lt;/span> &lt;span class="s2">&amp;#34;C:\backup\reg_backup.xml&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 由於 $backup 內儲存了已還原的自訂 PSObject，&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># 因此可透過迴圈讀取其屬性，並編寫使用 Set-ItemProperty 重新套用的邏輯。&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="11-使用-sysinternals-process-monitor-procmon-進行疑難排解">11. 使用 Sysinternals Process Monitor (Procmon) 進行疑難排解
&lt;/h2>&lt;p>若不清楚程式寫入了登錄檔的哪個地方，或者想尋找「Access Denied」的原因時，Microsoft 免費提供的 Sysinternals 工具 &lt;strong>Process Monitor (Procmon)&lt;/strong> 非常強大。
使用 Procmon，可以即時擷取在作業系統上發生的所有登錄檔 API 呼叫（如 &lt;code>RegOpenKey&lt;/code>、&lt;code>RegQueryValue&lt;/code>、&lt;code>RegSetValue&lt;/code> 等），並透過以下進階篩選功能進行疑難排解：&lt;/p>
&lt;ul>
&lt;li>&lt;code>Process Name&lt;/code> is &lt;code>powershell.exe&lt;/code>&lt;/li>
&lt;li>&lt;code>Operation&lt;/code> begins with &lt;code>Reg&lt;/code>&lt;/li>
&lt;li>&lt;code>Result&lt;/code> is &lt;code>ACCESS DENIED&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>這樣一來，就能在瞬間找出是哪個機碼的 ACL 設定不足，或者是是否錯誤地重新導向到了 WOW6432Node。&lt;/p>
&lt;h2 id="12-安全性與最佳實務">12. 安全性與最佳實務
&lt;/h2>&lt;p>最後，總結在處理登錄檔時重要的設計原則與最佳實務。&lt;/p>
&lt;ol>
&lt;li>&lt;strong>貫徹最低權限原則&lt;/strong>：應用程式或指令碼的設定，應盡可能儲存在 &lt;code>HKCU&lt;/code>（目前使用者）內的 &lt;code>Software&lt;/code> 機碼底下。寫入 &lt;code>HKLM&lt;/code> 會要求透過 UAC 提升至管理員權限，這將擴大安全性上的攻擊面（Attack Surface），並損害使用者體驗。&lt;/li>
&lt;li>&lt;strong>啟用稽核 (Auditing)&lt;/strong>：針對安全性上極其重要的機碼（例如：負責自動啟動的 &lt;code>Run&lt;/code> 機碼，或服務設定的機碼等），應設定 SACL（System Access Control List，系統存取控制清單），以便在 Windows 事件檢視器的「安全性記錄」中，記錄（稽核）是誰在何時變更或刪除了值。&lt;/li>
&lt;li>&lt;strong>因應交易功能的棄用&lt;/strong>：過去在 Windows Vista 導入、利用「核心交易管理員 (KTM)」的登錄檔交易功能 (TxR)，自 Windows 10 起已標示為已被取代（Deprecated）。必須在應用程式端自行實作備份與復原機制（例如在變更前先讀取原始值並保留在記憶體中）。&lt;/li>
&lt;li>&lt;strong>注意與群組原則 (GPO) 的衝突&lt;/strong>：&lt;code>HKLM\SOFTWARE\Policies&lt;/code> 和 &lt;code>HKCU\Software\Policies&lt;/code> 區域，應交由 Active Directory 的群組原則統一管理。即使從指令碼直接改寫這些機碼，在下一次群組原則背景更新週期（通常每隔 90 到 120 分鐘）時，也會被網域控制站的設定強制覆寫，成為設定無法永久保留的原因。&lt;/li>
&lt;/ol>
&lt;h2 id="總結">總結
&lt;/h2>&lt;p>Windows 登錄檔是個強大且複雜的基礎系統，統整管理了作業系統的所有行為與應用程式設定。手動且無序的編輯將伴隨極高的系統損毀風險，這在數學上也是可以被證實的。因此，使用 PowerShell 和 C# 等可程式化的手段，遵循「基礎架構即程式碼 (Infrastructure as Code)」的原則，以安全、可測試且可重現的方式進行組態管理，在現代的系統管理與開發中是不可或缺的。請活用本文所解說的深層架構理解與實作模式，目標是建構出更堅固且安全的 Windows 環境。&lt;/p></description></item></channel></rss>