65.9K
CodeProject 正在变化。 阅读更多。
Home

NtRegEdit - 本机注册表编辑器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (42投票s)

2006年9月5日

CPOL

8分钟阅读

viewsIcon

328647

downloadIcon

15301

Microsoft注册表编辑器的替代品。

Sample NtRegEdit Image

引言

绝非完成或100%。我说这话的意思是,它可能无法达到我想要的100%功能。这是因为我很难找到时间来完成它。如果有人想帮助我完成100%,请告诉我!

我想创建一个注册表编辑器,它使用“原生注册表API”,而不是使用AdvApi32.dll中的Microsoft注册表API(它只是原生注册表API的包装器)。由于其中包含所有其他API,因此仍然依赖于AdvApi32.dll。我基本上写了一个类来完成这个任务(我想它也是一个包装器 - 见下图)。我想创建一个具有与Microsoft注册表编辑器相同功能但能做更多事情的程序。我喜欢使用SDI框架,所以决定从它开始。我还想让注册表数据的读取更容易一些,所以我决定使用颜色编码。这样用户就可以根据自己的喜好对信息进行颜色编码,使其更易于阅读,用户友好性更高。

所有注册表的查看/修改均严格通过我编写的CNtRegistry类完成,该类可以在CodeProject上找到。市面上有很多注册表编辑器,包括免费和共享软件,但它们不使用原生注册表API来执行查看/修改。我的目标是创建一个注册表编辑器,能够“完全”做到Microsoft的RegEdit能做的,而且更多

Sample NtRegistryAPI Image

使用软件

它的功能方面,你已经知道很多了(因为你知道如何使用Microsoft的RegEdit),这些功能都通过界面提供。我试图将所有真正复杂的东西隐藏在类中,以便突出其简洁性。这种简洁性是在Robert Pittenger找到的CRegistry类中实现的,该类位于CodeProject此处,并且是该类的整体结构来源。谢谢Robert!

使用代码 (CNtRegistry)

现在,CNtRegistry类在我另一篇文章此处中有解释,所以我建议你去那里获取完整的故事,但我将只列出其中的几个函数。

BOOL SetRootKey(HKEY hKey);
BOOL SetKey(HKEY hRoot, CString csKey, BOOL bCanCreate, BOOL bCanSaveCurrentKey);
BOOL SetKey(CString csKey, BOOL bCanCreate, BOOL bCanSaveCurrentKey);
BOOL CreateKey(CString csKey);
BOOL CreateHiddenKey(CString csKey);
BOOL RenameKey(CString csFullKey, CString csNewKeyName);
BOOL DeleteKey(CString csKey);
BOOL DeleteKeysRecursive(CString csKey);
BOOL FindHiddenKeys(CString csKey, BOOL bRecursive, CStringArray& csaResults);
BOOL Search(CString csString, CString csStartKey, CStringArray& csaResults, 
            int nRegSearchType = 3, BOOL bCaseSensitive = TRUE);
BOOL CopyKeys(CString csSource, CString csTarget);

正如你所见,上面的函数非常简单且用户友好。还有很多内容,你应该去看看那篇文章以获取更详细的信息。

一些视觉功能

你可以导入/导出原生注册表(.neg)和/或Microsoft注册表(.reg)文件,前提是它们是Win2000或更高版本(基本上,如果注册表文件的第一行是“Windows Registry Editor Version 5.00”)。下面的图片展示了导出的文件示例(注意,图片中显示的Key是上面的Key)。如果你查看“.neg”文件,它在Key“[HKCU\AppTest\HiddenKey2*]”后面有一个星号(*)。这是为了让你能够导入/导出隐藏的Key。

NtRegEdit Imp/Exp2 Image

NtRegEdit Imp/Exp1 Image

当你尝试导出Key时,如果它下面有Key,你将看到下面的弹出窗口(感谢“Defenestration”的建议)。

NtRegEdit Imp/Exp3 Image

这是当前RegEdit格式与NtRegEdit格式的映射

NtRegEdit
RegEdit
注册表类型
@= @= (默认)
=str ="" REG_SZ
=exp =hex(2) REG_EXPAND_SZ
=bin =hex REG_BINARY
=dw =dword REG_DWORD
=dwbe =dword REG_DWORD_BIG_ENDIAN
=link =hex(6) REG_LINK
=multi =hex(7) REG_MULTI_SZ
=reslist =hex(8) REG_RESOURCE_LIST
=fullres =hex(9) REG_FULL_RESOURCE_DESCRIPTOR
=reqlist =hex(10) REG_RESOURCE_REQUIREMENTS_LIST
=qword =hex(b) REG_QWORD

创建/修改Key将弹出下图所示的对话框。它执行许多功能/能力,例如

  • 创建普通/隐藏Key
  • 复制普通/隐藏Key
  • 查找隐藏Key
  • 重命名普通/隐藏Key
  • 在Key/值/数据中搜索

NtRegEdit CRDFS1 Image

点击“浏览”按钮允许用户选择要执行特定任务的Key(见下图)。

NtRegEdit Keys Dialog Image

现在,我还添加了一个应用程序设置对话框,允许你设置一些影响GUI的常规/ListCtrl/TreeCtrl设置。这些对话框中还有很多内容(甚至可以添加更多对话框),但目前就这些。你可以在下面看到这些对话框。

  • 常规选项卡
    • 保存窗口位置
    • 保持窗口置顶
    • 启动时检查操作系统类型
    • 启动时检查用户是否为管理员
    • 等等...
  • 列表控件选项卡
    • 为每种注册表类型选择一种颜色(通过单击项目)
  • 树状控件选项卡
    • 对注册表根Key使用粗体
    • 对隐藏Key使用粗体
    • 为每种注册表根Key(及其子Key)选择一种颜色(通过单击项目)

NtRegEdit CRDFS Image

NtRegEdit CRDFS Image

NtRegEdit CRDFS Image

内部代码 (显示Key)

用于获取注册表信息来构建树视图的代码也非常简单,它只显示当前Key,并使用GetSubKeyCount()函数来确定Key是否有子Key。如果有,它会添加一个“假项目”,目的是显示Key拥有子Key。每次你在树中向下钻取(通过展开树项目)时,它都会读取下一级Key的注册表(见下图)。这使得TreeView在启动时加载速度更快。

// Set the key so we can go through the subkeys

if (m_ntReg.SetKey(csFullKey,FALSE,TRUE)) {
    // Holds the subkeys of the current key

    CStringArray csaKeys;

    if (hItem == NULL) {
        hItem = m_hRoot;
    }

    BOOL bOk = FALSE;
    m_ntReg.GetSubKeyList(csaKeys);
    for (int n=0; n<csaKeys.GetSize(); n++) {
        //

        CString csKey(csFullKey);
        csKey += _T("\\");
        csKey += csaKeys.GetAt(n);

        bOk = m_ntReg.SetKey(csKey,FALSE,TRUE);

        int nIcon = 5;
        if (m_ntReg.m_bHidden) { nIcon = 0; }

        HTREEITEM hNewItem = 
          tc.InsertItem(csaKeys.GetAt(n),nIcon,nIcon,hItem);
        SetItemColor(hNewItem,crTextColor);
        if (m_ntReg.m_bHidden && theApp.m_clsMainFrm->m_bBoldHidden) {
            SetItemBold(hNewItem,TRUE); 
        }

        if (bOk && m_ntReg.GetSubKeyCount() > 0) {
            tc.InsertItem(FAKEDITEM,5,5,hNewItem,TVI_LAST);
        }
        tc.SortChildren(hNewItem);
    }
}

现在我们可以看到子Key了,当用户单击一个树项目时,它会查询Key的值,并在列表视图中显示它们。列表控件的颜色设置方式取决于用户如何查看信息。

还可以查看给定Key的权限(只要你有权限执行此操作)。

NtRegEdit Permissions Image

列表视图下方还有一些选项卡。这些用于创建/修改注册表数据。由于注册表中只有三种数据格式(二进制、DWORDs和字符串(3)),这相当容易。在列表视图中单击任何注册表类型,它将激活该选项卡并填充数据。在那里,你可以创建一个新值,或者仅仅修改数据。如果你在“创建名称”编辑控件中输入任何内容,它将假定你想要“创建”一个新值。如果你修改了数据,它将假定你想要“更新”数据。

NtRegEdit Binary Tab Image

NtRegEdit DWord Tab Image

NtRegEdit Multi-String Tab Image

NtRegEdit String-Expand Tab Image

还有一个选项卡用于查看“搜索和查找隐藏Key”的结果(感谢“Tcpip2005”的建议)。如果你从菜单或工具栏中选择搜索(及其他命令),你将看到一个带有某些控件的对话框。

NtRegEdit Search/Find Tab Image

这还不是全部,你还可以“双击”搜索/查找视图,然后你将被带到Key、值名称和/或值。例如,如果你搜索一个名为“string”的字符串,它将在第1列显示结果。如果单词在值名称中找到,它将被放入第2列。如果单词在值中找到,它将被放入第3列。双击它时,应用程序将显示Key(可视化)。如果第2列中有值名称,它将被高亮显示。如果第3列中有值,它也会被高亮显示(基本上,它会显示它的位置)。即使是“隐藏Key”也同样适用。

结语...

这就是我目前为止所做的。我不指望它能完美,所以请给我你的想法来改进它。生活中和伴随而来的所有挑战,记住一件事……如果你犯了“错误”并从中学习,那么它一开始就不是错误……它是一次“教训”!

感谢...

NtRegEdit 使用了一些非常有用类/控件,这些类/控件可以在CodeProject上找到

待办事项

  • 使其拥有所有“RegEdit”功能
  • 添加RegEdit没有的更多原生功能
  • 使其真正用户友好!!

历史

  • 2006年9月6日
    • 修复GUI - Tree/List视图未正确初始化
  • 2006年8月23日 (0.0.2.857)
    • 添加了安全权限对话框
  • 2006年8月10日 (0.0.2.734)
    • 向“关于”对话框添加了名称(源码所有者)
    • 向TreeCtrl添加了粗体选项
    • 添加了应用程序设置对话框
      • COptGenDlg() - 常规
      • COptListDlg() - 列表控件
      • COptTreeDlg() - 树状控件
    • CNtRegEditTreeView类添加了颜色(XListCtrl已包含)
    • CTreeCtrl添加了标签编辑
    • 添加了“NtRegEdit”格式的开头
    • 添加了虚拟键
      • VK_UP (向上到下一个“可见”项目(显示值))
      • VK_DOWN (向下到下一个“可见”项目(显示值))
      • VK_DELETE (如果存在子Key,将提示用户进行递归)
      • VK_ENTER (如果存在,则打开子Key,否则无效果)
    • 修复了OnKeysRefresh()函数(我认为)
  • 2006年7月16日 (0.0.1.689)
    • 在状态栏中添加了Key路径(感谢...)
  • 2006年7月10日
    • 首次公开发布
  • 2006年7月3日 (0.0.0.1)
    • 初始创建
© . All rights reserved.