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

Dragokas

Very kind Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,131
Реакции
5,904
Баллы
648
Читал:
http://safezone.cc/threads/desjat-sovetov-po-tonkoj-nastrojke-windows-xp-s-pomoschju-reestra.7780/

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

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

Кирилл

Команда форума
Администратор
Сообщения
13,812
Реакции
6,164
Баллы
913
Dragokas, тут нам предстоит совместная работа.

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


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

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

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


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

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

Dragokas

Very kind Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,131
Реакции
5,904
Баллы
648
На счет цифр после 1, здесь для меня загадка.
Не расскажешь ли, где слышал о них. И как симмитировать действие хотя бы одной из них?
% 1 действие передается файлу
Наверное, более корректно сказать "... от файла".

Раздел Command ,насколько я знаю, работает с COMMAND.COM или чем то подобным,так думаю потому что не все команды CMD воспринимаются в разделе.
Возможно это было из за разницы в версиях cmd ,тут надо поэкспериментировать-вдруг COMMAND.COM окажется не при делах.
Но-но. Ты вспомни еще 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: @=
Код:
explorer %W
получаем ту же ошибку.

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

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

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

Вбиваю не задумываясь:
Код:
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. Также неизвестно, что это.

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

Вложения

Последнее редактирование:

Кирилл

Команда форума
Администратор
Сообщения
13,812
Реакции
6,164
Баллы
913
О...смотри:
Код:
Windows Registry Editor Version 5.00

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

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


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

Кирилл

Команда форума
Администратор
Сообщения
13,812
Реакции
6,164
Баллы
913
Оказывается есть макросы,которые воспринимаются определенными глаголами.
После некоторых поисков по реестру я удостоверился что есть цифровые макросы и для глагола printto.
Глагол позволяет напечатать выбранный файл или папку, просто перетаскивая его на принтер. Можно указать принтер, используя "% 1", "% 2", "% 3" и т.д., в зависимости от того, сколько есть принтеров.

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

Кирилл

Команда форума
Администратор
Сообщения
13,812
Реакции
6,164
Баллы
913
Вот еще один нюанс,я по ходу с принтерами поторопился.
Код:
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 - имя принтера

например
Код:
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
 
Последнее редактирование:

Dragokas

Very kind Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,131
Реакции
5,904
Баллы
648
  • Like
Реакции: akok

Dragokas

Very kind Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
6,131
Реакции
5,904
Баллы
648
Что означает %*
например:
Код:
[HKEY_CLASSES_ROOT\exefile\shell\open\command]
@="\"%1\" %*"
"IsolatedCommand"="\"%1\" %*"
 

Кирилл

Команда форума
Администратор
Сообщения
13,812
Реакции
6,164
Баллы
913
Если я правильно понимаю - выполнить двоичный файл с последующей передачей аргумента.
 

Dragokas

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

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