有人写过像REGJUMP那样的delphi代码吗?

有人写过像REGJUMP那样的delphi代码吗?,delphi,path,regedit,Delphi,Path,Regedit,有人写过一些delphi代码来做什么吗 具体而言,REGJUMP是一款MS应用程序,允许您打开regedit到指定的值/键路径(准备在regedit中查看或编辑)。例如:regjump HKLM\Software\Microsoft\Windows将在路径HKLM\Software\Microsoft\Windows处打开regedit 我试过: ShellExecute(handle,'Open','C:\WINDOWS\regedit.exe', nil, nil, SW_SHOW); S

有人写过一些delphi代码来做什么吗

具体而言,REGJUMP是一款MS应用程序,允许您打开regedit到指定的值/键路径(准备在regedit中查看或编辑)。例如: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打开到您查看的最后一个路径

我试过:

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.
程序测试;
{$APPTYPE控制台}
使用
SysUtils,注册表;
变量
注册:树木学;
LastKey,
KeyToFind,
ValueToWrite:字符串;
开始
ValueToWrite:=ParamStr(1);
KeyToFind:=“SOFTWARE\Microsoft\Windows\CurrentVersion\Applets\Regedit”;
Reg:=TRegistry.Create;
如果存在注册表项(KeyToFind),则
writeln('found',KeyToFind)
其他的
writeln('notfound',KeyToFind);
如果注册OpenKey(KeyToFind,False),则
writeln(KeyToFind,‘打开正常’)
否则开始
writeln('未能打开键:',KeyToFind);
暂停(1);
结束;
LastKey:=Reg.ReadString('LastKey');

writeln('Last key:>',LastKey,“这是您想要的代码。我很久以前就使用过它,它放在我的助手单元中。不记得我是从其他地方写的还是重用过它

它所做的是搜索Regedit的窗口,在未运行时启动它,并通过发送消息来模拟按键以导航所需的键来自动执行它。这不是传递命令行参数的本机解决方案,但工作得非常好

// 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;
//打开注册表编辑器并转到指定的项
程序JumpToRegKey(常数:字符串);
变量
一、 J:整数;
hWin:HWND;
ExecInfo:TShellExecuteInfo;
开始
//检查regedit是否正在运行,如果没有,则启动它
//下面的所有代码都取决于特定的窗口标题和类,因此如果MS更改Regedit应用程序,它将失败
hWin:=FindWindow(PChar('RegEdit_RegEdit'),nil);
如果hWin=0,则
开始
零内存(@ExecInfo,sizeof(ExecInfo));
用ExecInfo做什么
开始
cbSize:=SizeOf(TShellExecuteInfo);
fMask:=见屏蔽过程;
Wnd:=Application.Handle;
lpVerb:=PChar('open');
lpFile:=PChar('regedit.exe');
nShow:=SW_最大化;
结束;
ShellExecuteEx(@ExecInfo);
WaitForInputIdle(ExecInfo.hProcess,200);
hWin:=FindWindow(PChar('RegEdit_RegEdit'),nil);
结束;
如果hWin为0,则
开始
显示窗口(hWin、SW_显示最大化);
hWin:=FindWindowEx(hWin,0,PChar('SysTreeView32'),nil);
setforegroundindow(hWin);
//通过发送大量左箭头键,首先折叠树
I:=30;
重复
SendMessage(hWin,WM_键下,VK_左,0);
十二月一日;
直到I=0;
睡眠(100);
SendMessage(hWin,WM_键下,VK_右,0);
睡眠(100);
I:=1;
J:=长度(aKey);
重复
如果aKey[I]='\'那么
开始
SendMessage(hWin,WM_键下,VK_右,0);
睡眠(50);
结束
其他的
SendMessage(hWin,WM_CHAR,整数(aKey[I]),0);
I:=I+1;
直到I=J;
结束;
结束;
正如kobik提醒的那样,此代码的使用有一个限制。非提升的应用程序无法向提升的应用程序发送消息。Regedit是提升的,因此,如果您的应用程序具有提升的权限,或者UAC已关闭,则可以使用此代码。

否则,它将启动流程(这将要求批准)并找到它的窗口,但PostMessage将不起作用。

似乎没有命令行选项来执行此操作。在我看来,这个sysinternals工具似乎可以自动执行UI。毫无疑问,您也可以这样做。但这个问题已脱离主题,因为它是一个推荐问题。来自Windows sysinternals工具的疑难解答:Window消息可用于模拟鼠标或键盘活动。进程监视器和自动运行中的RegJump和跳转功能正是这样做的,以导航到Regedit中的某个键。现在这是开箱思考!这也适用于Win7。但只有在Regedit当前未运行的情况下,这才是第一次,因为Regedit只运行一个实例。可能需要ds必须先接近+1@kobik:感谢您对Win7的确认。是的,我想向OP提及,如果Regedit已经运行,则不希望此功能一定有效。此功能非常有效(假设Regedit尚未运行)-谢谢。对于那些搜索代码的人来说,它基本上意味着按如下方式编写到LastKey的所需路径:如果不是Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Applets\RegEdit',True),则是raiselastError;Reg.WriteString('LastKey','Computer\HKEY\U CURRENT\u USER\Software\MyCompany\MyApp\Settings'));您无法向提升的进程(如RegEdit)发送消息。您在Win7上测试过吗?是的,这是一个限制。要使代码正常工作,必须提升调用者,或者必须关闭UAC。如果从非提升的应用程序调用,它将不起作用。我将在答案中添加注释,谢谢。