Запрос одной строкой на REG QUERY

Тема в разделе "Пакетные файлы CMD, BAT", создана пользователем bob_plus, 19 ноя 2017.

  1. bob_plus

    bob_plus Новый пользователь

    Сообщения:
    12
    Симпатии:
    2
    Не могу придумать как одной строкой вывести из REG QUERY значение
    параметра в тех случаях, когда имеется несколько параметров, имена которых
    включают искомое мной Hidden:
    Hidden
    SuperHidden
    ShowSuperHidden

    Пробовал
    и так:
    Код (DOS):

    For /F "UseBackQ Tokens=1,2,3*" %%i In (`REG QUERY "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"^| Find /I "Hidden"`) Do (set hidFilePhold=%%i%& echo %%j% & set hidFilePhold=%%k%)
    и так:
    For /F "UseBackQ skip=2 Tokens=1,2,3" %%i In (`REG QUERY HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /f Hidden /t REG_DWORD /c /e`) Do set hd=%%i% &echo %%j% & set hidFilePhold=%%k%
     
    ECHO исполняет, а SET - нет.

    Не могу допереть как это записать: "масла в башне" не достает...:Dash1:
     
    Последнее редактирование модератором: 21 ноя 2017
    Кирилл нравится это.
  2. Лучший ответ:
    Post #2 by Dragokas, 19 ноя 2017
  3. Dragokas

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    5.341
    Симпатии:
    5.248
    Лучший ответ
    Здравствуйте, bob_plus !
    Добро пожаловать на SafeZone !

    Set работает, как положено.

    Если вы раскрываете переменную, которой было присвоено значение в том же блоке (скобки или однострочная команда), то получите старое значение (до входа в блок),
    если только не воспользуетесь:
    1) отложенным раскрытием - через знаки !, например:
    Код (Text):

    !variable!
     
    Для этого сперва нужно включить режим:
    Код (Text):

    SetLocal EnableDelayedExpansion
     
    Внимание! Все литералы "!" будут игнорироваться в коде, т.к. примут синтаксическую форму спец. символа.
    2) Через call с обрамлением переменной двойными процентами:
    Код (Text):

    call echo %%variable%%
     
    3) Через переход в другую подпрограмму командой call и раскрытием переменной за пределами блока.

    Подробнее в этой статье: https://safezone.cc/threads/cmd-setlocal-i-rasshirennaja-obrabotka-komand.22629/

    Обратите внимание, что это ненадёжный способ. У меня может не быть ни одного параметра, быть только один, или имена параметров могут быть расположены в другом порядке. Реестр не выполняет сортировку имён.

    Поэтому, вы конечно можете поместить весь код в одну строку.
    Тем не менее, наиболее надёжным вариантом будет такой:
    Код (DOS):
    @echo off
    SetLocal EnableExtensions
    set Hidden=0x0
    set SuperHidden=0x0
    set ShowSuperHidden=0x0
    For /f "tokens=2*" %%a in ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Hidden') do set Hidden=%%b
    For /f "tokens=2*" %%a in ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v SuperHidden') do set SuperHidden=%%b
    For /f "tokens=2*" %%a in ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v ShowSuperHidden') do set ShowSuperHidden=%%b
    set h=%Hidden%,%SuperHidden%,%ShowSuperHidden%
    echo %h%
    pause
     
    Последнее редактирование: 19 ноя 2017
    bob_plus и Кирилл нравится это.
  4. bob_plus

    bob_plus Новый пользователь

    Сообщения:
    12
    Симпатии:
    2
    Спасибо за быстрый ответ и, главное, - растолкования! И за статью тоже! Поиск однострочного решения связан с тем, что этот цикл входит в "этажерку" других команд типа FOR, или IF, организующих ветвления для разных версий ОС и пр. зависимостей. Но вообще я искал единственное совпадение. Догнал в различии выгрузки из запроса REG QUERY с разными ключами. Однако мучают смутные сомнения по корректности использования одинаковых имен переменных и имен ключей/параметров в реестре. Hidden - это имя ключа/параметра, а здесь еще и переменная, хотя это и удобно. На сколько безопасно?
     
  5. Dragokas

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    5.341
    Симпатии:
    5.248
    Переменная процесса CMD и имя параметра в реестре никак не будут конфликтовать между собой.
    В таком случае можно проще, даже без раскрытия переменной:

    (учтите, что эти настройки также могут быть заданы в кусте HKLM. (для всех пользователей)

    Код (Text):

    @echo off
    SetLocal EnableExtensions
    :: убеждаюсь, что переменная пуста
    set "Hidden="
    (
      For /F "Tokens=2*" %%i In ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"^| Find /I "Hidden"') Do if "%%j"=="0x1" set Hidden=true
      For /F "Tokens=2*" %%i In ('REG QUERY "HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"^| Find /I "Hidden"') Do if "%%j"=="0x1" set Hidden=true
      if defined Hidden echo Есть по крайней мере одна настройка Hidden !!!
    )
    pause
     
    Дополнительные скобки добавлены для наглядности, что это будет работать и внутри блока (например, другой цикл).
     
    Кирилл и bob_plus нравится это.
  6. bob_plus

    bob_plus Новый пользователь

    Сообщения:
    12
    Симпатии:
    2
    Спасибо! Это - то, что нужно: пример синтаксиса! А какую роль играют двойные кавычки в set "Hidden=" ?
     
  7. Dragokas

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    5.341
    Симпатии:
    5.248
    Для надёжности.
    На некоторых форумах движок сам подставляет пробелы в конец строк.
    Иногда после вставки в редактор бывают проблемы.
    Иногда, автору скрипта нужно специально присвоить переменной именно пробел, но без кавычек это не всегда очевидно.
     
    Кирилл и bob_plus нравится это.
  8. bob_plus

    bob_plus Новый пользователь

    Сообщения:
    12
    Симпатии:
    2
    А можно двумя словами сформулировать "заповеди" передачи данных из цикла в др. команды? Я зачастую не врубаюсь в то, что цикл передает через DO, и передает ли. :Dash1: Как можно продетектировать процесс? Посмотреть визуально где-нибудь в
    файле. Как продублировать вывод ? Какую роль играют двойные кавычки: Do if "%%j"=="0x1". Почему set Hidden=true срабатывает, а set Hidden=%%j - нет?
    Т.е. set "Hidden=" - это объявление переменной с пустым значением, и/или здесь уже объявлен скрытый пробел?
     
  9. Dragokas

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    5.341
    Симпатии:
    5.248
    Вернее сказать, удаление переменной окружения процесса.

    В принципе всё рассказано в статье: https://safezone.cc/threads/cmd-setlocal-i-rasshirennaja-obrabotka-komand.22629/

    - В однострочных командах (когда команд 2 и больше и они объединены через знак & ) - в вашем случае это цикл do команда1 & команда2
    а также:
    - в блоках (всё, что начинается со скобки) - в вашем случае тоже может быть цикл, если после do открыть скобку и записать команды в несколько строк.
    все переменные окружения виртуализируются, т.е. сохраняется их исходное значение. Вы находитесь в "песочнице", пока не выйдите за пределы блока, где значения актуализируются.
    Актуальное значение, тем не менее, можно получить внутри блока. Как? Я показывал в посте #2.

    Переменная цикла %%буква к этим понятиям не относится. Она раскрывается в значение текущей итерации цикла по правилам, указанным вами после слова for.
    О правилах работы цикла можно почитать в этой статье: https://safezone.cc/threads/ciklicheskie-operacii-i-primery-komanda-for.27784/

    Можно убрать/закомментировать @echo off
    Можно поставить команду pause внутрь цикла, если задачей является проследить каждую итерацию цикла.
    вывод на экран - echo %%буква
    Можно выставить пустой разделитель "delims=", чтобы увидеть полностью ту строку, которая попадает под синтаксический разбор циклу.
    Если батник "падает", можно запустить его из-под командной строки - Win + R, cmd (опять же, убрав @echo off). Детальнее: см. статью: https://safezone.cc/threads/kak-dia...i-v-sintaksise-kogda-bat-fajl-vyletaet.22870/ При этом, в батнике не должно быть команды exit (допускается exit /b)

    В данном конкретном случае по привычке, и просто для наглядности.
    Ну а в случае, если бы это была обычная переменная, а не переменная цикла, то для защиты от пустого операнда.

    Почему вы так решили?
     
  10. bob_plus

    bob_plus Новый пользователь

    Сообщения:
    12
    Симпатии:
    2
    > удаление переменной
    Смутило то, что не объявленная ранее переменная очищается, и наличие кавычек: подумал, что там есть что-то, чего я не знаю...
    > однострочных командах (когда команд... и далее.
    Каскадирование команд знакомо. Ищу способ понимать ситуацию, когда интерпретатор просто "вываливается ничего не сообщая". Иногда дохожу до приличного тупизма, упираясь в такой ситуации, а "перетереть" сюжет не с кем. Случается рассказываешь ситуацию, иногда абсолютно далекому от темы человеку, и в процессе рассказа допираешь до ответа. Вот про iPhone сколько угодно и много с кем, а про Batch - увы...
    > для защиты от пустого операнда
    Если не очень надоел: что подорозумевается под пустым операндом, для каких целей от него защищают, и каким образом организуется защита от него?
    >Почему set Hidden=true срабатывает, а set Hidden=%%j - нет?
    Пробовал.
    Есть ли по Вашему представлению удобная бесплатна среда отладки Batch (аля CRM) ? Консоль в SciTE и NotePad++ как-то не очень... Или мне пока это криворуко... Занимаюсь скриптами эпизодически, а память уже садиться...
    Спасибо !
     
  11. Dragokas

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    5.341
    Симпатии:
    5.248
    Среды разработки под него нету.
    Я пользуюсь модифицированным AkelPad, см. скрин. По Ctrl + F5 из него можно вызвать файл на исполнение (не зависимо, что это за файл .cmd, .js и т.п.). Но многие работают в Notepad++ подобным образом. Вот здесь был опрос.

    Поскольку я даю код как пример, то могу предположить, что его вставят в другой код, где нет гарантии, что такая переменная ранее не объявлялась, а это напрямую повлияет на логику приведённого кода (команду If defined), т.к. она как раз и сообщает результат о том, объявлена переменная или нет.

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

    If Операнд1==Операнд2

    Если одного из операндов не будет, исполнение пакетного файла "упадёт".
    Пример:

    If %v%==1 echo .....

    если v пуста, поэтому для надёжности нужны кавычки:

    if "%v%"=="1" echo ....

    если v пуста превратится в:

    if ""=="1" echo ....

    и не "упадёт".
     
  12. bob_plus

    bob_plus Новый пользователь

    Сообщения:
    12
    Симпатии:
    2
    > Среды разработки под него нету.
    Очень жаль, что не случилось приятной неожиданности: все время предугадываю результат...
    >...что такая переменная ранее не объявлялась...
    Значит это-таки - очистка переменной. Или ликвидация?
    Про кавычки попробую "пожувать" себе эту идею: что смогу полезного для себя извлечь из такого применения... Спасибо!
    >...если v пуста превратится...
    Значит это - про операцию сравнения. С этого боку я на этот сюжет не заглядывал. Просто ОГРОМНОЕ СПАСИБО!
    Ваш ответ - класс!
    СПАСИБО!
    К стати, русский язык у Вас, в общем, аккуратный, в отличие от многих московских журналистов, или стрингеров из Интернетовских СМИ. Не без ошибок (я не про "очепятки")... Но вполне.., в отличие от них. Если еще учесть, что здесь у нас с Вами - "междусобойчик". Даже приятно заметить.
     
    Кирилл нравится это.
  13. Dragokas

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    5.341
    Симпатии:
    5.248
    Честно говоря, не изучал этот вопрос на практике. Но мне интересно проверить, т.к. в заначке лежит черновой вариант статьи на эту тему.
    Давайте посмотрим.
    Код (Text):

    set ZZZ=1
     
    В SysInternals Process Explorer => CMD => Properties => Environment видим ZZZ
    Код (Text):

    set ZZZ=
     
    Снова открываем Process Explorer, там ZZZ пропадает.
    Смотрим документацию: https://msdn.microsoft.com/en-us/library/ms686206.aspx
    Так что нет, Microsoft пишет, что пустых переменных окружения не бывает вообще.
    А на счёт конфликтов имён - да, конфликты бывают, между переменными в CMD и переменными окружения, которые в системе.
    Например, если вы измените переменную path, то из-под этого же батника уже не сможете вызвать ни одну утилиту, хранящуюся в папке C:\Windows\System32.
    Список переменных окружения процесса можно получить командой: set

    Ну а если более детально интересует, то лучше поговорить в отдельной теме.

    Если это параметр какой-либо функции, то кавычки тоже важны и не помешают, например,

    if exist "файл" - для пустой переменной, если бы не было кавычек, то батник бы "сломался". Кроме того, здесь кавычки ещё и для защиты от пробелов в имени файла, иначе батник распознал бы вторую часть (после пробела) как следующую команду.

    Также кавычки используются для передачи пустого аргумента, например, если вам нужно передать второй аргумент, а первый оставить пустым:
    Код (Text):

    call some.bat "" "second"
     
    Спасибо за лестный отзыв.
     
  14. bob_plus

    bob_plus Новый пользователь

    Сообщения:
    12
    Симпатии:
    2
    С пустым значением переменной или аргумента использование кавычек понятно. Но, то хорошо, что вы о них, и о перекрестке переменных среды и скрипта описали: это рассуждение в каких-то ситуациях может избавить от долгих "непоняток".
    "лестный отзыв" - нет, просто константация. Очень важно правильно писать, когда втолковываешь кому-то не простые вещи. А у нас сейчас пацанский "ля-ля" взлетел до преподавания в ВУЗах "бла-бла" и "вау". В результате: не смотря на обычное количество способных и знающих ребят настоящих инженеров крайне мало.
    Попробовать выяснить что-то крайне сложно.
     

Поделиться этой страницей

Загрузка...