PDA

Показать полную графическую версию : экранировать скобки в данных из реестра


kokos76
10-01-2016, 14:38
Для одного цикла FOR поборол лишние круглые скобки, а дальше отсутствие образования не позволяет :-)
Помогите, пожалуйста, довести до ума скрипт. Делаю на основе этого (http://forum.oszone.net/post-1327492.html#post1327492) и этого (http://forum.oszone.net/post-2592636.html#post2592636) кода.

rem @echo off
rem chcp 1251
if not exist "c:\backup\reg" mkdir c:\backup\reg
set count=1

for %%? in (
"HKEY_CLASSES_ROOT\TypeLib\{EDCD5812-6A06-43C3-AFAC-46EF5D14E22C}\1.0\HELPDIR\(Default)"
) do (
call :sub %%?
)

goto :eof

:sub
setlocal
set "s=%~1"

:sub_1
for /f "tokens=1* delims=\" %%i in ("%s%") do set s=%%j& set t=%%i
if defined s ((if defined $R_REG (set "$R_REG=%$R_REG%\%t%") else (set "$R_REG=%t%"))& goto %0_1) else (set "$R_VAL=%t%")

Set $R_TMP=HKEY_CURRENT_USER\Temp
Set $F_REG=c:\backup\reg\%count%.reg
Set $F_TMP=c:\backup\reg\%count%.tmp

set $R_VAL=%$R_VAL:(=^^(%
set $R_VAL=%$R_VAL:)=^^)%
Set $N=1
For %%i In (%$R_VAL%) Do Set /A $N+=1

Reg Delete "%$R_TMP%" /f >Nul 2>&1
If Exist "%$F_TMP%" DEL /F/Q "%$F_TMP%"
If Exist "%$F_REG%" DEL /F/Q "%$F_REG%"

rem set $R_VAL=%$R_VAL:^^(=(%
rem set $R_VAL=%$R_VAL:^^)=)%
rem echo %$R_VAL%
rem pause

For /F "Tokens=%$N%* Delims= " %%i In (
'REG Query "%$R_REG%" /v "%$R_VAL%"^|FindStr /IBRC:"[ ]*%$R_VAL%[ ][ ]*REG_"'
) Do REG ADD "%$R_TMP%" /v "%$R_VAL%" /t %%i /f /d "%%j" >Nul
RegEdit /E:A "%$F_TMP%" "%$R_TMP%"

For /F "Delims=:" %%i In ('FindStr /BNC:^"[^" "%$F_TMP%"') Do Set $M=%%i
For /F "Tokens=1* Delims=:" %%i In ('FindStr /BVNC:^"]^" "%$F_TMP%"') Do (
If %%i EQU %$M% (
Echo.[%$R_REG%]>>%$F_REG%
) ELSE (
Echo.%%j>>%$F_REG%
)
)

endlocal

del c:\backup\reg\%count%.tmp
set /a count=count+1
exit /b 0

Iska
10-01-2016, 15:27
kokos76, не борите. Просто используйте WSH или PoSH для оригинального кода.

kokos76
10-01-2016, 16:03
Что, неужели никак? С одной стороны, я ничего не знаю, кроме bat-ников (когда-то в школе интересовался), а с другой стороны, мне нужно, чтобы скрипт мог работать в Безопасном режиме и в Windows RE.

Georgio
10-01-2016, 21:16
kokos76, если представленный Вами код рабочий, то тогда почти со всеми спецсимволами будет работать такой код:

@echo off
rem chcp 1251
if not exist "c:\backup\reg" mkdir c:\backup\reg
set count=1

for %%? in (
"HKEY_CLASSES_ROOT\TypeLib\{EDCD5812-6A06-43C3-AFAC-46EF5D14E22C}\1.0\HELPDIR\(Default)"
) do (
call :sub %%?
)

goto :eof

:sub
setlocal
set "s=%~1"

:sub_1
for /f "tokens=1* delims=\" %%i in ("%s%") do set s=%%j& set t=%%i
if defined s ((if defined $R_REG (set "$R_REG=%$R_REG%\%t%") else (set "$R_REG=%t%"))& goto %0_1) else (set "$R_VAL=%t%")

Set $R_TMP=HKEY_CURRENT_USER\Temp
Set $F_REG=c:\backup\reg\%count%.reg
Set $F_TMP=c:\backup\reg\%count%.tmp

Set $N=1
For %%i In ("%$R_VAL: =" "%") Do If %%i neq "" Set /A $N+=1

Reg Delete "%$R_TMP%" /f >Nul 2>&1
If Exist "%$F_TMP%" DEL /F/Q "%$F_TMP%"
If Exist "%$F_REG%" DEL /F/Q "%$F_REG%"

For /F "Tokens=%$N%* Delims= " %%i In (
'REG Query "%$R_REG%" /v "%$R_VAL%"^|FindStr /IBRC:"[ ]*%$R_VAL%[ ][ ]*REG_"'
) Do REG ADD "%$R_TMP%" /v "%$R_VAL%" /t %%i /f /d "%%j" >Nul
RegEdit /E:A "%$F_TMP%" "%$R_TMP%"

For /F "Delims=:" %%i In ('FindStr /BNC:^"[^" "%$F_TMP%"') Do Set $M=%%i
For /F "Tokens=1* Delims=:" %%i In ('FindStr /BVNC:^"]^" "%$F_TMP%"') Do (
If %%i EQU %$M% (
cmd/v/c Echo.[!$R_REG!]>>%$F_REG%
) ELSE (
Echo.%%j>>%$F_REG%
)
)

endlocal

del c:\backup\reg\%count%.tmp
set /a count=count+1
exit /b 0

.

Пакетный файл с этим кодом не сможет только обрабатывать имена параметров реестра, содержащие символы
*
?
\
.

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

Да, чуть не забыл написать, что если в обрабатываемой строке встретятся символы процента, то в коде пакетного файла их надо обязательно удваивать при записи такой строки.

kokos76
10-01-2016, 23:53
Georgio, код рабочий. Со обычными строками работает нормально. Это вывод ошибки в Вашем варианте.
C:\test>Set $N=1

C:\test>For %i In ("(Default)") Do If %i NEQ "" Set /A $N+=1

C:\test>If "(Default)" NEQ "" Set /A $N+=1

C:\test>Reg Delete "HKEY_CURRENT_USER\Temp" /f 1>Nul 2>&1

C:\test>If Exist "c:\backup\reg\1.tmp" DEL /F/Q "c:\backup\reg\1.tmp"

C:\test>If Exist "c:\backup\reg\1.reg" DEL /F/Q "c:\backup\reg\1.reg"

C:\test>For /F "Tokens=2* Delims= " %i In ('REG Query "HKEY_CLASSES_ROOT\TypeLib\{EDCD5812-6A06-43C3-AFAC-46EF5D14E22C}\1.0\HELPDIR" /v "(Default)"|FindS
tr /IBRC:"[ ]*(Default)[ ][ ]*REG_"') Do REG ADD "HKEY_CURRENT_USER\Temp" /v "(Default)" /t %i /f /d "%j" 1>Nul
Ошибка: Не удается найти указанный раздел или параметр в реестре.

А вообще, конечно, жаль, что звёздочки нельзя обработать.

Georgio
11-01-2016, 01:20
C:\test>For /F "Tokens=2* Delims= " %i In ('REG Query "HKEY_CLASSES_ROOT\TypeLib\{EDCD5812-6A06-43C3-AFAC-46EF5D14E22C}\1.0\HELPDIR" /v "(Default)"|FindS
tr /IBRC:"[ ]*(Default)[ ][ ]*REG_"') Do REG ADD "HKEY_CURRENT_USER\Temp" /v "(Default)" /t %i /f /d "%j" 1>Nul
Ошибка: Не удается найти указанный раздел или параметр в реестре. »



Как раз-таки мой вариант кода отработал безошибочно.

Если уж параметра с таким именем в реестре нет, то его значение никаким кодом найти невозможно.

Очевидно, Вы посчитали за имя параметра отображаемую в реестре запись "(Default)" (то есть "(По умолчанию)") для безымянных параметров.

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

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

Iska
11-01-2016, 02:50
для чего нужно знать цель Вашей разработки и причину, по которой Вы объединяете изначально имя раздела реестра с именем параметра реестра в одну строку »
Из Process Monitor'а:
Имеется множество строк вида КОРЕНЬ_РАЗДЕЛА_РЕЕСТРА\название\подраздела\реестра\параметр_реестра разной длины, т.е. они содержат неодинаковое количество символов \ (получены экспортом из procmon). Помогите, пожалуйста, разбить каждую на две подстроки: КОРЕНЬ_РАЗДЕЛА_РЕЕСТРА\название\подраздела\реестра и параметр_реестра.
Цель - подать эти значения на вход cmd-скрипта, выполняющего экспорт конкретных параметров реестра от ув. amel27. Если необходимо, массив исходных данных можно вынести в отдельный txt-файл. »

Georgio
11-01-2016, 03:29
...КОРЕНЬ_РАЗДЕЛА_РЕЕСТРА\название\подраздела\реестра\параметр_реестра... » »



Да уж... Если с вопросительными знаками и астерисками ещё можно справиться, то что делать, когда имя параметра также, как и имя раздела, содержит обратные слеши?.. Хотя, разделить строку, конечно, можно (проверяя существование каждого раздела в этом "псевдопути"), но сложно...

kokos76
11-01-2016, 07:47
Очевидно, Вы посчитали за имя параметра отображаемую в реестре запись "(Default)" (то есть "(По умолчанию)") для безымянных параметров.
А значения безымянных параметров с помощью такого кода получать невозможно. »
так вот оно что...
с параметром (newparameter) скрипт отработал нормально. Вот результат:
REGEDIT4

[HKEY_CLASSES_ROOT\TypeLib\{EDCD5812-6A06-43C3-AFAC-46EF5D14E22C}\1.0\HELPDIR]
"(newparameter)"="somevalue"

P.S. Мне нужно бэкапить\восстанавливать параметры реестра из safemode и WinRE. Раз тут так сложно, то, возможно, будет лучше в AutoIt ?

kokos76
11-01-2016, 08:21
P.p.s. Да, такая запись входных данных - это выходные данные из Process Monitor. Посмотрю после работы, может там можно как-то "подкрутить" экспорт.




© OSzone.net 2001-2012