2017-01-13 13 views
3

Кто-нибудь когда-либо писал какой-то код delphi, который делает то, что делает REGJUMP?Кто-нибудь когда-либо писал какой-то код delphi, который делает то, что делает REGJUMP?

В частности, REGJUMP - это приложение MS, которое позволяет вам открыть regedit для указанного пути значений/ключей (готовых для просмотра или редактирования в regedit). Например: regjump HKLM \ Software \ Microsoft \ Windows откроет regedit на пути HKLM \ Software \ Microsoft \ Windows.

Я пробовал:

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

Что, конечно, только открывает Regedit к последнему пути, который вы смотрели.

Я пробовал:

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

но попытки импортировать значения пути - и по разным причинам, с треском проваливается - и не то, что я хочу сделать в любом случае.

+0

Не похоже, что для этого есть параметры командной строки. Мне кажется, что этот инструмент sysinternals автоматизирует пользовательский интерфейс. Вы могли бы сделать то же самое без сомнения. Но вопрос не в тему, потому что это вопрос рекомендации. –

+1

От устранения неполадок с помощью средств Windows Sysinternals: * Текстовые сообщения могут использоваться для имитации активности мыши или клавиатуры. Режимы RegJump и Jump To в Process Monitor и Autoruns делают именно это, чтобы перейти к клавише в Regedit. * –

ответ

10

Я думаю, что вы найдете последний раздел реестра посещаемый в Regedit сохраняется в реестре стоимости LastKey под

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

в Windows 10, по крайней мере.

Итак, я бы попытался написать значение, которое я хочу посетить, прежде чем вызывать 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. 
+0

Это аккуратный трюк ! –

+0

Теперь это за пределами штрафной! – MikeD

+1

Это работает и на Win7. но только в первый раз, если REGEDIT в настоящее время не запущен, поскольку REGEDIT запускает один экземпляр. возможно, сначала он должен быть закрыт. +1 – kobik

0

Вот код, который делает то, что вы хотели. Я использовал его давным-давно, и он сидит в моих вспомогательных подразделениях. Не могу вспомнить, писал ли я его или повторно использовал его из другого места.

Что он делает, чтобы искать окно 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; 

Существует ограничение на использование этого кода, как напомнил kobik. Неподнятое приложение не может отправлять сообщения на повышенную. Regedit повышен, поэтому код можно использовать, если ваше приложение имеет повышенные привилегии или если UAC выключен.
В противном случае он запустит процесс (который будет запрашивать одобрение) и найдет его окно, но PostMessage не будет работать.

+1

Вы не можете отправлять сообщения на повышенный процесс, такой как RegEdit. вы тестировали это на Win7? – kobik

+0

Yup, это ограничение. Для того, чтобы код работал, вызывающий абонент должен быть повышен, или UAC должен быть отключен. Он не должен работать, если вызван из не-приподнятого приложения. Я добавлю примечание к ответу, спасибо. – VGeorgiev