[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