Немного о среде

Переменные среды хранят информацию об особенностях установки, например имя системы (computername), особенности архитектуры операционной системы, 32- или 64-разрядная система (processor_architecture), а также путь поиска, где находятся исполняемые программы (path). Переменные среды можно разделить на три категории: зависящие только от операционной системы (например, только что упомянутые computername, processor_architecture, path), переменные, используемые приложениями независимых поставщиков (в частности, на моей системе QuickTime создает переменную QTJAVA), а также переменные, которые используют командные файлы Windows.

Простота языка программирования не имеет значения (командный язык Windows относится к самым простым), он необходим программистам для получения внутренних данных. Здесь главную роль играют переменные среды. Однако для получения информации о переменных среды нужен инструмент, и таким инструментом является команда Set.

Вот тут читатель воскликнет: «Кто же не знает команды Set!» А на самом деле, знаете ли вы, что эта команда может выполнять арифметические действия, операции с любой частью строковой переменной в существующих переменных среды? Что она упрощает ввод и может генерировать случайные числа? Эти и другие операции можно выполнять с помощью команды Set. Далее я расскажу о двух возможностях, которые предоставляет команда Set.

Генерация случайных чисел

Рассмотрим простой командный файл guessnumber.cmd (листинг 1). Скопируем этот текст в Notepad, сохраним в некоторой папке и назовем его guessnumber.cmd. Теперь открываем командное окно, вводим guessnumber, нажимаем Enter и следуем приглашениям программы. Это простая игра нестрогих рассуждений с использованием догадок, в процессе командный файл выбирает случайное число, запрашивает ответ, какое это число, сообщает, правильный ответ или нет, дает подсказку, больше или меньше ответ, чем загаданное число, и, если число не угадано, повторяет процесс. Игра, может быть, не самая интересная, но она есть в Windows Server 2008 Server Core.

Листинг 1. Guessnumber.cmd

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

set gamevalue=%random%

Главное место в этом коде занимает функция %random% (встроена в командный процессор Windows начиная с Windows 2000 Server), которая генерирует случайные числа в диапазоне от 0 до 32767.

После генерации случайного числа система должна повторить пользователю вопрос для угадывания. До Windows 2000 командные файлы не предлагали полезного способа для запроса ввода (как известно тем, кто пытался задействовать команду Choice). Начиная с Windows 2000 команда Set получила возможность ввода через ключ /p, как видно в следующем операторе:

set/p latestguess=What do you think it is?

Эта команда в общем виде выглядит так:

set/p environmentvariablename= [prompttext]

Здесь видно, что приглашением является вопрос «What do you think it is?». Отмечу, что пробел после вопросительного знака служит для лучшего форматирования. Все, что будет введено в переменную среды, получит название latestguess.

Выполнение арифметических действий

Я отметил выше, что задан диапазон значений (максимальное целое число равно 32768). Изменим правила игры, ограничив пользователя числом попыток не более 16. Необходимо выполнение арифметических действий, чтобы подсчитывать, сколько было предпринято попыток. Результат измененной версии guessnumber отражен в листинге 2. Рассмотрим код guessnumber2.cmd. Видно, что два командных файла имеют различия только в нескольких строках, которые вводят новую переменную среды guessesleft. Я ввел эту переменную, которую помнят все, кто работал с любой операционной системой Microsoft начиная с DOS 2.0:

set guessesleft=16

В этом операторе появляются новые арифметические возможности команды:

set/a guessesleft=%guessesleft%-1

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

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

В тех же случаях, когда не удается достичь желаемой цели с помощью Set, можно задействовать ее усовершенствованную версию — команду Setx.

Для многих пакетных файлов, использующих переменную среды, ее значение устанавливается путем запроса ввода данных пользователем (с помощью переключателя/p, как было показано ранее), либо с помощью простой команды Set:

set myname=Mark

Эта команда работает отлично, но иногда возникает необходимость ввести в переменную среды другие виды информации — в частности, результат выполнения команды (например, время на передачу и подтверждение приема сигнала проверки связи по Ping) или значение параметра реестра.

Уже по меньшей мере в течение 10 лет это позволяет делать инструмент из Resource Kit под названием Setx, который в Windows Vista и более новых версиях уже входит в состав операционной системы. Как будет показано далее, поведение Setx может оказаться несколько нестандартным, но этот инструмент способен составить основу для разработки некоторых мощных пакетных файлов.

Предположим, например, что нам требуется извлечь значение параметра реестра и поместить его в переменную среды. Нужно найти имя организации, на которое зарегистрирована данная копия Windows — для отчета, либо для проверки правильности имени, указанного в реестре. Windows хранит эту информацию в параметре HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\Current
Version\RegisteredOrganization. Приведенная ниже команда

setx regorg/k "HKLM\SOFTWARE\Microsoft\Windows NT\
CurrentVersion\RegisteredOrganization"

позволяет извлечь его значение и поместить в переменную среды.

С помощью Setx можно извлекать данные не только из реестра, но и из других источников. В нашем случае параметр /k направляет поиск в реестр.

На первый взгляд строка в кавычках представляет подраздел реестра, однако это не так. Данная строка содержит комбинацию имени подраздела реестра и имени значимого элемента реестра, чье содержимое требуется сохранить в переменной среды regorg. При успешном выполнении этой команды ее результат выглядит следующим образом:

Extracted value: "MR&D".
SUCCESS: Specified value was saved.

Для Setx не предусмотрен параметр для подавления столь многословного ответа, однако появление на экране лишней информации можно блокировать, перенаправив выход на устройство nul:

setx regorg/k “HKLM\SOFTWARE\Microsoft\Windows NT\
CurrentVersion\RegisteredOrganization” >nul

Итак, в системе появилась переменная среды regorg. Теперь вспомним об упомянутой ранее «странности поведения». По причинам, известным лишь разработчикам Setx, эта команда создает переменную среды и наполняет ее содержимым, но не передает соответствующую информацию той ее копии, которая находится в текущем окне командной строки. Поэтому любая команда, вводимая в окне командной строки, где была введена команда Setx, не сможет увидеть значение, только что созданное для переменной среды. Например, в ответ на ввод set regorg будет выдано сообщение об ошибке: Environment variable regorg not defined («Переменная среды regorg не определена»). Чтобы увидеть новую переменную среды, необходимо открыть второе окно командной строки и ввести там нужную команду.

Тот, кто работает с переменными среды, знает, что одни переменные Windows хранит в профиле системы, другие — в профиле пользователя. В ответ на ввод в командной строке команды set выдаются как системные переменные среды, так и переменные среды из профиля пользователя, без указания их источника. Насколько мне известно, не существует способа применения команды Set, позволяющего вывести только системные переменные среды, либо только переменные среды, относящиеся к пользователю. Однако разницу можно увидеть, если щелкнуть кнопку «Переменные среды» на вкладке «Дополнительно» на странице «Свойства системы» элемента «Компьютер». Параметр /m команды Setx позволяет обеспечить большую степень контроля над создаваемыми переменными среды. Когда используется этот параметр, новая переменная среды сохраняется в профиле системы, а не в профиле пользователя.

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

Марк Минаси (mark@minasi.com) — редактор Windows IT Pro, MCSE и автор книги Mastering Windows Server 2003 (издательство Sybex)