В работе Макросы реестра

Тема в разделе "Реестр Microsoft Windows", создана пользователем Dragokas, 3 янв 2014.

  1. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Читал:
    http://safezone.cc/threads/desjat-sovetov-po-tonkoj-nastrojke-windows-xp-s-pomoschju-reestra.7780/

    Заметил в самом конце pushd %L
    Логично предположить, что %L - это видимо текущий каталог (с возможностью вернуться в системный командой popd). Хороший хинт.

    А какие еще макросы бывают?
    Я знаю только %1 - путь с именем целевого объекта, над которым выполняется глагол.
     
    Drongo нравится это.
  2. Kиpилл
    Онлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.217
    Симпатии:
    4.978
    Dragokas, тут нам предстоит совместная работа.

    Раздел Command ,насколько я знаю, работает с COMMAND.COM или чем то подобным,так думаю потому что не все команды CMD воспринимаются в разделе.
    Возможно это было из за разницы в версиях cmd ,тут надо поэкспериментировать-вдруг COMMAND.COM окажется не при делах.


    Тут мы имеем дело с тем,что не до конца известно и в принципе я не нашел документации.

    Скажу что всего 10 макросов цифровых+ как минимум 2 буквенных,это %I %L

    %0 - возвращает имя директории и файла
    % 1 действие передается файлу
    % 2 принтер
    % 3 драйвер (?)
    % 4 порт
    Остальные не знаю.
    Надо подумать.


    Цифры после 1 касаются настроек печати.

    Давай попробуем толкнуться от аргументов cmd?
    Расскажи о них.
     
  3. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    На счет цифр после 1, здесь для меня загадка.
    Не расскажешь ли, где слышал о них. И как симмитировать действие хотя бы одной из них?
    Наверное, более корректно сказать "... от файла".

    Но-но. Ты вспомни еще Windows 3.11 -))) Command.com, это тот же CMD только для Win 9x и находился он в корне %SystemDisk%-a.
    Никакого отношения нет. И ничего общего нет.
    Если ты напишешь %Буква в глаголе рядом с CMD, то после запуска он получит уже готовые обработанные системой макросы реестра,
    имена которых не имеют ничего общего (кроме внешнего вида :) с похожими модификаторами CMD.

    Итак, исследование.
    Я вооружился первой методикой поиска секретов от Сергея Ткаченко, сделав незамысловатый скрипт, который:
    • создает строку со всеми вариантами макросов,
    • создает в реестре глагол Test_Verb с этой строкой;
    • вызывает глагол или предлагает сделать пользователю это самостоятельно;
    • глагол записывает вывод в файл на рабочем столе в одну строку,
    затем после нажатия ОК перекодирует файл во многострочный лог.

    Смотрите 3, 5 строки - настройка true или false
    Код (vb.net):
    ' Automatic Invoke Verb on Script (Имитировать выполнение глагола на самом скрипте автоматически (программно))
    ' In this case %W macros will be omitted (в этом случае исключаю макрос %W, т.к. получим исключение о неопределенном родителе)
    SelfInvoke = false
    ' Удалить глагол после отработки скрипта
    AutoDeleteVerb = false

    RegVerb = "Test_Verb"
    RegKey = "HKCR\AllFilesystemObjects\Shell\" & RegVerb & "\"

    Set oFSO = CreateObject("Scripting.FileSystemObject")
    Set oShell = CreateObject("WScript.Shell")

    LogFile = oShell.SpecialFolders("Desktop") & "\" & RegVerb & "_Result.log"
    if oFSO.FileExists(LogFile) then oFSO.DeleteFile(LogFile)

    ' Make me Admin :) Получаем права Администратора
    if WScript.Arguments.Count = 0 then
        if not isAdminRights() then
            Elevate()
            WScript.Quit
        end if
    end if

    cur = oFSO.GetParentFolderName(WScript.ScriptFullName)
    msgbox "ok"
    ' Generating Verb string (генерирую строку команды для глагола)
    s = "cmd /c for /f ""delims="" %%a in ("""
    for n = 0 to 255
        if (n>=65 and n<=90) or (n>=97 and n<=122) then
            s = s & "/n" & chr(n) & "=%" & chr(n)
        end if
    next
    for n = 0 to 9
            s = s & "/n" & n & "=%" & n
    next
    s = s & """) do echo %%a > """ & LogFile & """"""
    if SelfInvoke then s = replace(s, "%w", "BLOCKED by Script", 1, -1, vbTextCompare)

    ' Writing to the registry (создаю в реестре глагол)
    oShell.RegWrite RegKey, RegVerb
    oShell.RegWrite RegKey & "command\", s

    ' Invoke Test Registry Verb onto this script themself (самовыполнение глагола скриптом себя)
    me_file = WScript.ScriptFullName
    if SelfInvoke then
        CreateObject("Shell.Application").Namespace(left(me_file, 3)).ParseName(mid(me_file, 4)).InvokeVerb(RegVerb)
        WScript.Sleep(2000)
    end if

    if not SelfInvoke then msgbox "Теперь выполните глагол контекстного меню " & RegVerb & " на любом файле или папке."

    ' Clear the registry (удаление глагола контекстного меню)
    if AutoDeleteVerb then
        oShell.RegDelete RegKey & "command\"
        oShell.RegDelete RegKey
    end if

    ' Replace \n -> 0x0D 0x0A (заменяю в однострочном выводе псевдопереносы на перевод каретки)
    with oFSO.OpenTextFile(LogFile,1) '1 - for Reading only
        s = .ReadAll()
        .Close
    end with

    s = Replace (s, "/n", vbCrLf)

    with oFSO.CreateTextFile(LogFile, true) 'перезаписываю файл
        .Write s
        .Close
    end with

    ' Open Log-file (открываю файл)
    oShell.Run "explorer """ & LogFile & """", 1, false

    Set oFSO = Nothing: Set oShell = Nothing

    Sub Elevate()
      Const DQ = """"
      Set colOS = GetObject("winmgmts:\root\cimv2").ExecQuery("Select * from Win32_OperatingSystem")
      For Each oOS In colOS
        strOSLong = oOS.Version
      Next
      If Left(strOSLong, 1) = "6" Then
        If Not isAdminRights Then
            Set oShellApp = CreateObject("Shell.Application")
            oShellApp.ShellExecute WScript.FullName, DQ & WScript.ScriptFullName & DQ & " " & DQ & "Twice" & DQ, "", "runas", 1
            WScript.Quit
        End If
      End If
      set oOS = Nothing: set colOS = Nothing: set oShellApp = Nothing
    End Sub

    Function isAdminRights()
        Const KQV = &H1, KSV = &H2, HKCU = &H80000001, HKLM = &H80000002
        Set oReg = GetObject("winmgmts:root\default:StdRegProv")
        strKey = "System\CurrentControlSet\Control\Session Manager"
        intErrNum = oReg.CheckAccess(HKLM, strKey, KQV + KSV, flagAccess)
        isAdminRights = flagAccess
        Set oReg = Nothing
    End Function
     

    A=A
    B=B
    C=C
    D=C:\Users\Alex\Desktop\Special Character.txt
    E=E
    F=F
    G=G
    H=0
    I=:192046304:2236

    J=J
    K=K
    L=C:\Users\Alex\Desktop\Special Character.txt
    M=M
    N=N
    O=O
    P=P
    Q=Q
    R=R
    S=1
    T=T
    U=U
    V=C:\Users\Alex\Desktop\Special Character.txt
    W=C:\Users\Alex\Desktop

    X=X
    Y=Y
    Z=Z
    a=a
    b=b
    c=c
    d=C:\Users\Alex\Desktop\Special Character.txt
    e=e
    f=f
    g=g
    h=0
    i=:192046304:2236
    j=j
    k=k
    l=C:\Users\Alex\Desktop\Special Character.txt
    m=m
    n=n
    o=o
    p=p
    q=q
    r=r
    s=1
    t=t
    u=u
    v=C:\Users\Alex\Desktop\Special Character.txt
    w=C:\Users\Alex\Desktop
    x=x
    y=y
    z=z
    0=C:\Users\Alex\Desktop\Special Character.txt
    1=C:\Users\Alex\Desktop\Special Character.txt

    2=
    3=
    4=
    5=
    6=
    7=
    8=
    9=


    Из анализа видно, что:
    • регистр букв макроса не имеет значения;
    • для папок и файлов результаты не отличаются;
    • Доступные макросы: %D, %H, %I, %L, %S, %V, %W, %0 - %9
    • %D,%L,%V,%0,%1 - выдают одинаковую информацию - путь и имя целевого объекта
    • %W - выдает путь к папке, в которой находится объект;
    • %H - всегда показывает 0
    • %S - всегда показывает 1
    • %I - что такое для меня сначала было загадкой. :192046304:2236 ??? при этом последние 4 цифры за время тестов всегда были одинаковы.

    1) Также я долго не мог понять, почему получаю ошибку при попытке исполнить глагол контекстного меню программно из скрипта
    (да, такое возможно. Я ранее описывал полезность это метода для установки inf).

    Методом исключения виновником нашелся макрос %W,
    который не просто выдает путь к каталогу, в котором находится целевой файл или каталог,
    а обращает внимание на родителя (а именно процесса), из которого вызван глагол для объекта.

    В чем это выражается:
    когда я нажимаю в Total Commander-e правой клавишей по любому файлу и выполняю глагол, получаю ту же ошибку:
    Error.png

    Т.е. родитель - не Explorer, а TC.
    Тоже самое, когда я делаю это программно. Родитель - wscript.exe

    Забавно, что если в реестре оставить только само значение %W - это не вызывает ошибки. И в ответ на глагол открывается стандартное окно "Открыть с помощью"
    связанное с типом файла целевого объекта.

    Но при попытке явно раскрыть его как строку, передав в качестве аргумента любому приложению, например, если пропишу в Verb\Command: @=
    Код (Text):
    explorer %W
    получаем ту же ошибку.

    Напрашивается вывод: неужели внутри самих реестровых значений также существует некий подтип данных
    (например, строка и Nothing - отсутствие объекта, вызывающее "исключение" у самой среды)?

    2) И когда я обошел эту проблему путем удаления макроса %W из строки
    и запустил глагол программно, макрос %%I поменял последние цифры !!!

    Вуаля, первая мысль ProcessID. И команда tasklist | find "2236" указала на explorer.exe, что
    так и есть. Глагол умеет определять ProcessID родителя, который его запустил.
    Но там же не только PID.
    192046304

    Вбиваю не задумываясь:
    Код (Text):
    wmic process where caption="explorer.exe" get /value
    Но дальше ждет облом, т.к. никакой зависимости я не нашел :D
    wscript.exe, запускающий глагол самого себя:
    (поэтому PID всегда разный)

    2980272:6116
    3850752:4676
    4785408:6752
    2710240:6068

    Запуск глагола через проводник:

    275734032:2236
    275733024:2236
    275733600:2236

    -- здесь выдержал некоторое время:

    189618384:2236
    189616656:2236
    189618240:2236
    189618096:2236

    192040688:2236
    191547376:2236
    191545360:2236

    Первые 5 цифр у explorer.exe часто совпадают,
    да и их общее кол-во больше чем у wscript.exe
    Но что это такое - остается загадкой.
    На счет цифровых макросов нужно больше информации.
    С 2 по 9 - пустые значения (но они точно есть, а иначе бы вывелась цифра)
    На счет %H = 0, %S = 1. Также неизвестно, что это.

    Продолжение следует...
     

    Вложения:

    Последнее редактирование: 7 янв 2014
    Kиpилл нравится это.
  4. Kиpилл
    Онлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.217
    Симпатии:
    4.978
    О...смотри:
    Код (Text):
    Windows Registry Editor Version 5.00

    [HKEY_CLASSES_ROOT\*\shell\help]
    @="help command"

    [HKEY_CLASSES_ROOT\*\shell\help\command]
    @="help"
     
    И получаем:
    Безымянный.jpg


    То бишь это все таки командная строка,но ее возможности несколько ограничены чем то.
     
  5. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Что тебя удивляет?
     
  6. Kиpилл
    Онлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.217
    Симпатии:
    4.978
    Оказывается есть макросы,которые воспринимаются определенными глаголами.
    После некоторых поисков по реестру я удостоверился что есть цифровые макросы и для глагола printto.
    Глагол позволяет напечатать выбранный файл или папку, просто перетаскивая его на принтер. Можно указать принтер, используя "% 1", "% 2", "% 3" и т.д., в зависимости от того, сколько есть принтеров.

    По тем макросам что ты эксперементировал тоже все неоднозначно - в зависимости от того есть ли исполняемый файл прописанный в глаголе команда выполняется под разными условиями,пока точно не разобрал еще.
     
    Последнее редактирование: 24 янв 2014
    Dragokas нравится это.
  7. Kиpилл
    Онлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.217
    Симпатии:
    4.978
    Вот еще один нюанс,я по ходу с принтерами поторопился.
    Код (Text):
    HKEY_LOCAL_MACHINE\SOFTWARE\Classes\txtfile\shell\open\command
    %SystemRoot%\system32\NOTEPAD.EXE /p %1
    %SystemRoot%\system32\notepad.exe /pt "%1" "%2" "%3" "%4"
    Такой вариант будет отправлять объект на печать при отрытии в блокноте.
    Здесь %1 это открытие файла,как обычно.
    %2 - отправка на принтер
    %3 вызов драйвера печати
    %4 номер порта

    % 3 и% 4 не заключаются в кавычки.
    Аргументы
    %fn - путь к файлу
    %pt - имя принтера

    например
    Код (Text):
    notepad.exe /pt "%fn" "%pt"
    отправляет файл %fn на принтер %pt

    printo и pt печатает файл на указанном принтере. Используется Оболочка с поддержкой drag-and-drop для принтеров.

    %1-это имя файла и %2-имя принтера. Можно игнорировать %3 и %4 для Windows 95 и более поздних системах. Для систем Windows 3.1, %3 представляет собой имя драйвера и %4 имя порта

    надо попробовать изучить:
    http://technet.microsoft.com/en-us/library/ee156618.aspx
     
    Последнее редактирование: 24 янв 2014
    Dragokas нравится это.
  8. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Там об этом ничего.
    Зато в целом неплохая библиотека статей по WSH. Спасибо.
     
    akok нравится это.
  9. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Что означает %*
    например:
    Код (Text):
    [HKEY_CLASSES_ROOT\exefile\shell\open\command]
    @="\"%1\" %*"
    "IsolatedCommand"="\"%1\" %*"
     
  10. Kиpилл
    Онлайн

    Kиpилл Команда форума Администратор

    Лучший автор месяца

    Сообщения:
    12.217
    Симпатии:
    4.978
    Если я правильно понимаю - выполнить двоичный файл с последующей передачей аргумента.
     
  11. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Вот, что прописано для дефолтовой ассоциации .zip:
    Код (Text):
     %SystemRoot%\Explorer.exe /idlist,%I,%L
    %I - это оказывается хендл ItemIDList. IDList - это идентификатор, который можно альтернативно использовать для задания пути к файлу.
    А %I постоянно менялся для одного и того же файлового объекта, потому что это не сам ID, а хендл ("указатель") на него внутри процесса с ProcessID, заданным через 2-ю часть макроса %I
    Код (Text):
    :Handle:ProcessID
    Для справки:
    Configuring Windows Explorer - Command Line Options
    The Windows Explorer Command Line

    Получается, согласно данным от Geoff Chappell в качестве файлового объекта для макроса %I может использоваться только папка, а также объекты которые к ней приравниваются из-за своей специфики, например, Cabinet-архивы, архивы Zip и Windows Search Protocol.
     
    Последнее редактирование: 4 мар 2016
    Kиpилл нравится это.

Поделиться этой страницей