在上一篇《用 Visual C# 讀取登錄表信息》中,我們已經介紹了如何讀取 Windows 登錄表。本文將深入講解一項具備破壞性的操作——刪除登錄表中的鍵值、子鍵乃至整個子鍵樹。由於錯誤操作可能導致系統不穩定,請務必在測試環境中驗證後再應用於生產環境。
C# 本身不包含直接操作登錄表的類庫,所有操作均通過 Microsoft.Win32 命名空間下的兩個核心類別實現:
LocalMachine、CurrentUser)。刪除指定的單層子鍵。若該子鍵下仍包含其他子鍵,會拋出例外。
throwOnMissing = false 時,找不到不報錯,適合防禦性程式設計。遞歸刪除指定子鍵及其所有後代子鍵與值。破壞力極強,使用前請三思。
刪除指定鍵下的單個值,不影響子鍵結構。
RegistryKey.OpenSubKey(string name, bool writable) 的第二個參數決定是否取得寫入權限:
false(預設):唯讀,適合讀取場景。true:可寫,執行刪除、修改、新增時必須指定 true,否則運行時會拋出 UnauthorizedAccessException。下列程式碼建立一個視窗,包含四個按鈕分別示範:讀取現狀、刪除值、刪除無子鍵的子鍵、刪除含子鍵的子鍵樹。程式啟動前請先在 HKEY_LOCAL_MACHINE\SOFTWARE\aaa 下手動建立文中所述的測試結構(bbb/ccc、ddd/eee/fff)。
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.Win32;
public class RegDeleteDemo : Form
{
private ListBox lstLog = new ListBox();
private Button btnRead = new Button { Text = "讀取登錄表", Left = 16, Top = 320, Width = 100 };
private Button btnDelVal = new Button { Text = "刪除值 ccc", Left = 116, Top = 320, Width = 100 };
private Button btnDelSub = new Button { Text = "刪除子鍵 bbb", Left = 216, Top = 320, Width = 100 };
private Button btnDelTree = new Button { Text = "刪除子鍵樹 ddd", Left = 316, Top = 320, Width = 120 };
public RegDeleteDemo()
{
Text = "C# 登錄表刪除操作示範";
ClientSize = new Size(528, 357);
lstLog.Location = new Point(16, 32);
lstLog.Size = new Size(496, 264);
Controls.AddRange(new Control[] { lstLog, btnRead, btnDelVal, btnDelSub, btnDelTree });
btnRead.Click += BtnRead_Click;
btnDelVal.Click += BtnDelVal_Click;
btnDelSub.Click += BtnDelSub_Click;
btnDelTree.Click += BtnDelTree_Click;
}
// 讀取並顯示 aaa 下的所有子鍵與值
private void BtnRead_Click(object sender, EventArgs e)
{
lstLog.Items.Clear();
using (var hklm = Registry.LocalMachine)
using (var software = hklm.OpenSubKey("SOFTWARE"))
using (var aaa = software?.OpenSubKey("aaa"))
{
if (aaa == null) return;
foreach (var subName in aaa.GetSubKeyNames())
{
lstLog.Items.Add(subName);
using (var sub = aaa.OpenSubKey(subName))
{
foreach (var valName in sub.GetValueNames())
lstLog.Items.Add($" {valName} = {sub.GetValue(valName)}");
}
}
}
}
// 刪除 bbb\ccc 值
private void BtnDelVal_Click(object sender, EventArgs e)
{
using (var hklm = Registry.LocalMachine)
using (var software = hklm.OpenSubKey("SOFTWARE", true))
using (var aaa = software?.OpenSubKey("aaa", true))
using (var bbb = aaa?.OpenSubKey("bbb", true))
bbb?.DeleteValue("ccc");
MessageBox.Show("已嘗試刪除值 ccc");
}
// 刪除不含子鍵的 bbb
private void BtnDelSub_Click(object sender, EventArgs e)
{
using (var hklm = Registry.LocalMachine)
using (var software = hklm.OpenSubKey("SOFTWARE", true))
using (var aaa = software?.OpenSubKey("aaa", true))
aaa?.DeleteSubKey("bbb", false); // 不拋出例外
MessageBox.Show("已嘗試刪除子鍵 bbb");
}
// 刪除含子鍵的 ddd(連同 eee/fff 一併移除)
private void BtnDelTree_Click(object sender, EventArgs e)
{
using (var hklm = Registry.LocalMachine)
using (var software = hklm.OpenSubKey("SOFTWARE", true))
using (var aaa = software?.OpenSubKey("aaa", true))
aaa?.DeleteSubKeyTree("ddd");
MessageBox.Show("已嘗試刪除子鍵樹 ddd");
}
[STAThread]
static void Main() => Application.Run(new RegDeleteDemo());
}
writable=true,讀取時保持唯讀。DeleteSubKey(key, false) 避免因鍵不存在而中斷流程。using 區塊確保 RegistryKey 正確釋放非託管控制碼。LocalMachine 需管理員權限,請在應用程式資訊清單中設定 requireAdministrator。掌握 DeleteValue、DeleteSubKey、DeleteSubKeyTree 三大方法,搭配正確的 OpenSubKey(..., true) 寫入模式,即可在 C# 中安全、精準地執行登錄表刪除操作。實務上請嚴守「先備份、再驗證、後部署」原則,將風險降至最低。