Вопрос или проблема
Мне нужно получить значение из ключа реестра и сохранить его в переменной, используя пакетный файл.
Я написал базовую команду, чтобы проиллюстрировать свою логику (используя echo вместо установки переменной):
for /f "tokens=3 delims= " %%a in ('reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "LastUsedUsername" ^|findstr /ri "REG_SZ"') do echo=%%a
Я ожидаю, что имя пользователя будет выведено на экран, но этого не происходит.
Я уверен, что значение реестра “LastUsedUsername” не пустое, в нем действительно есть данные.
Кроме того, разделитель — это табуляция, а не пробелы.
РЕДАКТИРОВАТЬ
Если я просто набираю
reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "LastUsedUsername"
… это возвращает:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon
LastUsedUsername REG_SZ Администратор
Этот код
reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "LastUsedUsername" ^| findstr /ri "REG_SZ"
… возвращает:
LastUsedUsername REG_SZ Администратор
Затем, когда я использую команду for, я просто не получаю вывода от echo.
Вам не нужен переключатель delims вообще, поскольку по умолчанию используется пробел, который и возвращает reg query. Создавая bat-файл с этим циклом for и реестром на ключе, с которым я работаю, я получаю правильный echo, в моем случае значение “Red” цвета фона RGB равно 55:
for /f "tokens=3" %%a in ('reg query "HKCU\Control Panel\Colors" /V Background ^|findstr /ri "REG_SZ"') do echo %%a
Одобренный ответ не верен в некоторых ситуациях – если значение, прочитанное из реестра, содержит пробелы (Program Files (x86)), то возвращается только первая часть значения (‘Program’).
То, что я разработал, это:
FOR /F "tokens=2* skip=2" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion" /v "CommonFilesDir"') do echo %%b
Результат C:\Program Files\Common Files
Синтаксис команды DOS верен. Я бы поставил под сомнение наличие у вас правильного значения ключа реестра. Просто введите часть req query… в командной строке и посмотрите, что она возвращает. Я использую Win 7, и я не нахожу ключа, LastUsedUsername, определенного в HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon
setx может сделать то, что вам нужно, без необходимости в скрипте:
setx DefaultUserName /k "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName"
Примечание: Переменную нельзя использовать в текущем сценарии команды, так как она задается в окружении пользователя, а не в текущем окружении. Проверьте с помощью
echo %DefaultUserName% (не работает OOTB, но будет работать в новом окне cmd)
reg query "HKCU\Volatile Environment" /v "DefaultUserName" (не работает)
reg query "HKCU\Environment" /v "DefaultUserName" (работает)
Эта короткая процедура назначит тип и значение reg на: getkeytype/ getkeyvalue
и установит errorlevel и errror value, если не найдено, вот три примера использования:
@echo off
setlocal enableextensions enabledelayedexpansion & REM для получения значения var при exec с !varNm!
call :SUBGETKEY HKLM\SOFTWARE\Microsoft\nonExistantKey /v nothing
echo Err:%errorlevel%, Type:!getkeytype!, Value:!getkeyvalue!
call :SUBGETKEY "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "defaultUsername"
echo Err:%errorlevel%, Type:!getkeytype!, Value:!getkeyvalue!
call :SUBGETKEY "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "Shutdownflags"
echo Err:%errorlevel%, Type:!getkeytype!, Value:!getkeyvalue!
pause
goto :FIN
:SUBGETKEY
set SubKeyParam= %*& rem получить параметры, добавить пробел, чтобы не было пустоты
REM запрос GETKEY, возвращает: getkeytype, getkeyvalue
rem если не найдено: errorlevel установлен, и "error" на переменных
set getkeyaux=error error& REM значения возвращаемых значений по умолчанию не найдены
FOR /F "tokens=2* delims=_" %%A IN ('REG.EXE QUERY %SubKeyParam% 2^>nul') DO (
set getkeyaux=REG_%%A%%B
)
rem echo -%errorlevel%-!getkeyaux!-
for /f "tokens=1*" %%I in ("!getkeyaux!") do (
set getkeytype=%%I
set getkeyvalue=%%J
) & rem {call} устанавливает ERROLEVEL 1, иначе {call } устанавливает ERROLEVEL 0
if %getkeytype%==error (CALL) else (CALL )
goto :FIN
:FIN
Ответ или решение
Для экспертов в области информационных технологий работа с реестром Windows зачастую является обычной практикой. Вопрос о том, как извлечь значение из реестра Windows и сохранить его в переменной с помощью пакетного файла, требует комплексного подхода и детального понимания синтаксиса командной строки Windows. Рассмотрим эту задачу с использованием подхода "ТЕА" (теория, пример, применение), чтобы детально понять, как это можно реализовать.
Теория
Реестр Windows — это иерархическая база данных, используемая ОС для хранения низкоуровневых настроек системы и приложений. Для извлечения данных из реестра обычно используется команда reg query
, а для обработки этих данных в пакетных файлах часто применяется цикл for
.
Команда reg query
позволяет выполнять запросы к определенному ключу реестра и извлекать значения. В своей основе команда возвращает информацию в формате, который включает полное имя ключа, имя значения, тип данных (например, REG_SZ
), и само значение.
Цикл for
в пакетных файлах может принимать результаты других команд, выполняемых в командной строке, и обрабатывать их. Параметры tokens
и delims
используются для разбора выходных данных. Tokens
указывает, какие элементы строки использовать, а delims
определяет разделители.
Пример
Рассмотрим вопрос, как извлечь и сохранить в переменной имя последнего использованного пользователя в Windows с помощью пакетного файла. Известно, что нужное значение содержится по пути HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon
с именем LastUsedUsername
.
Ваш код изначально выглядел так:
for /f "tokens=3 delims= " %%a in ('reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "LastUsedUsername" ^|findstr /ri "REG_SZ"') do echo=%%a
Эта команда должна была вывести значение "LastUsedUsername", но, по словам автора, она не выдавала ожидаемого результата. Причина в неверно указанных разделителях и потенциальных проблемах с разбором строки.
Применение
Теперь исправим код, чтобы он правильно обрабатывал вывод команды reg query
:
@echo off
setlocal
for /f "tokens=3*" %%a in ('reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v "LastUsedUsername"') do (
set LastUsedUsername=%%b
)
echo Last Used Username: %LastUsedUsername%
endlocal
Объяснение
-
Региональное окружение и переменные: Команда
setlocal
используется для того, чтобы изменения окружения (такие как установка переменных) были локальными для скрипта. -
Использование
tokens
иdelims
: Параметрtokens=3*
важен, так как он указывает на использование третьего поля и всех остальных, если значение содержит пробелы. Таким образом, если имя пользователя состоит из более чем одного слова, весь остаток строки будет захвачен. -
Сохранение и вывод значения: Мы сохраняем извлеченное значение в переменной
LastUsedUsername
и затем выводим его с помощью командыecho
.
С помощью этого подхода можно легко адаптировать скрипт для извлечения других значений из реестра, изменяя путь к ключу и имя значения.
Это метод программирования позволяет автоматизировать задачи администрирования и мониторинга, которые очень ценны в больших корпоративных IT-инфраструктурах, предоставляя быстрый доступ к критически важной информации.
В итоге, такой детальный подход не только решает вашу непосредственную задачу, но и предоставляет гибкий механизм для работы с любыми данными реестра в Windows через пакетные файлы.