有没有人写过一些 delphi 代码来完成 REGJUMP 的功能?

Has anyone ever written some delphi code that does what REGJUMP does?

有没有人写过一些 delphi 代码来完成 REGJUMP 的功能?

具体来说,REGJUMP 是一款 MS 应用程序,可让您将注册表编辑器打开到 values/keys 的指定路径(准备好在注册表编辑器中查看或编辑)。例如:regjump HKLM\Software\Microsoft\Windows 将在路径 HKLM\Software\Microsoft\Windows.

处打开 regedit

我试过了:

ShellExecute(handle,'Open','C:\WINDOWS\regedit.exe', nil, nil, SW_SHOW);

这当然只会将注册表编辑器打开到您查看的最后一个路径。

我试过了:

ShellExecute(handle,'Open','C:\WINDOWS\regedit.exe', '[HKLM\Software\Microsoft\Windows]', nil, SW_SHOW);

但是尝试将值导入路径 - 由于各种原因惨遭失败 - 无论如何都不是我想要做的。

我想您会发现在 Regedit 中访问的最后一个注册表项保存在注册表中 LastKey 值下

HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\RegEdit

至少 Windows10。

所以,我会尝试在调用 ShellExecute 或其他任何东西之前将我想要访问的值写入那里。

示例代码:

program RegJumpTest;

{$APPTYPE CONSOLE}

uses
  SysUtils, Registry;
var
  Reg : TRegistry;
  LastKey,
  KeyToFind,
  ValueToWrite : String;
begin
  ValueToWrite := ParamStr(1);
  KeyToFind := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Applets\Regedit';
  Reg := TRegistry.Create;
  if Reg.KeyExists(KeyToFind) then
    writeln('found ', KeyToFind)
  else
    writeln('not found ', KeyToFind);

  if Reg.OpenKey(KeyToFind, False) then
    writeln(KeyToFind, ' opened ok')
  else begin
    writeln('failed to open key: ', KeyToFind);
    Halt(1);
  end;
  LastKey := Reg.ReadString('LastKey');
  writeln('Last key: >', LastKey, '<');

  Reg.WriteString('LastKey', ValueToWrite);
  readln;
end.

这是执行您想要的操作的代码。我很久以前就用过它,它就在我的助手单元里。不记得是我写的还是从别处重用的。

它的作用是搜索 Regedit 的 window,如果不是 运行,则启动它,并通过发送消息来模拟按键以导航所需的键来自动执行它。不是传递命令行参数的本机解决方案,但工作得很好。

// Open Registry editor and go to the specified key
procedure JumpToRegKey(const aKey: string);
var
   I, J: Integer;
   hWin: HWND;
   ExecInfo: TShellExecuteInfo;
begin
   // Check if regedit is running and launch it if not
   // All the code below depends on specific window titles and classes, so it will fail if MS changes the Regedit app
   hWin := FindWindow(PChar('RegEdit_RegEdit'), nil);
   if hWin = 0 then
   begin
     ZeroMemory(@ExecInfo, sizeof(ExecInfo));
     with ExecInfo do
     begin
       cbSize := SizeOf(TShellExecuteInfo);
       fMask  := SEE_MASK_NOCLOSEPROCESS;
       Wnd := Application.Handle;
       lpVerb := PChar('open');
       lpFile := PChar('regedit.exe');
       nShow  := SW_SHOWMAXIMIZED;
     end;
     ShellExecuteEx(@ExecInfo);
     WaitForInputIdle(ExecInfo.hProcess, 200);
     hWin := FindWindow(PChar('RegEdit_RegEdit'), nil);
   end;

   if hWin <> 0 then
   begin
     ShowWindow(hWin, SW_SHOWMAXIMIZED);
     hWin := FindWindowEx(hWin, 0, PChar('SysTreeView32'), nil);
     SetForegroundWindow(hWin);
     // Collapse the tree first by sending a large number of Left arrow keys
     I := 30;
     repeat
       SendMessage(hWin, WM_KEYDOWN, VK_LEFT, 0);
       Dec(I);
     until I = 0;
     Sleep(100);
     SendMessage(hWin, WM_KEYDOWN, VK_RIGHT, 0);
     Sleep(100);
     I := 1;
     J := Length(aKey);
     repeat
       if aKey[I] = '\' then
       begin
         SendMessage(hWin, WM_KEYDOWN, VK_RIGHT, 0);
         Sleep(50);
       end
       else
         SendMessage(hWin, WM_CHAR, Integer(aKey[I]), 0);
       I := I + 1;
     until I = J;
   end;
end;

如kobik提醒的那样,此代码的使用有限制。 non-elevated 应用无法向提升的应用发送消息。 Regedit 已提升,因此如果您的应用程序具有提升的权限,或者 UAC 已关闭,则可以使用代码。
否则它将启动进程(将请求批准)并找到它的 window,但 PostMessage 将不起作用。