Как я могу получить значение ключа реестра из пакетного скрипта? - PullRequest
57 голосов
/ 15 января 2009

Мне нужно использовать команду 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

Ответы [ 16 ]

57 голосов
/ 15 января 2009

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

@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.
27 голосов
/ 03 декабря 2012

Эта работа для меня с переменной, которая содержит пробелы в 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

7 голосов
/ 22 декабря 2011

Основываясь на решении 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) но устраняет большую гибкость, поэтому следует использовать только в конкретных случаях использования.

5 голосов
/ 28 апреля 2014

Я понимаю, что это старый вопрос - но эта однострочная почти такая же, как ваша первоначальная попытка с парой дополнений. Он работает с путями, включая пробелы, и работает как в 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 голосов
/ 04 октября 2012
@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 \

4 голосов
/ 11 декабря 2014

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

Мое маленькое зерно соли в виде раствора @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 голосов
/ 28 ноября 2012

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

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 голосов
/ 01 ноября 2011

По какой-то причине код Патрика Каффа не работает в моей системе (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 голосов
/ 17 февраля 2011

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

! REG.EXE VERSION 3.0

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

skip=2

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

1 голос
/ 01 июня 2017

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...