[C#.NET][VB.NET] 如何 列舉 Registry / 使用 treeView 實作
1.Registry 類別 提供我們 讀/寫,昏到死的機碼
Registry 公開的機碼為:
- CurrentUser:儲存有關使用者喜好設定的資訊。這個欄位會讀取 Windows 登錄主要機碼 HKEY_CURRENT_USER。
- CurrentConfig:儲存非使用者特定的硬體資訊。這個欄位會讀取 Windows 登錄主要機碼 HKEY_CURRENT_CONFIG。
LocalMachine:儲存本機電腦 (Local Machine) 的組態資訊。這個欄位會讀取 Windows 登錄主要機碼 HKEY_LOCAL_MACHINE。
ClassesRoot:儲存有關型別 (和類別) 和屬性 (Property) 的資訊。這個欄位會讀取 Windows 登錄主要機碼 HKEY_CLASSES_ROOT。
Users:儲存有關預設使用者設定的資訊。這個欄位會讀取 Windows 登錄主要機碼 HKEY_USERS。
PerformanceData:儲存軟體元件的效能資訊。這個欄位會讀取 Windows 登錄主要機碼 HKEY_PERFORMANCE_DATA。
DynData:儲存動態 (Dynamic) 資料。這個欄位會讀取 Windows 登錄主要機碼 HKEY_DYN_DATA。動態機碼原本是在 Microsoft Windows 95 中所引入用來處理動態的登錄資料。它們只在 Windows 98/Windows ME 中支援。
2.Registry 類別 需要與RegistryKey 類別搭配使用,如下:
3.除了使用上述類別之外,VB的My類別系列也有My.Computer.Registry
ClassesRoot:對應至 HKEY_CLASSES_ROOT。
CurrentConfig:對應至 HKEY_CURRENT_CONFIG。
CurrentUser:對應至 HKEY_CURRENT_USER。
DynData:對應至 HKEY_DYNAMIC_DATA。
LocalMachine:對應至 HKEY_LOCAL_MACHINE。
PerformanceData:對應至。HKEY_PERFORMANCE_DATA。
Users:對應至 HKEY_USERS。
以下程式碼需要匯入
Microsoft.Win32 命名空間
如何列舉 Registry
1.引用類別
RegistryKey myReg = Registry.Users;
2.取得類別中的機碼名稱
String[] names = myReg.GetSubKeyNames();
3.列舉根目錄中的子目錄
string[] mySubKey = myReg.GetSubKeyNames();
foreach (string item in mySubKey)
{
listBox1.Items.Add(item);
}
基本上往下圖方向發展
Step1.開一個新的WinForm專案,拖曳一個splitContainer1至專案,拖曳treeView1至splitContainer1的左邊,拖曳listView1至splitContainer1的右邊(開始沒耐心打下去了
)
Step2.設定treeView1及listView1的Dock屬性為FIll
Step3.拖曳一個imageList1至專案,並加入圖庫。
Step4.設定listView1的Columns
Step5.在HandleCreated事件設定控制項的初始值
public Form1() { InitializeComponent();
this.HandleCreated += new EventHandler(Form1_HandleCreated);
}
void Form1_HandleCreated(object sender, EventArgs e)
{ //treeView1屬性設定 this.treeView1.ImageList = this.imageList1;//圖庫
//listView1屬性設定 this.listView1.View = View.Details; this.listView1.GridLines = true;
this.listView1.SmallImageList = this.imageList1;//圖庫
this.listView1.FullRowSelect = true;
//加入根目錄 TreeNode RootNode = new TreeNode("我的電腦", 2, 2);
this.treeView1.Nodes.Add(RootNode);
//加入主要目錄 TreeNode SubNode1 = new TreeNode("HKEY_CLASSES_ROOT", 0, 1);
RootNode.Nodes.Add(SubNode1);
TreeNode SubNode2 = new TreeNode("HKEY_CURRENT_USER", 0, 1);
RootNode.Nodes.Add(SubNode2);
TreeNode SubNode3 = new TreeNode("HKEY_LOCAL_MACHINE", 0, 1);
RootNode.Nodes.Add(SubNode3);
TreeNode SubNode4 = new TreeNode("HKEY_USERS", 0, 1);
RootNode.Nodes.Add(SubNode4);
TreeNode SubNode5 = new TreeNode("HKEY_CURRENT_CONFIG", 0, 1);
RootNode.Nodes.Add(SubNode5);
}
Step6.在treeView1的BeforeExpand事件加入以下程式碼,並觀察其變化。
//展開樹狀節點 private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{ foreach (TreeNode item in e.Node.Nodes)
{ AddSubRegKey(item);
}
}
//列舉子目錄 private void AddSubRegKey(TreeNode node)
{ //取得子目錄名稱 if (node.Nodes.Count == 0) { try { RegistryKey myReg = GetRegKey(node);
//Console.WriteLine("根目錄: " + node.Text); if (myReg != null)
{ //列舉根目錄中的子目錄 string[] mySubKey = myReg.GetSubKeyNames(); foreach (string item in mySubKey)
{ //Console.WriteLine("子目錄: "+item); node.Nodes.Add(item);
}
}
}
catch (Exception ee) { Console.WriteLine(ee.Message);
}
}
}
//取得節點的 "RegistryKey" private RegistryKey GetRegKey(TreeNode node) { //取得節點的完整名稱 string myRegName = node.Text; string myPath = node.FullPath; RegistryKey myReg = null; //給根目錄使用 //=========================================== switch (myRegName) { case "我的電腦":
myReg = Registry.LocalMachine;
myReg = null; break;
default: switch (myRegName) { case "HKEY_CLASSES_ROOT":
myReg = Registry.ClassesRoot;
break; case "HKEY_CURRENT_USER":
myReg = Registry.CurrentUser;
break; case "HKEY_LOCAL_MACHINE":
myReg = Registry.LocalMachine;
break; case "HKEY_USERS":
myReg = Registry.Users;
break; case "HKEY_CURRENT_CONFIG":
myReg = Registry.CurrentConfig;
break; }
break; }
//給根目錄使用 //===========================================
//若有包含\\字串表示有子目錄 if (myPath.IndexOf("\\") >= 1)
{ string[] KeyName = myPath.Split(new Char[] { '\\' }); string myParent = node.Parent.Text;
//取的目錄名稱2層
if (KeyName.Length == 2)//例如:我的電腦\\HKEY_USERS
{ return myReg;
}
//取的目錄名稱3層以上
if (KeyName.Length >= 3)//例如:我的電腦\\HKEY_USERS\\.DEFAULT
{ string OldQuery = null;
//過濾"我的電腦"字串 foreach (string item in KeyName)
{ if (item != "我的電腦") { if (OldQuery == null)
{ OldQuery += item;
}
else
{ OldQuery += "\\" + item; }
}
}
string[] NewQuery = OldQuery.Split(new Char[] { '\\' });//字串分割 //取得主機碼例如:HKEY_USERS
switch (NewQuery[0])
{ case "HKEY_CLASSES_ROOT": myReg = Registry.ClassesRoot;
break;
case "HKEY_CURRENT_USER": myReg = Registry.CurrentUser;
break;
case "HKEY_LOCAL_MACHINE": myReg = Registry.LocalMachine;
break;
case "HKEY_USERS": myReg = Registry.Users;
break;
case "HKEY_CURRENT_CONFIG": myReg = Registry.CurrentConfig;
break;
}
string query = null;
//重新排列根目錄
foreach (string item in NewQuery)
{ if (item != NewQuery[0])
{ if (query == null)
{ query += item;
}
else
{ query += "\\" + item;
}
}
}
myReg = myReg.OpenSubKey(query, true); }
}
//回傳 return myReg; }
1.設定中斷點
2.觀察列舉的結果
3.比對OS的登錄檔程式
我的HKEY_CLASSES_ROOT裡有9745筆的資料
Step7.在treeView1的AfterSele事件加入以下程式碼。
//選取樹狀節點之後。(開啟資料夾) private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{ //清空 this.listView1.Items.Clear(); //依節點名稱取得 RegistryKey RegistryKey myReg = GetRegKey(this.treeView1.SelectedNode); //取得包含所有與這個機碼相關值名稱的字串陣列。 if (myReg != null)
{ string[] AllValueName = myReg.GetValueNames(); string RegName; RegistryValueKind GetType;
object RegData; string RegType; //若陣列有資料 if (AllValueName.Length != 0) { foreach (var item in AllValueName)
{ //取得名稱 RegName = item.ToString();
//取得資料 RegData = myReg.GetValue(RegName);
//取得類型 GetType = myReg.GetValueKind(item);
//Console.WriteLine( myReg.GetValueKind(item.ToString()));
ListViewItem mySubItem = null; Console.WriteLine("Name: " + RegName + "\t" + "Type: " + GetType.ToString() + "\t" + "Data: " + RegData.ToString());
//判斷資料型態 switch (GetType) { case RegistryValueKind.String: RegType = "REG_SZ"; //建立ListView子項目"名稱、類型、資料" mySubItem = new ListViewItem(new String[] { RegName, RegType.ToString(), RegData.ToString() }, 3);
break; case RegistryValueKind.Binary: RegType = "REG_BINARY"; //建立ListView子項目"名稱、類型、資料" mySubItem = new ListViewItem(new String[] { RegName, RegType.ToString(), RegData.ToString() }, 4);
break; case RegistryValueKind.DWord: RegType = "REG_DWORD"; //建立ListView子項目"名稱、類型、資料" mySubItem = new ListViewItem(new String[] { RegName, RegType.ToString(), RegData.ToString() }, 4);
break; case RegistryValueKind.MultiString: RegType = "REG_MULTI_SZ"; //建立ListView子項目"名稱、類型、資料" mySubItem = new ListViewItem(new String[] { RegName, RegType.ToString(), RegData.ToString() }, 3);
break; case RegistryValueKind.ExpandString: RegType = "REG_EXPAND_SZ"; //建立ListView子項目"名稱、類型、資料" mySubItem = new ListViewItem(new String[] { RegName, RegType.ToString(), RegData.ToString() }, 3);
break; }
this.listView1.Items.Add(mySubItem); }
}
}
}
點選資料夾後會將資料夾的內容秀出
實作結果
4.範例下載:
若有謬誤,煩請告知,新手發帖請多包涵

Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

