.NET Compact Framework下的注冊表開發(fā)
簡介
本文講述了CF.net下的注冊表開發(fā)的基本概念,介紹在Windows Mobile和Wince下操作注冊表的工具,同時使用C#實現(xiàn)了一個注冊表導(dǎo)出工具。
背景
Wince和Windows桌面系統(tǒng)一樣都是把系統(tǒng)信息,驅(qū)動信息,應(yīng)用程序信息等重要存放在注冊表里面。最近需要實現(xiàn)3G設(shè)備的自動注冊,3G鏈接項的自動創(chuàng)建功能。在實現(xiàn)該功能的過程中發(fā)現(xiàn)設(shè)備注冊信息和鏈接項信息均保存在注冊表里面,所以需要實現(xiàn)導(dǎo)出注冊表功能,把注冊前后的注冊表信息進行比較。
什么是注冊表
注冊表(Registry)其實就是一個層次型的文件數(shù)據(jù)庫,用于保存操作系統(tǒng)信息,驅(qū)動信息,應(yīng)用程序信息,用戶信息等等。在注冊表內(nèi)有兩個關(guān)鍵項,Key和Value,這里我保留英文,因為翻譯成中文是鍵(key)和值(Value)比較容易混淆。所謂Key就是可以包含SubKey和Value的項??梢岳斫鉃橐粋€容器節(jié)點,SubKey和Key在本質(zhì)上是一樣,SubKey可以繼續(xù)包含SubKey和Value。Value就是包含數(shù)據(jù)類型,數(shù)據(jù)值的項,也可以理解為葉子節(jié)點,Value不能包含其他SubKey和Value。
注冊表開發(fā)方案
查看和修改注冊表,推薦使用以下兩個工具:
Windows CE Remote Registry Editor,可以在VS 2005和VS 2008的菜單下找到??梢赃h程查看和修改注冊表,非常方便??墒窃摴ぞ卟恢С謱?dǎo)入導(dǎo)出功能。
PHM Registry Editor
該工具可以安裝在設(shè)備上,在設(shè)備上直接查看和修改注冊表。PHM Registry Editor同時支持導(dǎo)入導(dǎo)出功能,可是導(dǎo)入導(dǎo)出是使用私有格式,和MS的不兼容。
注冊表開發(fā)的現(xiàn)實
由于上述兩個工具的局限性,所以我實現(xiàn)了一個注冊表導(dǎo)出功能,和桌面版的Registry Editor導(dǎo)出功能的文件格式兼容。
操作注冊表類是在CF.net 2.0引入的,CF.net 1.0不支持。使用注冊表功能,需要引用Microsoft.Win32 namespace。
- using Microsoft.Win32;
下面是導(dǎo)出接口,把根下所以key導(dǎo)出到StringBuilder中。
- public StringBuilder Export()
- {
- StringBuilder sb = new StringBuilder();
- Export(sb, Registry.ClassesRoot);
- Export(sb, Registry.CurrentUser);
- Export(sb, Registry.LocalMachine);
- Export(sb, Registry.Users);
- return sb;
- }
在Windows Mobile和Wince系統(tǒng)下注冊表的項比桌面系統(tǒng)少一些,如上圖可見。
下面的代碼是導(dǎo)出具體的一個key。
- public void Export(StringBuilder sb, RegistryKey key)
- {
- //log down itself.
- sb.AppendFormat(CultureInfo.CurrentCulture, "\r\n[{0}]\r\n", key.Name);
- //log down values
- string[] s = key.GetValueNames();
- Array.Sort(s);
- //log down "Default" first
- try
- {
- key.GetValue(Default);
- ExportValue(sb, key, Default);
- }
- catch
- {
- }
- foreach(string name in s)
- {
- if (!name.Equals(Default))
- {
- ExportValue(sb, key, name);
- }
- }
- //log down subkeys
- s = key.GetSubKeyNames();
- Array.Sort(s);
- foreach(string subKeyName in s)
- {
- Export(sb, key.OpenSubKey(subKeyName));
- }
- }
導(dǎo)出Key是先導(dǎo)出自身,然后導(dǎo)出Value,導(dǎo)出Value時如果有Default Value的話先導(dǎo)出Default Value,然后導(dǎo)出其他Value。導(dǎo)出Value后再遞歸導(dǎo)出SubKeys。
下面代碼是導(dǎo)出Value。
- private void ExportValue(StringBuilder sb, RegistryKey key, string name)
- {
- switch (key.GetValueKind(name))
- {
- case RegistryValueKind.DWord:
- int dword = (int)key.GetValue(name);
- if (name.Equals(Default))
- {
- sb.AppendFormat(CultureInfo.CurrentCulture, "@=dword:{0:X8}\r\n", dword);
- }
- else
- {
- sb.AppendFormat(CultureInfo.CurrentCulture, "\"{0}\"=dword:{1:X8}\r\n", name, dword);
- }
- break;
- case RegistryValueKind.String:
- if (name.Equals(Default))
- {
- sb.AppendFormat(CultureInfo.CurrentCulture, "@=\"{0}\"\r\n", key.GetValue(name));
- }
- else
- {
- sb.AppendFormat(CultureInfo.CurrentCulture, "\"{0}\"=\"{1}\"\r\n", name, key.GetValue(name));
- }
- break;
- case RegistryValueKind.MultiString:
- string[] values = (string[])key.GetValue(name);
- if (name.Equals(Default))
- {
- sb.Append("@=multi_sz:");
- }
- else
- {
- sb.AppendFormat(CultureInfo.CurrentCulture, "\"{0}\"=multi_sz:", name);
- }
- for (int i = 0; i < values.Length; i++)
- {
- if (i != 0)
- {
- sb.Append(",");
- }
- sb.AppendFormat(CultureInfo.CurrentCulture, "\"{0}\"", values[i]);
- }
- sb.Append("\r\n");
- break;
- case RegistryValueKind.Binary:
- byte[] bytes = (byte[])key.GetValue(name);
- if (name.Equals(Default))
- {
- sb.Append("@=hex:");
- }
- else
- {
- sb.AppendFormat(CultureInfo.CurrentCulture, "\"{0}\"=hex:", name);
- }
- int j = 0;
- for (int i = 0; i < bytes.Length; i++)
- {
- // Display each byte as two hexadecimal digits.
- if (i == (bytes.Length - 1))
- {
- sb.AppendFormat(CultureInfo.CurrentCulture, "{0:X2}", bytes[i]);
- }
- else
- {
- sb.AppendFormat(CultureInfo.CurrentCulture, "{0:X2},", bytes[i]);
- }
- ++j;
- if (j == 25)
- {
- j = 0;
- sb.Append("\\\r\n");
- }
- }
- sb.Append("\r\n");
- break;
- }
- }
由于Value有不同的數(shù)據(jù)類型,導(dǎo)出的時候根據(jù)數(shù)據(jù)類型來導(dǎo)出不同的格式。key.GetValueKind()函數(shù)可以取出Key數(shù)據(jù)類型RegistryValueKind。
下面是運行效果。
環(huán)境:Visual Studio 2008 + Windows Mobile 6 professional SDK + .NET Compact Framework 2.0
【編輯推薦】