![]() |
Некорректная работа оператора сравнения "neq"
Включил в батник следующие строки:
Код:
For /F "Tokens=2,*" %%i In ('2^>nul Reg Query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{*-*-*-*-*}_is1" /V InstallLocation') Do if /i "%%j" neq "%~dp0" Goto label Помогите разобраться с чем это может быть связано. |
Если включить в скрипт конструкции:
Код:
Do if "%%j"=="%~dp0" Goto label На WinXP с оператором "neq" скрипт работает, только так: Код:
For /F "Tokens=2,*" %%i In ('2^>nul Reg Query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{*-*-*-*-*}_is1" /V InstallLocation') Do set Location=%%j |
Lucretius, у Вас изначально ошибка — в алгоритме. В запросе «reg.exe /query» Вы получаете (или не получаете) несколько строк. Вам нужно отфильтровать среди них потребную:
Код:
@echo off |
Lucretius, Вы, наверное, имели в виду, что при якобы очевидном тождестве "%%j" и "%~dp0" в условии IF "%%j" neq "%~dp0" всё равно происходит переход по метке. Ну, ладно, дело тут не в этом.
Вся проблема заключена в результате выполнения команды Код:
REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*******" /V InstallLocation Не знаю, как в других версиях утилиты reg.exe, но у меня как в Windows XP, так и в Windows 7 результат выполнения команды, например, Код:
REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{006B5C65-3938-4246-B182-994A7E415EDE}" /V InstallLocation Код:
В указанном выше спучае при ключе "tokens=2*" второго и последующих "токенов" не найдётся, и переменные %%I и %%J не определятся. После этого будет обработана вторая строка, и переменная %%J примет ожидаемое нами значение C:\Program Files\Intel\Bluetooth\, после чего корректно выполнится условие IF. Теперь рассмотрим другой случай. Команда: Код:
REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Download Master_is1" /V InstallLocation Код:
Третий пример. Команда: Код:
REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft .NET Framework 4 Client Profile" /V InstallLocation Код:
Таким образом, в таких условиях получить правильный результат можно, только убрав вторую (первую из непустых) строку результата команды REG QUERY из обработки командой FOR, например, так: Код:
FOR /F "skip=2 tokens=2*" %%I IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Download Master_is1" /V InstallLocation') DO IF /I "%%J" NEQ "%~dp0" GOTO label |
Iska, Ваш скрипт работает правильно только в случаях, когда в значении параметра InstallLocation отсутствуют пробелы. Поэтому надо так:
Код:
for /f "usebackq tokens=2* delims= " %%i in ( |
Вот, уж (в данном значении "уж" -- не пресмыкающееся), что работает некорректно, так это переведённая справка командной строки по операторам сравнения (Windows 7 Starter). Для тех, кто хочет улыбнуться (не "оффтоп") --
|
Цитата:
Цитата:
в отличие от более новых версий: где вместо табуляции используются пробелы в качестве разделителей. Я потому и писал: Цитата:
Цитата:
|
Спасибо всем откликнувшимся!
Georgio Вы правы, я допустил опечатку, действительно "при якобы очевидном тождестве "%%j" и "%~dp0" в условии IF "%%j" neq "%~dp0" всё равно происходит переход по метке." (исправил в шапке) Сразу скажу, что код на примере Вашего Iska: Код:
For /f "usebackq Tokens=2*" %%I In (`2^>nul Reg Query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\CCleaner" /V "InstallLocation" ^| find.exe /i "InstallLocation"`) Do if /I "%%J\" NEQ "%~dp0" Goto label Код:
For /F "skip=2 Tokens=2*" %%I In ('2^>nul Reg Query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\CCleaner" /V InstallLocation') Do if /I "%%J\" NEQ "%~dp0" Goto label По поводу знака табуляции - подтверждаю, работает на XP, но не работает на семёрке я поднимал уже эту тему здесь. Кстати, с пробелом в качестве разделителя: Код:
for /f "usebackq tokens=2* delims= " %%i in ( Код:
for /f "usebackq tokens=2*" %%i in ( Изначально меня сбило с толку то, что если вынести значения в переменную за пределы цикла, переменная обретает верное значение, в противоречие тому, что внутри цикла "не работает" оператор NEQ. Причём оператор EQU, как я уже говорил, работал. На примере приведённого мной (неверного) кода: Код:
@echo Off Код:
Reg Query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\CCleaner" /V InstallLocation Код:
REM WinXP: Georgio спасибо за детальное объяснение, буду разбираться... |
Цитата:
Цитата:
|
Iska, верно, перенаправил в файл, открыл в hex - табуляция...
|
Объясните, а зачем указывать в качестве разделителей - используемые по умолчанию?
Выдержка из справки(Win7): " delims=xxx - набор разделителей вместо используемых по умолчанию пробела и знака табуляции." Как я уже отмечал выше, если в подобных случаях(обработка результатов команд reg.exe) не указывать разделитель, скрипты работают одинаково правильно на обоих осях. Вот наткнулся на скрипт где в качестве разделителей указаны и табуляция и пробел, можно сказать универсальный вариант, но опять же - без указания разделителей работает ничуть не хуже. При каких условиях это может иметь значение? |
Цитата:
|
Ещё такой вопрос, приведённые выше скрипты можно реализовать двумя способами:
1. Код:
For /f "usebackq Tokens=2* Delims= " %%I In (`2^>nul REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\CCleaner" /V "InstallLocation" ^| find.exe /i "REG_SZ"`) Do Set loc=%%~J Код:
For /f "Tokens=2* Delims= " %%I In ('2^>nul REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\CCleaner" /V "InstallLocation" ^| find.exe /i "REG_SZ"') Do Set loc=%%~J |
Lucretius, в данном случае «оба лучше».
Пример, когда «usebackq» «лучше»: Код:
@echo off |
Iska, спасибо Вам за внимание к теме и оперативность в ответах. По поводу "usebackq", - назначение новой семантики мне понятно, меня смущало применение её там, где в ней нет необходимости.
Последний вопрос: Внутри цикла - Код:
For /f "Tokens=2* Delims= " %%I In ('2^>nul REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\CCleaner" /V "InstallLocation" ^| find.exe /i "REG_SZ"') вынес значение в переменную за пределы цикла: Код:
For /f "Tokens=2* Delims= " %%I In ('2^>nul REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\CCleaner" /V "InstallLocation" ^| find.exe /i "REG_SZ"') Do Set install=%%~J |
Да не особенно. Ну, разве что:
Код:
if not defined install goto :MyLabel |
Время: 19:51. |
Время: 19:51.
© OSzone.net 2001-