it-swarm.com.ru

Как я могу получить значение ключа реестра из пакетного скрипта?

Мне нужно использовать команду REG QUERY, чтобы просмотреть значение ключа и установить результат в переменную с помощью этой команды:

FOR /F "tokens=2* delims=    " %%A IN ('REG QUERY "KeyName" /v ValueName') DO SET Variable=%%B

Но если ключ не существует, я получаю сообщение об ошибке в консоли. Мне нужно скрыть эту ошибку! Я попытался поставить 2> nul после команды, чтобы остановить stderr, но это работает, если я только вызываю команду:

REG QUERY "KeyName" /v ValueName 2>nul

Если я введу это в команду FOR следующим образом:

FOR /F "tokens=2* delims=    " %%A IN ('REG QUERY "KeyName" /v ValueName') DO SET Variable=%%B 2>nul

Ошибка отображается . Так кто-нибудь знает, как скрыть ошибку? Или, может быть, другая команда тоже увидит, существует ключ или нет?

Спасибо

PS: я использую Windows XP

55
Fabius

Это работает для меня:

@echo OFF

setlocal ENABLEEXTENSIONS
set KEY_NAME="HKEY_CURRENT_USER\Software\Microsoft\Command Processor"
set VALUE_NAME=DefaultColor

FOR /F "usebackq skip=4 tokens=1-3" %%A IN (`REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul`) DO (
    set ValueName=%%A
    set ValueType=%%B
    set ValueValue=%%C
)

if defined ValueName (
    @echo Value Name = %ValueName%
    @echo Value Type = %ValueType%
    @echo Value Value = %ValueValue%
) else (
    @echo %KEY_NAME%\%VALUE_NAME% not found.
)

usebackq необходим, так как команда REG QUERY использует двойные кавычки.

skip=4 игнорирует все выходные данные, кроме строки, которая имеет имя значения, тип и значение, если оно существует.

2^>nul предотвращает появление текста ошибки. ^ - это escape-символ, который позволяет вам ввести > в команду for.

Когда я запускаю сценарий выше, как указано, я получаю этот вывод:

Value Name = DefaultColor
Value Type = REG_DWORD
Value Value = 0x0

Если я изменю значение VALUE_NAME на BogusValue, я получу это:

"HKEY_CURRENT_USER\Software\Microsoft\Command Processor"\BogusValue not found.
55
Patrick Cuff

Эта работа для меня с переменной, которая содержит пробелы в Windows 7:

FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKEY_LOCAL_MACHINE\Software\SomeAPP" /v ValueName`) DO (
    set appdir=%%A %%B
    )
ECHO %appdir%

Переменная A содержит все данные перед первым пробелом, B - оставшаяся часть ValueName (включая дополнительные пробелы), поэтому appdir = ValueName 

26
Ivan

Основываясь на решении tryToBeClever (на которое я случайно наткнулся и исправил методом проб и ошибок, прежде чем найти его), я также предлагаю пропустить вывод результатов с reg query через find для фильтрации нежелательных строк из-за несоответствия ! REG.EXE VERSION x.y. Фильтрация find и настройка tokens также позволяет выбрать именно то, что нам нужно (обычно это значение). Также добавлены кавычки, чтобы избежать неожиданных результатов с именами ключей/значений, содержащих пробелы.

Окончательный результат предлагается, когда мы заинтересованы только в получении значения:

@echo off
setlocal ENABLEEXTENSIONS
set KEY_NAME=HKCU\Software\Microsoft\Command Processor
set VALUE_NAME=DefaultColor
for /F "usebackq tokens=3" %%A IN (`reg query "%KEY_NAME%" /v "%VALUE_NAME%" 2^>nul ^| find "%VALUE_NAME%"`) do (
  echo %%A
)

Возможное предостережение от использования find заключается в том, что уровень ошибки, установленный reg, при возникновении ошибок теперь обфусцируется, поэтому следует использовать этот подход только для ключей, о которых известно, что они существуют, и/или после предыдущей проверки.

Небольшая дополнительная оптимизация (добавьте skip=1, чтобы избежать обработки первой строки вывода) может быть выполнена в случаях, когда имя ключа также содержит имя значения (как это имеет место с HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion и CurrentVersion), но удаляет большую гибкость, поэтому следует использовать только в особых случаях использования.

7
Helder Magalhães

Я понимаю, что это старый вопрос - но эта однострочная почти такая же, как ваша первоначальная попытка с парой дополнений. Он работает с путями, включая пробелы, и работает как в XP, так и в Windows 7, даже если ключ не найден (и скрывает ошибку). % fn% будет пустым, если ключ не существует. В этом примере показано текущее имя файла рабочего стола:

for /f "tokens=2*" %%a in ('reg query "HKEY_CURRENT_USER\Control Panel\Desktop" /v Wallpaper 2^>^&1^|find "REG_"') do @set fn=%%b
5
ChevyNo1
@echo off
setlocal ENABLEEXTENSIONS
set KEY_NAME=HKLM\SOFTWARE\Wow6432Node\Acme Software Inc\Common
set VALUE_NAME=InstallDir

FOR /F "tokens=2*" %%A IN ('REG.exe query "%KEY_NAME%" /v "%VALUE_NAME%"') DO (set pInstallDir=%%B)
echo %pInstallDir%

Это работает для меня в Win7, где ключ имеет пробел, а значение также имеет пробел . Поэтому, сохраняя вышеприведенный файл в c:\temp как test.bat, откройте окно cmd и запустите его.

C:\TEMP> тест

C:\Program Files (x86)\acme Software Inc\APP \ 

5
sheir

Для Windows 7 (Professional, 64-битная - не могу говорить за других) я вижу, что REG больше не выплевывает 

! REG.EXE VERSION 3.0

как это происходит в XP. Таким образом, вышеперечисленное необходимо изменить, чтобы использовать

skip=2

вместо 4 - что усложняет ситуацию, если вы хотите, чтобы ваш скрипт был переносимым. Хотя это намного более тяжелый и сложный, решение на основе WMIC может быть лучше.

4
tryingToBeClever

По какой-то причине код Патрика Каффа не работает в моей системе (Windows 7), вероятно, из-за попытки комментария ToBeClever. Немного изменив это, сделали свое дело:

@echo OFF

setlocal ENABLEEXTENSIONS
set KEY_NAME=HKEY_CURRENT_USER\Software\Microsoft\Command Processor
set VALUE_NAME=DefaultColor

FOR /F "tokens=1-3" %%A IN ('REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul') DO (
    set ValueName=%%A
    set ValueType=%%B
    set ValueValue=%%C
)

if defined ValueName (
    @echo Value Name = %ValueName%
    @echo Value Type = %ValueType%
    @echo Value Value = %ValueValue%
) else (
    @echo %KEY_NAME%\%VALUE_NAME% not found.
)
4
niels

Это работает, если значение содержит пробел:

FOR /F "skip=2 tokens=1,2*" %%A IN ('REG QUERY "%KEY_NAME%" /v "%VALUE_NAME%" 2^>nul') DO (
    set ValueName=%%A
    set ValueType=%%B
    set ValueValue=%%C
)

if defined ValueName (
    echo Value Name = %ValueName%
    echo Value Type = %ValueType%
    echo Value Value = %ValueValue%
) else (
    @echo "%KEY_NAME%"\"%VALUE_NAME%" not found.
)
4
Andrew S

Отличный уровень решений здесь.

Мое маленькое зерно соли как решение @Patrick Cuff не работало из коробки; У меня было 2 проблемы

  • Я использую Windows 7 => изменено на "skip = 2"
  • В значении параметра реестра есть пробел Value Value = C:\Program Files\...

Вот решение, которое я нашел: взять 4 токена и установить ValueValue в %% C и %% D. (Спасибо @Ivan!)

setlocal ENABLEEXTENSIONS
set KEY_NAME="HKEY_CURRENT_USER\Software\Microsoft\Command Processor"
set VALUE_NAME=DefaultColor

FOR /F "usebackq skip=2 tokens=1-4" %%A IN (`REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul`) DO (
    set ValueName=%%A
    set ValueType=%%B
    set ValueValue=%%C %%D
)

if defined ValueName (
    @echo Value Name = %ValueName%
    @echo Value Type = %ValueType%
    @echo Value Value = %ValueValue%
) else (
    @echo "%KEY_NAME:"=%\%VALUE_NAME%" not found.
)
4
Jean-Francois T.

Чтобы получить конкретный ответ на значение реестра, вы можете использовать следующий запрос:

REG QUERY "Key_Name"/v "Value_Name"/s

например: REG QUERY "HKEY_CURRENT_USER\Software\Microsoft\Command Processor"/v "EnableExtensions"/s

здесь /v: Запросы для определенных значений ключа реестра.

/ s: запрашивает все подразделы и значения рекурсивно (например, dir/s)

0
Ishita Kapur
@echo off
setlocal ENABLEEXTENSIONS
set KEY_NAME=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\awhost32.exe
set VALUE_NAME=Path
for /F "usebackq tokens=3" %%A IN (`reg query "%KEY_NAME%" /v "%VALUE_NAME%" 2^>nul ^| find "%VALUE_NAME%"`) do (
  echo %%A
)

Как вы обрабатываете пробел в переменной %% A? Это приводит к C:\Program. Фактический путь - это C:\Program Files\Symantec\pcAnywhere.

0
Tom

Я сталкивался со многими ошибками на компьютерах с Windows XP при использовании WMIC (например, из-за поврежденных файлов на компьютерах). Поэтому лучше не использовать WMIC для Win XP в коде. Никаких проблем с WMIC на Win 7 все же.

0
unseen_rider

Спасибо, мне просто нужно использовать:

SETLOCAL EnableExtensions

И положить:

2^>nul

В REG QUERY вызывается команда FOR . Еще раз спасибо! :)

0
Fabius

Вы можете получить значение из ключа реестра следующим образом

@echo OFF
setlocal ENABLEEXTENSIONS
set REG_NAME="HKEY_CURRENT_USER\Software\Test"
set KEY_NAME=TestVal

FOR /F "usebackq skip=2 tokens=1-3" %%A IN (`REG QUERY %REG_NAME% /v %KEY_NAME% 2^>nul`) DO (
    @echo %%A : %%C
)
pause

те, кто интересуется, как добавить рег ключи, вот способ.

REGEDIT4

; @ECHO OFF
; CLS
; REGEDIT.EXE /S "%~f0"
; EXIT

[HKEY_CURRENT_USER\Software\Test]
"TestVal"="Succeeded"
0
Sameera R.
echo Off
setlocal ENABLEEXTENSIONS

set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup"
set VALUE_NAME=release 

REG QUERY %KEY_NAME% /S /v %VALUE_NAME%
endlocal

поставить точку\в конце KEY_NAME

0
jacob justin