Об утилите LaunchControl для управления параметрами запуска программ ОС DOS и Windows в среде Windows 3.1
PC Magazine/RE logo
(С) СК Пресс 4/96
PC Magazine, October 10, 1995, p. 523

Запускайте - как вам нравится

Дуглас Болинг


Запускайте Windows-программы в полном окне, в свернутом виде... - как угодно.

Точно так же, как PIF Editor позволяет задавать режим выполнения программ DOS, рассматриваемая в этом выпуске утилита предоставит вам возможность выбирать режим выполнения программ DOS и Windows 3.1. Программу LaunchControl образуют две составляющие: редактор ее файлов LCD и драйвер, использующий данные из этих файлов для запуска конкретных программ в выбранном вами режиме.

LaunchControl

Утилита LaunchControl позволяет управлять параметрами запуска программ ОС DOS и Windows в среде Windows 3.1. Она предоставляет вам возможность установить для программ Windows переменные программной среды, а также размер и позицию окна. При запуске программ DOS из среды Windows утилита LaunchControl обеспечивает автоматическое закрытие Windows, выполнение программы и последующий перезапуск Windows.

Вы можете получить утилиту LaunchControl (это и исполнимый модуль, и исходный тест), загрузив ее из сети ZD Net через сети CompuServe, AT&T Interchange или Internet (ftp-сервер ftp.pcmag.ziff.com) либо запросив ее по почте. Для перекомпиляции LaunchControl вам потребуется транслятор, совместимый с Microsoft C 6.0 и позволяющий формировать исполнимые программы Windows.

Использование LaunchControl

Инсталлируйте утилиту LaunchControl, скопировав исполнимый файл LNCHCTRL.EXE в каталог, описанный в предложении PATH вашей системы. Вам также потребуетс создать в окне File Manager ассоциацию для файлов LaunchControl с расширением LCD. Для этого нужно запустить File Manager, выбрать раздел меню File/Associate, ввести в поле расширений LCD и внести в поле имен программ полное название (включая маршрут доступа) файла LNCHCTRL.EXE.

Запустите LaunchControl, выбрав в окне Program Manager пункт меню File|Run и задав имя LNCHCTRL. Если вы не поместили файл LNCHCTRL.EXE в каталог, описанный в предложении PATH, то в имени команды придется указать и маршрут доступа. При желании в окне Program Manager можно предусмотреть пиктограмму для группы LaunchControl.

Подготовка файлов LCD затруднений вызвать не должна. Запустив LaunchControl, вы увидите окно Properties. Внесите в первое поле Command окна LaunchControl имя программы, которую вы хотите запускать с помощью нового файла LCD. Название команды должно содержать все необходимые данные о маршруте доступа и параметры командной строки. У вас есть возможность внести в поле, расположенное сразу под полем Command, название рабочего каталога для программы в результате. LaunchControl до запуска программы переключается в каталог, выбранный в этом поле.

Под полями Command и Directory находится набор панелей. Левая панель позволяет установить параметры LCD для запуска программы: Environment (среда), Window Size (размер окна) и DOS Attributes (атрибуты DOS). По мере того как вы выбираете различные фиксируемые кнопки в левой части окна Properties, содержание ее правой части меняется и в ней индицируются соответствующие органы управления параметрами.

По умолчанию фиксируется кнопка Environment. В этом режиме в окне Properties можно установить переменные программной среды, которые должны использоваться с вашей программой. В случае включения кнопки "Use Def. environment + variables" ("Использовать установленную среду + переменные") при запуске программы будут использоваться заданные переменные среды плюс любые новые переменные, перечисленные в списке ниже. А при выборе кнопки "Use only variables below" ("Использовать только нижеприведенные переменные") запускаемой программе будут придаваться только переменные из списка.

Чтобы ввести новые переменные, следует "нажать" кнопку Change в правой части окна Properties. Появитс диалоговая врезка, которая позволит добавлять, редактировать и удалять переменные программной среды. Комбинированное окно предоставляет возможность вводить новые переменные из списка текущих переменных программной среды. Возможен и ручной ввод - для этого нужно ввести имя, а затем знак равенства и значение новой переменной. Для того чтобы выбрать или ввести новую переменную, "нажмите" на кнопку Add.

Для удаления переменной из списка следует выделить ее и "нажать" кнопку Delete. А для ввода режима редактирования переменной достаточно выделить ее имя в списке и дважды щелкнуть клавишей мыши. После этого переменная будет помещена в окно редактирования дл внесения изменений. По окончании редактировани "нажмите" кнопку Add. При добавлении переменной с таким же именем, как у имеющейся в списке, произойдет замена переменной из списка.

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

Включив в окне параметров Properties кнопку-переключатель Size, вы сможете определить размеры и позицию окна запускаемой программы. При этом в правой части окна Properties сменятся органы управления параметрами - появятся дочернее окно отметки выделения и поля для ввода размеров и расположени окна. Если выбран режим Default, LaunchControl проигнорирует заданные для размера и расположения окна, и будет использовать стандартные (используемые по умолчанию) параметры. Для индикации этого соответствующие поля ввода "отключаются".

Задать свои параметры размеров и расположения окна можно, отменив выбор кнопки Default. Базой отсчета при установке позиции окна являются координаты верхнего левого угла экрана, соответствующие позиции (0,0). Значения координат, а также высоты и ширины определяются в пикселах. Таким образом, ввод значений горизонтальной и вертикальной координат 100 и 200 соответственно означает для утилиты LaunchControl команду на такое размещение окна программы, при котором его верхний левый угол находится на экране в позиции (100, 200).

Если вы хотите ввести только размер окна, а его размещение оставить стандартным, то можете ввести значение одной из координат позиции, равное -1. И наоборот, чтобы задать только расположение, но не размер окна, введите значение -1 в поле его высоты или ширины.

Последний набор рабочих параметров LCD определяет режим обращения к DOS-программам. После выбора параметра DOS Attributes окно Properties будет содержать три органа управления: поле выбора, работу которого я опишу ниже, окно редактирования, позволяющее определить Window Description - описание окна программы, - и пиктограмму DOS-программы, используемую в среде Windows. Введите в поле описания текст, выбранный вами в качестве названия окна и метки пиктограммы. Пиктограмму можно изменить, "нажав" кнопку Set Icon. При этом появится диалоговое окно, очень похожее на окно Change Icon, используемое в режиме Properties окна Program Manager.

Необходимость ввода описания и выбора пиктограммы при запуске программы DOS с помощью утилиты LaunchControl обусловлена невозможностью использовани их вариантов, установленных в Program Manager, - именно потому, что запуск программы DOS производится утилитой LaunchControl, а не Program Manager. Установка отметки в поле, расположенном в верхней части окна управлени параметрами DOS-программы, означает для утилиты LaunchControl команду на выполнение программы вне среды Windows. В этом случае LaunchControl закроет текущую сессию Windows и запустит выбранную программу непосредственно в среде DOS. Если в это время в среде Windows выполняется какая-то другая программа, прекращать работу системы, естественно, нельзя. В этом случае LaunchControl просто прекращает свою работу без запуска DOS-программы.

Если работа Windows была прервана, утилита LaunchControl перезапустит оболочку по окончании работы DOS-программы. Если во время попытки запуска программы с помощью LaunchControl обнаруживается ошибка, то до перезапуска Windows на экран выводится соответствующее сообщение DOS. Заметьте, что после установки отметки в поле Exit Windows остальные органы управления, имеющиеся в окне, отключаются, поскольку не могут относиться к программам, выполняемым вне среды Windows.

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

По завершении ввода параметров программы сохраните введенные значения, выбрав оператор меню File/Save. На экране появится диалоговое окно со стандартным расширением имени файла LCD. Вы можете выбрать любое имя файла, однако в качестве его расширения нужно использовать именно LCD, поскольку для модулей File Manager и Program Manager это служит признаком дл обращения к LaunchControl.

Остальные пункты меню File - New, Open, Save As и Exit - работают стандартным образом. Пункт New обеспечивает ввод стандартных значений параметров в органах управления, чтобы вы смогли заново создать файл LCD. Команда Open открывает файлы LCD дл редактирования, а Save As позволяет сохранить текущие значения параметров в файле с новым именем. Наконец, пункт Exit оканчивает работу с программой.

Сохранив информацию о параметрах запуска в файле LCD, вы сможете использовать этот файл для запуска связанной с ним программы. Выделите файл LCD в окне File Manager и дважды щелкните клавишей мыши - произойдет запуск определенной в этом файле программы с установленными в нем значениями переменных среды, размером и позицией окна.

Вы можете сформировать для файла LCD пиктограмму в окне Program Manager. Выберите пункт меню File|New в окне Program Manager, затем введите вариант Program Item и введите в поле Command Line диалогового окна Program Item Properties имя LCD-файла. Обязательно задайте расширение LCD. По умолчанию для LCD-файла используется такая же пиктограмма, как у связанной с ним утилиты LaunchControl. "Нажав" кнопку Change Icon, ее можно заменить на пиктограмму вызываемой программы. Завершив заполнение всех полей диалогового окна, "нажмите" кнопку OK, и Program Manager образует новый элемент для файла LCD. Двойной щелчок клавишей мыши, курсор которой указывает на пиктограмму этого окна, - и утилита LaunchControl запустит описанную в файле программу с нужными параметрами и затем спокойно завершит работу.

При эксплуатации утилиты LaunchControl имеется одно ограничение: если вы применяете эту утилиту для запуска программы, ориентированной на DOS, то переменные программной среды задать нельзя. Это обусловлено особенностями выполнения DOS-программ в среде Windows. Однако это ограничение можно обойти, запуская с помощью утилиты LaunchControl файл BAT, который, прежде чем вызвать программу, установит нужные значения переменных среды.

LaunchControl изнутри

Для реализации функций утилиты LaunchControl используется несколько методик. Чтобы можно было изменять значения переменных среды, эта утилита запускает программы в обход стандартных функций WinExec или ShellExecute. При установке размеров программного окна LaunchControl определяет момент окончания процесса создания окна, а затем изменяет его размеры. Дл запуска DOS-программ вне среды Windows используетс функция ExitWindowsExec. Рассмотрим эти методики поближе - несмотря на простоту принципов, каждая из них содержит одну-две "хитрости".

Когда я работал над первой версией утилиты LaunchControl, для запуска программы в сочетании с изменением параметров среды я хотел применить функцию LoadModule. Этой функции передаются два параметра: указатели на команду и на структуру, содержащую значение сегмента среды, т. е. указатель командной строки и стандартный параметр ShowWindow, который определяет режим вывода окна запускаемой программы. Однако я был жестоко разочарован, обнаружив, что в отличие от WinExec функция LoadModule не может использоваться для запуска программ DOS!

Решая эту проблему, я обнаружил, или, говоря точнее, заново открыл для себя, тот простой факт, что большинство функций DOS работают и в среде Windows. Поэтому вместо использования функции высокого уровня из Windows в утилите LaunchControl можно применить простой вызов функции Exec DOS, обратившись к прерыванию Int 21h 4B00h в регистре AX! Как это ни странно, така методика срабатывает, поскольку оболочка Windows по сути является расширением DOS, работающим в защищенном режиме и обладающим удобным интерфейсом. Windows либо передает вызовы Int 21 в нижний DOS-уровень, либо - при необходимости - использует собственные версии этих функций. Для функции Exec в среде Windows применяетс ее "подмененная" версия, которая выполняет всю необходимую для DOS работу (и более), включа распознавание различия между программами DOS и Windows.

Лист.1 иллюстрирует синтаксис функции Exec в среде Windows. Заметьте, что вместо указания первого блока File Control Block вы можете определить параметр Show, указав поле массива из двух слов. В первом слове должно быть значение 2, а второе слово содержит параметр Show.

Оболочка Windows перехватывает обращение к функции Exec среды DOS, проверяет принадлежность запускаемой программы DOS или Windows и устанавливает в ядре системы необходимые флажки. Затем Windows вызывает функцию LoadModule в режиме, соответствующем запуску программы DOS или Windows. (Для более детального представления о том, как Windows запускает программы, прочтите прекрасную книгу Мэтта Петрека "Windows Internals", выпущенную издательством Addison-Wesley.)

На лист. 2 показана подпрограмма, использующа функцию Exec для запуска программы в среде Windows. Заметьте, что командная строка должна быть оформлена по правилам DOS: за байтом длины следует сам текст, а затем байт возврата каретки. Подпрограмма вызывает функцию DOS с помощью функции intdos языка Microsoft C. Если вы пользуетесь компилятором, в котором эта не соответствующая стандарту ANSI функция отсутствует, в текст программы придется внести необходимые изменения. Заметьте также, что, как и для функции LoadModule из среды Windows, return-значение равно либо коду ошибки (при значениях, меньших 32), либо номеру экземпляра данной программы из всех одновременно запущенных.

Оказалось, что запуск программы вне среды Windows и в этом случае требует "обходных маневров". Система Windows содержит очень удобную функцию ExitWindowsExec, которая закрывает сессию Windows, вызывает на исполнение программу, а затем - по завершении программы - перезапускает Windows. К сожалению, эта функция обладает рядом ограничений.

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

Чтобы обойти эти ограничения, утилита LaunchControl не выполняет программу DOS непосредственно. Вместо этого производится запуск другого экземпляра самой этой утилиты вне среды Windows. И как же Windows-программе удается работать в среде DOS? Дело в том, что внутри каждой Windows-программы содержится маленькая программа DOS. Обычно эта программа, называемая DOS-корнем, обеспечивает появление хорошо всем знакомого сообщени об ошибке "This program requires Microsoft Windows" ("Для этой программы требуется Microsoft Windows"). Однако нет причин, препятствующих замене этого стандартного DOS-корня на более сложную программу. Примером может служить программа Windows Setup. При ее запуске в среде DOS на экране воспроизводитс работающий в текстовом режиме установочный интерфейс. А если запуск происходит под управлением Windows, применяется графическая версия интерфейса. Подобным образом работает и утилита LaunchControl.

Если требуется запустить программу вне среды Windows, утилита LaunchControl использует функцию ExitWindowsExec для запуска собственной копии и передает в нее имя LCD-файла, выбранного дл интерпретации. Затем DOS-корень программы LaunchControl открывает переданный файл, выполняет переход в нужный каталог, заданный в этом файле, и запускает программу с помощью DOS-версии функции Exec. После этого происходит выполнение программы, а по ее завершении - перезапуск системы Windows. Если по каким-либо причинам запуск программы оказывается невозможным, выводится сообщение об ошибке. В этом случае утилита LaunchControl, чтобы обеспечить возможность считывания сообщения, прерывает свою работу и ожидает нажатия пользователем любой клавиши клавиатуры.

По сравнению с последовательностью запуска программы процесс установки размера и позиции окна прост. Утилита LaunchControl запускает на исполнение программу, а затем - системный таймер. При получении сигналов таймера (каждые 0,25 с) LaunchControl проверяет каждое из верхних окон на принадлежность к запущенной программе. После обнаружения нужного окна утилита использует функцию SetWindowPos для установки его размера и позиции. Если программа изначально была запущена как пиктограмма или с максимальным форматом окна, то для восстановления его позиции используетс функция SetWindowsPlacement. После установки размера и позиции окна утилита LaunchControl отключает таймер и завершает свою работу.

Утилита LaunchControl расширяет ваши возможности в управлении Windows-программами тем же способом, какой был реализован в PIF-файлах системы DOS. Вместо того чтобы вводить параметры при каждом запуске программы, вы устанавливаете их один раз. Использованные в LaunchControl приемы программирования демонстрируют тот факт, что получение нужного результата при решении даже простейших задач в ОС Windows иногда требует изощренных средств.


Лист. 1. Синтаксис версии функции Exec ОС DOS для среды Windows.
DOS Exec IN: AX = 4BOOh ES:BX = Указатель блока параметров DS:DX = Указатель имени запускаемой программы struct { envblk dw ? ; Сегмент блока переменных порожденной среды cmdline_ptr dd ? ; Указатель командной строки FCB1_ptr dd ? ; Для Windows: ; указывает массив из двух слов ; arr[0] = 2, ; arr[1] = nShow. FCB2_ptr dd ? ; Для Windows: ; устанавливает указатель на 0. } OUT: CF = Установить при ошибке AX = Код возврата управления ;for Windows: ; идентификатор запущенного экземпляра.
Лист. 2. В этой подпрограмме функция Exec используетс для запуска программ из среды Windows.
//---------------------------------------------------------------------- // WinExecEnv - вызов функции WinExec, позволяющий также изменять // параметры среды. // // Эта функция обращает к функции Exec операционной системы DOS. // Срабатывает расширитель DOS среды Windows и производит переключение // к LoadModule. Мы не можем применить LoadModule непосредственно, // поскольку эта подпрограмма не предусматривает работы с DOS-функциями. //---------------------------------------------------------------------- HINSTANCE WinExecEnv (LPSTR lpProg, UINT wShow, WORD wEnvSeg) { struct { WORD segEnv; LPSTR lpszCmdLine; LPWORD lpwShow; LPWORD lpwReserved; } exec_struct; WORD wShowArray[2]; HINSTANCE hExec; char szName[128], szTail[128], *pEnd; union REGS inregs, outregs; // Анализ командной строки lstrcpy (szName, lpProg); // Найти конец имени файла lpEnd = GetEndofName (szName); // Копировать остаток команды в другую строку lstrcpy (&szTail[1], pEnd); *pEnd = "\O'; // Конец командной строки начинается с нулевого байта, за которым следует // собственно окончание с завершающим байтом CR szTail[O] = (char)lstrlen (&szTail[1]); *pEnd = OxOd; *pEnd = '\O'; // Инициализация массива Show. Для работы утилиты LoadModule необходимо, // чтобы первое значение равнялось 2. wShowArray[O] = 2; wShowArray[1] = wShow; exec_struct.segEnv = wEnvSeg; exec_struct.lpszCmdLine = szTail; exec_struct.lpwShow = wShowArray; exec_struct.lpwReserved = O; //DOS Exec inregs.x.ax = Ox4bOO; inregs.x.bx = (WORD)&exec_struct; inregs.x.cx = (WORD)szName; inrdos (&inregs,&outregs); hExec = outregs.x.ax; return hExec; }