PDA

Показать полную графическую версию : [решено] Поиск строки в значени ключа реестра.


user_123
26-09-2009, 20:31
Подскажите пожалуйста, как проверить, содержится ли в значении ключа реестра искомая строка (с использованием маски *text*) и если содержится, присвоить определённой переменной определённое значение.

Как прочитать реестр, я знаю:
For /F "Tokens=2*" %%I In ('Reg Query HKCU\temp /V temp') Do ... %%J

Пробовал сам сделать, не чего не получилось...
Заранее благодарен.

Iska
26-09-2009, 21:14
user_123, можете попробовать на основе такого:
@echo off
setlocal enableextensions enabledelayedexpansion

rem If HKCU\Console\FaceName like "Lucida Console" or "Consolas"? --> Set SomeVar to SomeValue1 else SomeValue2
for /f "skip=3 tokens=3* delims= " %%i in ('reg.exe query "HKCU\Console" /v "FaceName"') do (
(echo %%i|findstr.exe /r /i /c:".*consol.*">nul) && set SomeVar=SomeValue1|| set SomeVar=SomeValue2
)

echo Result: SomeVar=[%SomeVar%]
endlocal
exit /b 0

user_123
27-09-2009, 00:27
Iska, Спасибо.

Однако, не работает... Не зависимо от того, имеется ли искомая строка, или нет, всё время присваивается 2-ое значение переменной. Ошибок в синтаксисе CMD не находит... И предложенный Вами метод чтения ключа реестра тоже на работает (переменная вообще не получает значение), я написал это немного по-другому...

А если ключа реестра нет, то нет и значения у переменной тоже нет...

А, в целом, у меня так написано:For /F "Tokens=2*" %%I In ('reg query "<RegDir>" /v "<Key>"') do (
(echo %%i|findstr /r /i /c:".*<text>.*">nul) && set <переменная1>=1|| set <переменная1>=0
)

Iska
27-09-2009, 02:43
Однако, не работает...
Что могу сказать… У меня, приведённый мною код, работает корректно. Обычно я даже проверяю ещё раз после выкладывания, дабы постараться избежать нелепых опечаток/ошибок при копировании.

Сие может зависеть отчасти от версии reg.exe; Вы можете попробовать, как указывал (http://forum.oszone.net/post-1132734-8.html) amel27, не использовать «skip», а фильтровать выходной поток команды «reg.exe», только используя в качестве фильтра имя параметра:
for /f "tokens=3* delims= " %%i in ('reg.exe query "HKCU\Console" /v "FaceName"^|find.exe /i "FaceName"') do (
вместо
for /f "skip=3 tokens=3* delims= " %%i in ('reg.exe query "HKCU\Console" /v "FaceName"') do (
А, в целом, у меня так написано…
А почему именно так? Ибо у меня команда (с реально существующими параметрами):
for /f "tokens=2*" %i in ('reg.exe query "HKCU\Console" /v "FaceName"') do echo %i
выдаёт ожидаемое:
REG_SZ
В таком случае верните на место своё «echo %%j» (а не «%%i», как в моём примере), поскольку Вы используете «tokens=2*» (а я — «tokens=3*»), и у Вас «*» будет как раз в «%%j».
А если ключа реестра нет, то нет и значения у переменной тоже нет...
Логично :). Цитирую……условие задачи, поставленное Вами же:
…как проверить, содержится ли в значении ключа реестра искомая строка…
Про то, что требуется попутно проверять наличие самого раздела и/или параметра реестра (и как следует в этом случае поступать) — не упоминалось никоим образом.

user_123
27-09-2009, 10:30
Iska, добавление ^|find.exe /i "FaceName" приводит к тому, что не присваивается ни 1, ни 2 переменная.

Дело действительно было в i / j. Поставил "j". Сначала не чего не изменилось... Как позже выяснилось проблема была в регистре "i".

т.е. надо было не так писать:For /F "Tokens=2*" %%I In ( а так: For /F "Tokens=2*" %%i In (
Спасибо большое за помошь.

Iska
27-09-2009, 10:58
user_123, да, это так:

For

* Имена параметров переменная команды for учитывают регистр буквы, они являются глобальными и одновременно может быть активно не больше 52 переменных.
К сожалению, я не обратил на это отдельного внимания при рассмотрении кода из Вашего поста #3 (http://forum.oszone.net/post-1228331-3.html), поскольку сразу привёл формат Вашего кода у себя к строчным (в том числе и переменную «%%I»).

user_123
27-09-2009, 12:59
%systemroot%\help\ntcmds.chm »
У меня такого файла нет... vista x32.
Хотя папка help есть...

Подскажите пожалуйста ещё кое-что... Я не могу до конца разобраться в синтаксисе команды "findstr".
В значении ключа реестра, в котором ищется строка содержится путь к ехе-файлу (может быть в кавычках) и дополнительные ключи (параметры). Мне надо определить, содержит ли значение ключа следующее:*путь_к_файлу*парамтры_запуска* и если всё соответствует (и путь, и параметры запуска) присвоить значение для переменной.

Смотрел findstr /?
Там сказано что для поиска нескольких строк надо писать через пробел... Но в данном случае условие определяется по принципу дизъюнкции (или), а мне надо, чтобы по принципу конъюкции (и).

amel27
28-09-2009, 05:20
надо определить, содержит ли значение ключа следующее »
FindStr /IRC:".*путь_к_файлу.*парамтры_запуска"

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

1. REG.EXE почти всегда возвращает значение в ANSI-кодировке (WIN), а для батника родной является OEM-кодировка (DOS), т.е. даже одинаковые строки в разных кодировках не совпадут;
2. Использование "CHCP 1251" не исправит ситуацию, т.к. FINDSTR неправильно перекодирует часть русских букв (в частности, "ь").

есть два варианта:

- набирать батник сразу в WIN кодировке, что нежелательно, т.к. может нарушить работу других команд;
- осуществлять перекодировку средствами самого батника, пример для "Test.TXT" в WIN-кодировке:
@Echo Off

CHCP 1251 >Nul
Set $R=.*путь_к_файлу.*парамтры_запуска
CHCP 866 >Nul

Type Test.TXT|FindStr /VIRC:"%$R%"

Iska
28-09-2009, 16:58
Мне надо определить, содержит ли значение ключа следующее…*путь_к_файлу*парамтры_запуска*
и если всё соответствует (и путь, и параметры запуска) присвоить значение для переменной.»
Я могу Вам посоветовать попробовать использовать регулярные выражения (findstr.exe в аккурат под это дело предназначена) в строке поиска [ага, amel27 уже привёл пример на эту тему; надо было мне сразу читать по диагонали]. Будет гораздо проще, ежели Вы приведёте конкретные примеры.

1. REG.EXE почти всегда возвращает значение в ANSI-кодировке (WIN)…
amel27, в консоль, насколько я понял, вывод идёт в текущей установленной кодовой странице, а вот при перенаправлении вывода в другую команду/файл — ANSI (я смотрел на MS WinXP SP3); правильно я понимаю? И, ещё, не могли бы Вы уточнить, для повышения квалификации, так сказать: Вы упомянули «…почти всегда» — подробнее можно? Каковы исключения, и в какую сторону?

amel27
29-09-2009, 04:26
Iska, AFAIK ввод/вывод всегда ведется в текущей (CHCP) кодировке... но только если он выполняется штатными CMD-командами, при вызове внешних EXE результат целиком зависит них, по идее они должны перед вводом/выводом проверять текущую кодировку и приводить поток к ней, на деле можно ждать всё что угодно - "метод тыка" рулит

подробнее можно? Каковы исключения, и в какую сторону? »хз... например, следующая команда корректно перекодирует в OEM и отображает русский текст параметра HKCU\test (REG_SZ) в Win2003 ENU (русская локаль), но в XP RUS («…почти всегда») на выходе имеем ANSI:
reg query hkcu /v test|find /v ""

З.Ы. кроме того, никто не мешает сохранить в реестре OEM-текст, как ANSI - попадались и такие случаи

Iska
30-09-2009, 05:57
amel27, спасибо, ясно. Интересное поведение. Вы случайно не в курсе, здесь является ключевым именно «Win2003» или же «ENU/RUS»?

amel27
01-10-2009, 03:22
Iska, проверил - на W2003 RUS работает правильно (OEM), XP ENU под рукой нет

Iska
01-10-2009, 06:30
amel27, ещё раз спасибо. Стало быть, будем считать, что в данном случае именно конкретная версия ОС/файла reg.exe влияет на учёт текущей кодовой страницы консоли при перенаправлении вывода.

Freem
27-11-2014, 13:34
Поправьте пожалуйста код.
1. Ищем в реестре параметр
2. Если параметр существует, выполнить его содержимое (а это путь к setup файлу) с ключами --uninstall --force-uninstall
3. Если параметр не существует, вывести Echo - Test is not installed


Echo Off
SetLocal EnableExtensions

For /F "Tokens=2* Delims= " %%I In ('Reg Query "HKEY_CURRENT_USER\Software\TEST" /V UninstallString') Do Set testuninstall=%%J

%testuninstall% --uninstall --force-uninstall

Georgio
27-11-2014, 18:07
@(for /f "tokens=2*" %%I in ('reg query "HKCU\Software\TEST" /v "UninstallString"') do @start "" "%%J" --uninstall --force-uninstall)|| (echo TEST isn't installed.&>nul timeout /t 2)

Поскольку символ табуляции, как и символ пробела, является для "for" разделителем по умолчанию, то разделители можно не указывать.




© OSzone.net 2001-2012