Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Dos7book

.pdf
Скачиваний:
76
Добавлен:
09.02.2015
Размер:
5.1 Mб
Скачать

Глава 9: Примеры композиции исполняемых файлов

%5 – файл-список имен, выделенных правой кнопкой %6 – буква диска из неактивной панели %7 – путь к каталогу, открытому в неактивной панели

Перечисленные сведения, полученные от файл-менеджера, дополняются теми, которые в файле ARC.BAT будут запрошены у операционной системы. Все они учитываются при проведении проверок с целью выявления обстоятельств, препятствующих успешному осуществлению архивирования. В зависимости от результатов проверок либо будет вызвана программа архивирования, либо на экран будет выведено понятное сообщение об ошибке. Ниже приведен полный текст batch-файла ARC.BAT, содержащий командные строки для выполнения всех необходимых проверок.

@echo off set V1=02

if %1"==ZIP" set V1=Pkzip.exe if %1"==RAR" set V1=Rar.exe if %6"==" set V1=02

if %V1%==02 echo Parameters are invalid or not defined! if %V1%==02 goto END

set V2=08

for %%Z in (%path%) do if exist %%Z\%V1% set V2=%%Z\%V1% rem ================== Line 10 ==================

if %V2%==08 echo The %V1% archiver hasn't been found! if %V2%==08 goto END

set V3=13

for %%Z in (%path%) do if exist %%Z\Find.exe set V3=%%Z\Find.exe if %V3%==13 echo The Find.exe utility hasn't been found!

if %V3%==13 goto END

if %7"==" echo Archive in inactive panel must be closed! if %7"==" goto END

if %4"==.." echo Name for the archive isn't chosen! rem ================== Line 20 ==================

if %4"==.." goto END

%V3% /C /I /V ".%1" %5 | %V3% ": 0" > nul

if not errorlevel 1 echo Chosen file(s) - already %1-archive(s)! if not errorlevel 1 goto END

%V3% /I "%4.%1" %5 > nul

if not errorlevel 1 if %2%3"==%6%7" echo Conflicting filenames! if not errorlevel 1 if %2%3"==%6%7" goto END

ctty nul

%comspec% /f /c copy %V3% %6%7%4.%1 /Y | %V3% "1 f" rem ================== Line 30 ==================

ctty con

– 489 –

Глава 9: Примеры композиции исполняемых файлов

if errorlevel 1 echo Non-writable target disk or overwrite denied if errorlevel 1 goto END

del %6%7%4.%1

if %1==RAR %V2% a -s- -rr -ems- -w%5\.. %6%7%4.%1 @%5 if %1==RAR if errorlevel 1 goto END

for %%Z in (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1) do echo. if %1==ZIP %V2% %6%7%4.%1 -ex -P -wHS -jhsr @%5

if %1==ZIP if errorlevel 1 goto END

rem ================== Line 40 ==================

echo Archive %4.%1 is written into the %6%7 directory. :END

По своей структуре файл ARC.BAT представляет собой просто последовательность проверок. Циклов и подпрограмм в нем нет. Все переходы

выполняются только в случае неисполнения условий проверок и только на единственную конечную метку END. Чтобы было легче искать строки по номерам, каждая десятая строка содержит комментарий с объявлением ее номера.

Первая строка файла ARC.BAT выключает ECHO-флаг, чтобы специально выводимые сообщения не терялись в множестве повторов исполняемых строк. В строках 2 – 7 проверяется значение 1-го формального параметра и наличие значения у 6-го формального параметра. Если эти условия не выполнены, то выводится сообщение о том, что параметры не определены или неверно заданы, и на том исполнение завершается. Но если условия выполнены, то значением переменной V1 становится имя той программы архивирования, которую потом предстоит вызывать.

Следующая проверка в строке 9 выясняет, имеется ли нужная программа архивирования в каком-либо из тех каталогов, пути к которым указаны в значении переменной PATH (2.02-02). Подготовка должного значения переменной PATH входит в число общих условий исполнения batch-файлов, оговоренных во вводной статье к главе 9. Примеры присвоения значений переменной PATH даны во всех комплектах конфигурационных файлов, представленных в этой книге. Однако это не снимает с пользователя ответственности за то, чтобы требуемая программа

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

Далее в 14-й строке аналогичным образом происходит поиск программы FIND.EXE (6.14), которая необходима для проведения нескольких последующих проверок. Если программа FIND.EXE будет найдена, то ее имя вместе с предшествующим полным путем станет значением переменной V3.

– 490 –

Глава 9: Примеры композиции исполняемых файлов

Встроках 17 и 18 файла ARC.BAT проверяется наличие значения у седьмого формального параметра, который должен задавать путь к каталогу, открытому в неактивной панели файл-менеждера. Значение 7-го параметра бывает не определено, когда в неактивной панели открыт не каталог, а другой архив. В таком случае сообщение, выводимое файлом ARC.BAT, укажет на то, что архив в неактивной панели следует закрыть.

В19-й строке проверяется то имя, которое пользователь должен был выделить левой кнопкой "мыши", чтобы оно было присвоено создаваемому архиву. Нередко выделение остается на строке с двумя точками, которая в панелях файл-менеджера Volcov Commander обозначает вышестоящий каталог. В таком случае на экран будет выведено сообщение о неправильном выборе имени будущего архива.

В22-й строке файла ARC.BAT выполняется проверка записей в том файле-списке, посредством которого файл-менеджер должен передать программе архивирования имена архивируемых файлов. Напомним, что значением переменной V3, дважды подставляемым в 22-й строке, является имя файла FIND.EXE с предшествующим полным путем к нему. При первом вызове программа FIND.EXE считает в списке имена файлов, не являющиеся архивами того же вида, какой предстоит создать. Дело в том, что наличие файла-архива в составе группы архивируемых файлов допустимо, но повторное сжатие только архивов бессмысленно: степень сжатия от этого не увеличивается, а надежность сохранения данных снижается. Результат подсчета передается через промежуточное перенаправление, и второй вызов программы FIND.EXE выясняет, не равен ли результат подсчета нулю. Если выяснится, что других файлов в подготовленной группе нет, то исполнение закончится выведением на экран сообщения о том, что выделенные пользователем файлы уже являются архивами желаемого типа.

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

такой ситуации на экран выводится сообщение о конфликте имен в текущем каталоге.

В строке 29 предпринимается попытка записать файл с именем создаваемого архива в тот каталог, куда предстоит поместить создаваемый архив. Обращение к каталогу назначения производится со всеми мерами предосторожности, какие должны быть приняты при обращении к недоступному диску: команда CTTY NUL в 28-й строке предотвратит выдачу панических сообщений, а вызов командного интерпретатора с параметром /f гарантирует безостановочное продолжение исполнения. Напомним, что значение переменной %COMSPEC%, подставляемое в 29-й строке, представляет имя командного интерпретатора с предшествующим

– 491 –

Глава 9: Примеры композиции исполняемых файлов

полным путем к нему, причем оно присваивается переменной %COMSPEC% автоматически при первом запуске командного интерпретатора (6.04).

Попытка записи в 29-й строке может завершиться неудачно, когда в каталоге назначения уже находится одноименный файл, имеющий атрибуты HRS (6.01), а

также когда каталог назначения находится на незаписываемом или на защищенном от записи диске. Исход попытки записи отображается сообщением, которое команда COPY направит в канал STDOUT. Но в 29-й строке оно перенаправлено программе FIND.EXE. Если она зафиксирует неудачу, то исполнение завершится

вследствие невозможности создания архива с заданным именем в указанном каталоге. Если же попытка записи окажется успешной, то записанный файл сразу же будет удален командой DEL (3.09) в 34-й строке. Тем самым будет устранено последнее препятствие, которое могло бы помешать исполнению миссии программы архивирования.

При вызове каждой программы архивирования нужно учитывать, как эта программа выводит на экран свои сообщения. Архиватор RAR.EXE формирует свое экранное поле, не пользуясь каналом STDOUT, и экран потом надо очистить. Но если это сделать командой CLS, то последующее заключительное сообщение

будет выведено в верхней строке экрана и сразу скроется под панелями файл-менеджера. Поэтому после вызова программы RAR.EXE в 35-й строке очистку экрана приходится выполнять смещением курсора на 20 строк вниз командой FOR в 37-й строке. Помимо того, панели файл-менеджера должны быть развернуты не на полную длину. Их длина регулируется "мышью" или клавишами стрелок вверх-вниз в то время, пока удерживаются нажатыми клавиши ALT-F11 или ALT-F12. Установленный размер панелей надо зафиксировать в файле VC.INI нажатием клавишной комбинации SHIFT-F9.

Архиватор PKZIP выводит сообщения через канал STDOUT, и потому его вызов производится в 38-й строке, то есть после очистки экрана. Благодаря всем

выполненным проверкам неудачный исход операций архивирования крайне маловероятен, но вообще исключать его нельзя. На этот случай предусмотрены переходы на конечную метку END со строк 36 и 39, и тогда сообщение об ошибке, выводимое программой архивирования, останется на экране после окончания исполнения команд файла ARC.BAT. А при удачном завершении миссии любого архиватора команда ECHO в 41-й строке выведет на экран финальное сообщение о том, как архив назван и в каком каталоге он создан.

Готовый batch-файл ARC.BAT надо поместить в каталог, путь к которому указан в значении переменной PATH (2.02-02), причем желательно в тот же каталог, где находятся файлы меню файл-менеджера Volcov Commander. Пример текста меню VC.MNU со строками вызова batch-файла ARC.BAT показан в разделе

6.25-02.

– 492 –

Глава 9: Примеры композиции исполняемых файлов

9.03-02 Batch-файл для исследования дисков.

Когда нужно обследовать незнакомый компьютер, то первый вопрос относится к дискам: сколько их и доступны ли они. Существуют программы MSD.EXE (из комплекта MS-DOS6.22) и NDIAGS.EXE (из пакета программ Norton Utilities),

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

Предлагаемый ниже batch-файл назовем его DISK.BAT – выдает краткий, но исчерпывающий отчет о статусе дисков в дисководах. Основная идея состоит в том, чтобы проверить возможность считывания путем считывания метки тома, а затем проверить доступность для записи путем записи той же метки обратно. Такая процедура безопасна, потому что и успех, и неудача операции записи не влекут за собой изменения содержания диска.

С другой стороны, поставленная задача дает повод показать в файле DISK.BAT несколько нетривиальных приемов batch-программирования, в частности:

использование подпрограмм в составе batch-файла;

обеспечение безостановочного тестирования недоступных дисков;

предотвращение выведения нежелательных сообщений;

формирование временных командных файлов;

запись сообщений из канала STDOUT в переменную окружения.

Для упрощения поиска строк в файле DISK.BAT каждая десятая строка содержит комментарий с объявлением ее номера. Кроме того, метки названы по номерам соответствующих строк; например, метка L28 отмечает 28-ю строку, где кончается основная часть программы и начинается одна из подпрограмм.

Ниже следует текст batch-файла DISK.BAT.

@echo off

if %1"==&" if not %2"==" goto L%2 if %Path%"==" %0 & 79 4 PATH

if %Temp%"==" %0 & 79 4 TEMP

Call %0 & 28 A Attrib D Debug F Find L Label if VA"==" goto L87

set V1=%Path% set Path=%1 set V2=%Path%

rem ================== Line 10 ==================

set Path=%V1% set V1=

Call %0 & 39 A B C D E F G H I J K L M N O P Q R S

– 493 –

Глава 9: Примеры композиции исполняемых файлов

if %V1%"==" if not %1"==" %0 & 79 5 if %1"==" set V1=A C D E F G O R ctty nul

%VA% -H -R -S %Temp%\tmp.*

echo e 100 'call %%1 & 46' 20 > %Temp%\tmp.scr echo w >> %Temp%\tmp.scr

rem ================== Line 20 ==================

echo q >> %Temp%\tmp.scr set Dircmd=

for %%Z in (%V1%) do call %0 & 53 %%Z: %1 del %Temp%\tmp.*

ctty con

for %%Z in (A D F L 1 2) do set V%%Z= goto L87

:L28 shift

rem ================== Line 30 ==================

shift set VL=

for %%Z in (%path%) do if exist %%Z\%2.exe set VL=%%Z\%2.exe if %VL%"==" echo Error: the %2.exe utility hasn't been found! if %VL%"==" set VA=

if not %VL%"==" set V%1=%VL% if not %4"==" goto L28

goto L87 :L39

rem ================== Line 40 ==================

shift

if %V2%"==%2" set V1=%2 if %V2%"==%2:" set V1=%2 if not %3"==" goto L39 goto L87

:L46

set V1=%6

if not %7"==" set V1=%6 %7

if not %8"==" set V1=%6 %7 %8

rem ================== Line 50 ==================

if %5"==has" set V1=NO NAME goto L87

:L53

%comspec% /f /c Dir /-p %3\nul > %Temp%\tmp.txt

%VF% "Volume in d" < %Temp%\tmp.txt > %Temp%\tmp.bat if errorlevel 1 %0 & 79 6 %3 %4

%VF% "Directory of " < %Temp%\tmp.txt

– 494 –

Глава 9: Примеры композиции исполняемых файлов

if errorlevel 1 %0 & 79 7 %3

%VF% "0 bytes free" < %Temp%\tmp.txt

rem ================== Line 60 ==================

if not errorlevel 1 %0 & 79 8 %3 %VD% %Temp%\tmp.bat < %Temp%\tmp.scr call %Temp%\tmp.bat %0

set V2=if errorlevel 20 del %Temp%\tmp.bat

%comspec% /f /c for %%Z in ("%VL% %3%V1%" "%V2%") do %%Z %VF% "Volume Seria" < %Temp%\tmp.txt

if errorlevel 1 if not exist %Temp%\tmp.bat %0 & 79 9 %3 if errorlevel 1 if exist %Temp%\tmp.bat %0 & 73 1 %3

if not errorlevel 1 if not exist %Temp%\tmp.bat %0 & 73 2 %3 rem ================== Line 70 ==================

if not errorlevel 1 if exist %Temp%\tmp.bat %0 & 73 3 %3 goto L87

:L73

if %3"==1" if %3"==A:" echo Disk %4 (%V1%) is writable > con

if %3"==1" if not %3"==A:" echo Disk %4 (%V1%) is a RAM-disk > con if %3"==2" echo Disk %4 (%V1%) is write-protected > con

if %3"==3" echo Disk %4 (%V1%) is writable > con

Dir /a:ARD /-p /v %4\ | %Dsk%\DOS\MS7\Find.exe "otal d" > con :L79

rem ================== Line 80 ==================

if %3"==4" echo The %4 variable is not defined

if %3"==5" echo Wrong parameter, it must be a letter-name or none

if %3"==6" if not %5"==" echo Letter %4 doesn't refer to a disk > con if %3"==7" echo Disk %4 has no media inside > con

if %3"==8" echo Disk %4 is probably a CD-ROM (no free space) > con if %3"==9" echo Disk %4 is not formatted > con

:L87

Вторая строка в файле DISK.BAT проверяет значение 1-го параметра. Если это значение амперсанд, то выполняется переход, а если нет, то будет продолжено исполнение основной части программы. Обратите внимание еще на то, что адрес перехода ("goto L%2") не фиксирован, а зависит от второго параметра. Такое

построение позволяет включить несколько подпрограмм в состав основного batch-файла, иначе пришлось бы использовать отдельные файлы для каждой подпрограммы.

Команды в строках 3 – 22 выполняют подготовительные операции. Сначала проверяется наличие значений у переменных PATH и TEMP: первая из них должна указывать путь к файлам MS-DOS7, а вторая к каталогу для временных файлов.

– 495 –

Глава 9: Примеры композиции исполняемых файлов

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

Следующая проверка в строке 5 вызывает подпрограмму, размещенную начиная со строки 28. Она должна записать в переменные окружения пути к каждому файлу, который потребуется при исполнении файла DISK.BAT. Имена этих файлов перечислены там же, в строке 5. Имена будут переданы подпрограмме через ее формальные параметры. Основная операция извлечения нужного пути из значения переменной PATH выполняется в 33-й строке. В случае неудачи из 34-й строки выводится сообщение об ошибке. Пока перечень формальных параметров не опустеет, из 37-й строки будет происходить переход на начало подпрограммы, на метку L28, чтобы найти путь к следующему файлу. В результате пути к файлам

Attrib.exe, Debug.exe, Find.exe, Label.exe станут значениями переменных окружения

VA, VD, VF и VL соответственно.

После возврата из подпрограммы продолжится исполнение операций в строках 7 – 11, где буква диска, которая может быть задана пользователем в командной строке, преобразуется в заглавную. Однако вместо буквы диска по ошибке может быть указан иной знак. На этот случай предусмотрен вызов в 13-й строке еще одной подпрограммы, которая размещена в строках 39 – 45 и проверяет знак на принадлежность к списку букв. Если знак будет отвергнут, то исполнение завершится переходом от 14-й строки к метке L79 и выдачей сообщения об ошибке. Если заданная пользователем буква имеется в списке, то она станет значением переменной V1, и тогда далее будет исследован только этот диск. Если же буква диска в строке вызова файла DISK.BAT вообще не была указана, то будет исследована группа дисков, буквенные обозначения которых станут значением переменной V1 в 15-й строке.

При исследовании дисков в каталоге для временных файлов придется создавать три файла: TMP.SCR, TMP.TXT, TMP.BAT. Чтобы гарантировать беспрепятственное создание временных файлов, операция в строке 17 снимает атрибуты с одноименных файлов, которые к тому моменту могут существовать. Напомним, что значением переменной VA, подставляемым в 17-й строке, является имя программы ATTRIB.EXE с полным предшествующим путем. Первый из временных файлов – TMP.SCR – создается перенаправлениями в строках 18 – 21; содержание и назначение этого файла будут пояснены позднее.

Команда FOR в 23-й строке запускает основной цикл исследования дисков, представленных значением переменной V1. Собственно исследование выполняет подпрограмма, размещаемая в строках 53 – 72. Вызов этой подпрограммы для исследования одного диска выглядит так:

– 496 –

Глава 9: Примеры композиции исполняемых файлов

call %0 & 53 %%Z: %1

где слово "call" означает команду возврата в тот же цикл FOR по окончании каждого предыдущего исследования. Параметр "%0" означает подстановку имени исполняемого batch-файла: DISK.BAT или другого, если он будет назван иначе. Параметры "& 53" направляют переход, выполняемый из второй строки, на метку L53. Вместо параметра %%Z: команда FOR подставит букву того конкретного диска, который должен быть исследован при данном вызове подпрограммы L53.

Обратите внимание, что до входа в цикл FOR, в 16-й строке стоит команда CTTY NUL (3.07), которая разрывает все принимаемые по умолчанию связи функций ввода-вывода с клавиатурой и дисплеем. С этого момента будут действовать только те связи, которые указаны явно. Разрыв принимаемых по

умолчанию связей позволит избежать появления на экране бесчисленных сообщений об ошибках при попытках доступа к недействующим и несуществующим дискам. Однако для отслеживания ошибок набора самого файла DISK.BAT выведение сообщений об ошибках может быть полезным, и тогда команду CTTY NUL надо будет временно сделать недействительной, поставив перед ней в той же 16-й строке команду REM (3.24). Когда Вы будете уверены, что ошибок набора нет, тогда исходный вид 16-й строки можно будет восстановить.

Подпрограмма исследования диска начинается с метки :L53. Первая проверка производится в 54-й строке и начинается с команды

%Comspec% /f /c Dir /-p %3\nul

где слово "%Comspec%" при исполнении заменяется значением переменной COMSPEC, то есть именем используемого командного интерпретатора с полным предшествующим путем к нему. Следовательно, каждая проверка начнется с загрузки еще одного резидентного модуля командного интерпретатора. Передаваемый ему параметр "/f" заставит его работать безостановочно, автоматически отвечая "FAIL" на все вопросы, которые могут возникнуть при неудачных попытках доступа. Параметр "/c" означает, что загружаемый резидентный модуль должен будет исполнить только одну команду "DIR", и потом сразу выгрузиться из памяти, возвратив управление для продолжения исполнения файла DISK.BAT. Сообщение, которое резидентный модуль пошлет в канал STDOUT, в 54-й строке перенаправлено во временный файл TMP.TXT.

Содержание временного файла TMP.TXT проверяется программой FIND.EXE четыре раза: в 55-й, 57-й, 59-й и 66-й строках. Напомним, что имя программы FIND.EXE вместе с путем к ней вводится в эти строки путем подстановки значения переменной VF. Первая проверка выявляет несуществующие диски, вторая случаи отсутствия сменного диска в дисководе, третья проверка выявляет оптические дисководы (CD-ROM). Если условия проверки не выполнены, то

– 497 –

Глава 9: Примеры композиции исполняемых файлов

происходит переход на метку L79, где на экран выводится соответствующее сообщение. Через первые три проверки пройдут только те диски, которые существуют, вставлены в дисковод и не являются оптическими дисками CD-ROM.

Строка, выделенная программой FIND.EXE при первой проверке в 55-й строке, записывается во временный файл TMP.BAT; его содержимое, к примеру, может выглядеть так:

Volume in drive D is EXTENDED1

После первых трех проверок, в 62-й строке, содержимое файла TMP.BAT передается как данные отладчику DEBUG.EXE, который принимает команды из заранее созданного временного файла TMP.SCR. Файл TMP.SCR, созданный посредством перенаправлений из строк 18 – 21, содержит следующее:

e 100 'call %1 & 46' 20 w

q

Первая команда "e 100" (6.05-05) из файла TMP.SCR заставляет отладчик DEBUG.EXE перезаписать начальную часть загруженной в него строки данных, которая тогда принимает следующий вид:

call %1 & 46 ve D is EXTENDED1

Вторая команда "w" (6.05-19) из файла TMP.SCR заставляет отладчика DEBUG.EXE записать измененную строку данных обратно в файл TMP.BAT, а третья команда из файла TMP.SCR закрывает сеанс работы с отладчиком

DEBUG.EXE.

После внесенных изменений в файле TMP.BAT оказывается команда CALL (3.02) командного интерпретатора COMMAND.COM, в результате исполнения которой будет вызвана программа, заданная значением первого параметра %1. Это так и происходит, когда в 63-й строке файл TMP.BAT ставится на исполнение, причем его первым параметром становится параметр %0 batch-файла, то есть сам файл DISK.BAT. Таким образом, в 63-й строке происходит рекурсивный вызов файла DISK.BAT, но при этом второй параметр задает переход из второй строки на метку L46, а 6-й параметр метку тома испытуемого диска. Далее команды, показанные в строках 47 – 51 файла DISK.BAT, заменяют прежнее значение переменной окружения V1 меткой тома испытуемого диска. Тем самым миссия подпрограммы L46 оказывается выполненной, и интерпретатор возвращается к исполнению строки 64 подпрограммы L53.

Команда в строке 64 файла DISK.BAT подготавливает значение переменной V2 с единственной целью: избежать переноса строки 65, которая иначе была бы слишком длинной. Цикл FOR в 65-й строке исполняет две операции, определяемые

– 498 –

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]