Introduction
How many times have you seen a post here at CP, or any place out on the Internet for that matter, that contained a reference to a long registry key, and thought how useful it would be if you could go straight to that key without having to type it into regedit? I think I have a solution.
Finding and Opening Regedit
To find Regedit's window, we search for and/or create the "RegEdit_RegEdit
" window class.
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);
}
At this point, pWndRegeditMain
should have a non-NULL
value. Next, we need to show Regedit's window and bring it to the foreground.
pWndRegeditMain->ShowWindow(SW_SHOW);
pWndRegeditMain->SetForegroundWindow();
The TreeView
Since Regedit maintains the last-accessed key (see Extras), we must ensure a known starting point: the root node. To do this, we simply "send" the left arrow key several dozen times.
CWnd WndRegeditTreeview;
WndRegeditTreeview.Attach(FindWindowEx(pWndRegeditMain->GetSafeHwnd(),
NULL, _T("SysTreeView32"), NULL));
WndRegeditTreeview.SetForegroundWindow();
WndRegeditTreeview.SetFocus();
for (int nDepth = 0; nDepth < 30; nDepth++)
WndRegeditTreeview.SendMessage(WM_KEYDOWN, VK_LEFT, 0);
Now that we are at the root node, we can start our descent down to the desired key. The key, as far as this code is concerned, can be formed in one of two ways:
key\
key\value
To separate the two, we use:
CString strRegistryPath(argv[1]);
if (strRegistryPath.Left(1) != _T('\\'))
strRegistryPath = _T('\\') + strRegistryPath;
int nIndex = strRegistryPath.ReverseFind(_T('\\'));
CString strValue = strRegistryPath.Mid(nIndex + 1);
strRegistryPath = strRegistryPath.Left(nIndex);
Note that when a backslash character is encountered, we "send" a right arrow key instead.
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);
}
}
At this point, we should be at the desired key in the left pane.
The ListView
Now if a value was also specified, we must switch over to the list view and select it.
CWnd WndRegeditListview;
WndRegeditListview.Attach(FindWindowEx(pWndRegeditMain->GetSafeHwnd(),
NULL, _T("SysListView32"), NULL));
WndRegeditListview.SetForegroundWindow();
WndRegeditListview.SetFocus();
Sleep(1000);
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);
}
Our value should now be selected. We can detach the temporary view objects and exit the program.
Usage
From a command prompt, simply type regeditgo followed by the desired key\value. If the key and/or value contains any spaces, you'll need to surround it with double quotes.
Once Regedit has finished navigating down to the desired key, you should have something that resembles the following:
A feature that I happen to like is Regedit's automatic selection of the last-accessed key. The name of this key is stored in the following value:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\LastKey
You can keep Regedit from maintaining the last-accessed key by removing write permission to the Regedit
key. However, there is a tradeoff. By doing so, you'll also be prohibiting Regedit from updating the FindFlags
and View
values.