Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   экранировать скобки в данных из реестра (http://forum.oszone.net/showthread.php?t=310174)

kokos76 10-01-2016 14:38 2593117

экранировать скобки в данных из реестра
 
Для одного цикла FOR поборол лишние круглые скобки, а дальше отсутствие образования не позволяет :-)
Помогите, пожалуйста, довести до ума скрипт. Делаю на основе этого и этого кода.

Код:

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 2593136

kokos76, не борите. Просто используйте WSH или PoSH для оригинального кода.

kokos76 10-01-2016 16:03 2593149

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

Georgio 10-01-2016 21:16 2593229

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 2593267

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 2593280

Цитата:

Цитата kokos76
Код:

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 2593293

Цитата:

Цитата Georgio
для чего нужно знать цель Вашей разработки и причину, по которой Вы объединяете изначально имя раздела реестра с именем параметра реестра в одну строку »

Из Process Monitor'а:
Цитата:

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


Georgio 11-01-2016 03:29 2593298

Цитата:

Цитата Iska
Цитата:

Цитата kokos76
...КОРЕНЬ_РАЗДЕЛА_РЕЕСТРА\название\подраздела\реестра\параметр_реестра... »

»



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

kokos76 11-01-2016 07:47 2593313

Цитата:

Цитата Georgio
Очевидно, Вы посчитали за имя параметра отображаемую в реестре запись "(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 2593319

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


Время: 22:00.

Время: 22:00.
© OSzone.net 2001-