Поместите вывод запроса reg в переменную

Я немного неопытен с CMD и надеюсь, что кто-то здесь может мне помочь.

В одном из моих старых сценариев установки мне теперь нужно проверить, установлен ли .NET 3.5, а затем либо установить пакет 3.5, либо продолжить работу со сценарием в зависимости от результата.

Теперь у меня возникли проблемы с попыткой проверить установленную версию в моем скрипте.

Я использую этот reg-запрос для поиска установленной версии:

reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP" | Find "3.5"

который выводит одну строку, если установлена ​​версия 3.5, или ничего, если нет:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5

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

К сожалению, что-то вроде:

set DNFound=reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP" | Find "3.5"
if not exist %DNFound%
(
 install framework
)

не работает, потому что вывод не будет сохранен в переменной.

Я немного исследовал и видел, как люди используют цикл в этом формате, чтобы получить отдельные значения из вывода запроса reg в переменную (пример кода):

 for /f "tokens=3" %%x in ('reg query HKLM\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile /v EnableFirewall') do set FWSTATUS=%%x

Однако я получаю синтаксическую ошибку, когда пытаюсь сделать то же самое из-за части | Find "3.5" в моем запросе на регистрацию.

Поскольку задействован второй экземпляр cmd.exe, вам нужно экранировать символ вертикальной черты с помощью знака вставки ^|, вы также должны перенаправить поток ошибок на nul 2^>NUL.

user6811411 03.05.2019 10:41

Спасибо за советы, я избежал символа трубы и заработала команда. При этом я обнаружил, что мой мыслительный процесс неверен, и я не проверяю здесь, существует ли переменная, а существует ли содержимое переменной. Так что мне все равно придется идти другим путем.

NickHH45 03.05.2019 11:11

Я просто подумал добавить, что ваш вопрос кажется немного странным, поскольку v3.5 является неотъемлемой частью ОС из Windows 7, что означает, что вам нужно будет проверять его только в том случае, если ОС было не менее 10 лет, (от XP до Vista/Server 2008 R2).

Compo 03.05.2019 13:55

Почти на всех наших рабочих станциях W10 установлена ​​только .NET 4.0 и выше.

NickHH45 03.05.2019 15:23

В каждой версии Windows, начиная с Windows 7, (что означает каждую из ваших рабочих станций с Windows 10), уже установлена ​​минимальная версия 3.5. Ваша задача неактуальна, так как нет необходимости устанавливать его ни на один из них.

Compo 03.05.2019 15:52

См. softwareengineering.stackexchange.com/a/149140/296373

DodgyCodeException 03.05.2019 16:37

Я могу со 100% уверенностью сказать, что на наших рабочих станциях W10 не установлено 3.5. По какой-то причине мы хотим свести использование приложений версии 3.5 к минимуму. Только определенные рабочие станции в финансовом секторе нуждаются в приложениях, требующих 3.5

NickHH45 06.05.2019 08:34
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
2 806
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я бы посоветовал вам использовать errorlevel, чтобы определить, успешно ли возвращена строка.

reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP" | Find "3.5"
if errorlevel 1 install framework

Что происходит, так это то, что find возвращает уровень ошибки 1 (нет совпадения) 0 совпадение найдено. Таким образом, вам не нужно устанавливать переменную.

Вышеупомянутое может быть расширено до нескольких команд:

reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP" | Find "3.5"
if errorlevel 1 (
    echo Framework not found
    install framework
    echo do something else
)

Что касается проблемы с циклом for, как уже упоминал @LotPings в комментарии, вам нужно выйти из канала ^|:

for /f "delims = " %%i in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP" ^| Find "3.5" 2^>nul) do set "var=%%i"
echo %var%

Интересно, что команда set DNFound=reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP" | Find "3.5" устанавливает НЕТDNFound, а всегда возвращает уровень ошибки 1, поскольку запрос команды reg никогда не выполняется (это не bash или powershell)

user6811411 03.05.2019 11:25

Как уже сказал LotPings, установка переменной здесь не дает мне желаемых результатов. Однако мне больше не нужна переменная, и простое удаление "set DNFound = " дает мне нужный результат. Большое спасибо вам обоим. Если бы я знал, как дать вам +Rep, я бы с удовольствием это сделал.

NickHH45 03.05.2019 11:35

@LotPings.. Да, спасибо, что заметили, я забыл удалить часть set.. прямая ошибка копирования/вставки :) Я исправил.

Gerhard 03.05.2019 11:37

@ NickHH45 да, это была ошибка с моей стороны, когда я скопировал вашу команду, включая набор .. Я исправил это сейчас. Нам не требуется набор, мы просто хотим получить результат от find либо errorlevel 1, либо 2

Gerhard 03.05.2019 11:40

В дополнение к вашему вопросу, поскольку он может иметь отношение к будущим пользователям, вы должны иметь возможность выводить все установленные версии, используя метод, аналогичный этому:

@Echo Off
SetLocal EnableDelayedExpansion
Set "rk=HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP"
Set/A "vi=ri=0"

For /F "Tokens=3*" %%A In ('Reg Query "%rk%" /F v /K') Do If "%%B"= = "" (
    If Not "%%~xA"= = "" (Set/A "vi+=1"
        For /F "Tokens=2*" %%C In (
            'Reg Query "%rk%\%%~nxA" /V Version 2^>Nul^|Find /V "\"'
        ) Do Set "_v!vi!=%%D"
    ) Else (Set/A "ri+=1"
        For /F "Tokens=2*" %%E In (
            'Reg Query "%rk%\%%~nxA\Full" /V Release 2^>Nul^|Find /V "\"'
        ) Do Set/A "_r!ri!=%%F"))
If %ri% Gtr 0 (Set/A "vi+=1"
    For /F "Tokens=2" %%A In ('FindStr/B "!_r%ri%!" "%~f0"'
    ) Do Set "_v%vi%=%%A")

If %vi% Gtr 0 For /F "Tokens=1* Delims= = " %%A In ('Set _v') Do Echo([%%B]

Pause
GoTo :EOF

Rem Later Version Table - do not remove
378389 4.5
378675 4.5.1
378758 4.5.1
379893 4.5.2
393295 4.6
393297 4.6
394254 4.6.1
394271 4.6.1
394802 4.6.2
394806 4.6.2
460798 4.7
460805 4.7
461308 4.7.1
461310 4.7.1
461808 4.7.2
461814 4.7.2
528040 4.8
528049 4.8

Когда выходит новая версия, вы просто обновляете содержимое внизу соответствующей информацией, чтобы обнаружение оставалось актуальным.

Другие вопросы по теме