Программирование для Windows NT

Функция StartProcess


Функция StartProcess выполняет запуск программного файла, выбранного пользователем.

Для выбора программного файла используется функция GetOpenFileName, которую мы подробно описали в разделе “Стандартные диалоговые панели для открытия файлов” 13 тома “Библиотеки системного программиста”. Путь к выбранному файлу записывается в поле lpstrFile структуры ofn.

Запуск процесса выполняется функцией CreateProcess, которая вызывается следующим образом:

if(CreateProcess(NULL, ofn.lpstrFile, NULL, NULL,

        FALSE, dwCreationFlags, NULL, NULL, &si, &pi))

{

   . . .

}

Первый параметр функции CreateProcess указан как NULL, поэтому адрес символьной строки, содержащей путь к программному файлу, передается через второй параметр. Напомним, что с помощью этого параметра можно передать функции CreateProcess командную строку (с параметрами) для запуска приложения.

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

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

Через шестой параметр функции CreateProcess передаются флаги создания процесса. Здесь мы используем глобальную переменную dwCreationFlags, содержимое которой устанавливается функцией диалога диалоговой панели Create Options. Эта функция будет описана ниже.

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



Через девятый параметр функции CreateProcess передается адрес структуры si типа STARTUPINFO. Ни одно из полей этой структуры, кроме поля cb, не используется, поэтому инициализация структуры выполняется очень просто:

memset(&si, 0, sizeof(STARTUPINFO));


si.cb = sizeof(si);

И, наконец, через последний, десятый параметр функции CreateProcess передается адрес структуры pi типа PROCESS_INFORMATION. Напомним, что после удачного запуска процесса в эту структуру записываются идентификаторы, а также системные номера процесса и его главной задачи.

В случае успешного запуска процесса функция StartProcess проверяет необходимость ожидания его завершения. По умолчанию ожидание не выполняется, однако если пользователь включил в диалоговой панели Start Options переключатель Wait process termination, функция этой диалоговой панели записывает в глобальную переменную fWaitTermination значение TRUE. При этом функция StartProcess будет ожидать завершение запущенного процесса.

В режиме ожидания функция StartProcess вначале закрывает ненужный ей больше идентификатор главной задачи процесса pi.hThread, а затем вызывает функцию WaitForSingleObject, передавая ей в качестве первого параметра идентификатор процесса pi.hProcess, завершение которого необходимо дождаться. Второй параметр задает ожилание в течении неограниченного времени:

if(WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED)

{

  . . .

}

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

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

Для получения кода завершения процесса мы воспользовались функцией GetExitCodeProcess:

GetExitCodeProcess(pi.hProcess, &dwExitCode);

Через первый параметр этой функции передается идентификатор завершившегося процесса, а через второй - адрес переменной типа DWORD, в которую будет записан код завершения.

После отображения кода завершения идентификатор процесса освобождается функцией CloseHandle.

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

CloseHandle(pi.hProcess);

CloseHandle(pi.hThread);

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


Содержание раздела