快速注册表导航






4.66/5 (12投票s)
2005 年 12 月 29 日
2分钟阅读

84318

379
一个工具,可以快速导航到使用 Regedit 的特定键/值。
引言
你多少次在 CP 或互联网上的其他地方看到一篇包含长注册表键引用的文章,并想如果可以直接跳转到该键而无需在 regedit 中输入它该有多好?我想我找到了一个解决方案。
查找和打开 Regedit
要查找 Regedit 的窗口,我们搜索和/或创建“RegEdit_RegEdit
”窗口类。
CWnd *pWndRegeditMain = CWnd::FindWindow(_T("RegEdit_RegEdit"), NULL); if (NULL == pWndRegeditMain) { rShellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO); rShellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS; rShellExecuteInfo.lpVerb = _T("open"); rShellExecuteInfo.lpFile = _T("regedit.exe"); rShellExecuteInfo.nShow = SW_SHOWNORMAL; ShellExecuteEx(&rShellExecuteInfo); WaitForInputIdle(rShellExecuteInfo.hProcess, INFINITE); pWndRegeditMain = CWnd::FindWindow(_T("RegEdit_RegEdit"), NULL); }
此时,pWndRegeditMain
应该具有非 NULL
值。接下来,我们需要显示 Regedit 的窗口并将其置于前景。
pWndRegeditMain->ShowWindow(SW_SHOW); pWndRegeditMain->SetForegroundWindow();
TreeView
由于 Regedit 维护上次访问的键(参见 补充说明),我们必须确保一个已知的起始点:根节点。为此,我们只需“发送”左箭头键几十次即可。
CWnd WndRegeditTreeview; WndRegeditTreeview.Attach(FindWindowEx(pWndRegeditMain->GetSafeHwnd(), NULL, _T("SysTreeView32"), NULL)); WndRegeditTreeview.SetForegroundWindow(); WndRegeditTreeview.SetFocus(); // close it up so we have a known starting point for (int nDepth = 0; nDepth < 30; nDepth++) WndRegeditTreeview.SendMessage(WM_KEYDOWN, VK_LEFT, 0);
现在我们位于根节点,可以开始向下导航到所需的键。对于这段代码而言,键可以以两种方式形成
key\
key\value
为了区分两者,我们使用
CString strRegistryPath(argv[1]); // the path must begin with a backslash if (strRegistryPath.Left(1) != _T('\\')) strRegistryPath = _T('\\') + strRegistryPath; int nIndex = strRegistryPath.ReverseFind(_T('\\')); CString strValue = strRegistryPath.Mid(nIndex + 1); strRegistryPath = strRegistryPath.Left(nIndex);
请注意,当遇到反斜杠字符时,我们会“发送”右箭头键。
for (nIndex = 0; nIndex < strRegistryPath.GetLength(); nIndex++) { UINT uVirtualKey = strRegistryPath[nIndex]; if (_T('\\') == uVirtualKey) WndRegeditTreeview.SendMessage(WM_KEYDOWN, VK_RIGHT, 0); else { uVirtualKey = toupper(uVirtualKey); WndRegeditTreeview.SendMessage(WM_CHAR, uVirtualKey, 0); } }
此时,我们应该位于左窗格中的所需键。
ListView
现在,如果也指定了一个值,我们必须切换到列表视图并选择它。
CWnd WndRegeditListview; WndRegeditListview.Attach(FindWindowEx(pWndRegeditMain->GetSafeHwnd(), NULL, _T("SysListView32"), NULL)); WndRegeditListview.SetForegroundWindow(); WndRegeditListview.SetFocus(); // have to wait for Regedit to update the listview Sleep(1000); // select the value WndRegeditListview.SendMessage(WM_KEYDOWN, VK_HOME, 0); for (nIndex = 0; nIndex < strValue.GetLength(); nIndex++) { UINT uVirtualKey = toupper(strValue[nIndex]); WndRegeditListview.SendMessage(WM_CHAR, uVirtualKey, 0); }
我们的值现在应该被选中。我们可以分离临时视图对象并退出程序。
用法
从命令行提示符,只需键入 regeditgo,后跟所需的键\值。如果键和/或值包含任何空格,则需要用双引号将其括起来。
一旦 Regedit 完成向下导航到所需的键,你应该会看到类似于以下内容

附加功能
我喜欢的一个功能是 Regedit 自动选择上次访问的键。该键的名称存储在以下值中
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\LastKey
你可以通过删除对 Regedit
键的写入权限来阻止 Regedit 维护上次访问的键。但是,有一个权衡。通过这样做,你也会禁止 Regedit 更新 FindFlags
和 View
值。