Delphi - объектно-ориентированный язык программирования, разработанный компанией Borland в 1995 году. Он основан на языке программирования Pascal, но имеет более расширенные возможности и добавлены новые функции.
Delphi является интегрированной средой разработки (IDE), которая позволяет разрабатывать программное обеспечение для различных платформ, включая Windows, macOS, Android и iOS. Delphi достигает многоплатформенности с помощью...
По сравнению с ShellExecute, функция дает дополнительные возможности по управлению процессом: можно установить начальный приоритет первого потока процесса, выставить положение и размер окна приложения, дождаться завершения процесса, завершить процесс.
CreateProcess(lpApplicationName: PChar, // имя исполняемого модуляlpCommandLine: PChar, // строка параметров запускаемой программыlpProcessAttributes: TSecurityAttributes, // структура SECURITY_ATTRIBUTES процессаlpThreadAttributes: TSecurityAttributes, // структура SECURITY_ATTRIBUTES потокаbInheritHandles: LongBool, // флаг наследования текущего процессаdwCreationFlags: Longword, // флаги способов создания процессаlpEnvironment: Pointer, // указатель на блок средыlpCurrentDirectory: PChar, // текущий диск и каталогlpStartupInfo:TStartupInfo, // структура STARTUPINFO lpProcessInformation: TProcessInformation // структура PROCESS_INFORMATION ): LongBool;
Приведу краткое описание функции, за более полным обращайтесь в Windows SDK.
lpApplicationNameПолный путь к исполняемому модулю программы, например, c:Program FilesBorlandDelphi7BinDelphi32.exe (поиск производится только в текущей директории!). lpApplicationName может быть nil, тогда lpCommandLine должна содержать имя исполняемого модуля (если имя содержит пробелы, то оно должно быть заключено в "двойные кавычки"), отделенное от остальной строки пробелом. Если запускается 16-разрядное приложение в среде Windows NT, lpApplicationName должна быть nil, а lpCommandLine содержать имя модуля.
lpCommandLineСтрока параметров, может быть nil. Если приложение указано в lpCommandLine, то поиск производится в текущей, системной и описанных в переменной окружения PATH директориях. Если приложение указано в lpApplicationName, строка параметров должна начинаться с пробела.
lpProcessAttributesАтрибуты защиты для нового процесса. Если указать nil то система сделает это по умолчанию. В Windows 9.x, Me игнорируется.
lpThreadAttributesАтрибуты защиты для первого потока созданного приложением. nil - установка по умолчанию. В Windows 9.x, Me игнорируется.
bInheritHandlesФлаг наследования от процесса производящего запуск. Унаследованные дескрипторы имеют те же значения и права доступа, что и оригиналы. Наследуются если установлено в true.
dwCreationFlagsФлаг способа создания процесса и его приоритет:
Флаг |
Описание |
CREATE_DEFAULT_ERROR_MODE | Новый процесс не наследует режим ошибок (error mode) вызывающего процесса. |
CREATE_NEW_CONSOLE | Новый процесс получает новую консоль вместо того, чтобы унаследовать родительскую. |
CREATE_SUSPENDED | Первичная нить процесса создается в спящем (suspended) состоянии и не выполняется до вызова функции ResumeThread. |
HIGH_PRIORITY_CLASS | Высокий приоритет |
IDLE_PRIORITY_CLASS | Поток выполняется только при простое системы |
NORMAL_PRIORITY_CLASS | Приоритет по умолчанию |
REALTIME_PRIORITY_CLASS | Наивысший приоритет |
lpEnvironmentБлок среды. Если nil, то будет использован блок среды родительского процесса. Блок среды это список переменных имя=значение в виде строк с нулевым окончанием.
lpCurrentDirectoryТекущий диск и каталог. Если nil, то будет использован диск и каталог процесса родителя.
lpStartupInfoИспользуется для настройки свойств процесса, например расположения окон и заголовок..
TStartUpInfo = recordcb: Longword; lpReserved: PChar; lpDesktop: PChar; lpTitle: PChar; dwX: Longword; dwY: Longword; dwXSize: Longword; dwYSize: Longword; dwXCountChars: Longword; dwYCountChars: Longword; dwFillAttribute: Longword; dwFlags: Longword; wShowWindow: Word; cbReserved2: Word; lpReserved2: PByte; hStdInput: THandle; hStdOutput: THandle; hStdError: THandle;end;
Некоторые элементы имеют смысл, только если дочернее приложение создает перекрываемое (overlapped) окно, а другие — если это приложение осуществляет ввод-вывод на консоль. Рассмотрим только первый тип параметров.
Элемент |
Описание |
cb | Содержит количество байтов, занимаемых структу рой TStartUpInfo. Обязательно для заполнения. Инициализируйте как SizeOf(TStartUpInfo). |
lpReserved |
Зарезервирован. Инициализируйте как nil |
IpDesktop | Идентифицирует имя рабочего стола, на котором запускается приложение. |
dwX dwY |
Координаты окна в пикселях. |
dwXSize dwYSize | Определяют ширину и высоту (в пикселях) окна приложения. |
dwFlags | Содержит набор флагов, позволяющих управлять созданием дочернего процесса |
wSbowWtndow | Определяет как должно выглядеть окно запущенного приложения. В этот элемент можно записать любой из идентификаторов типа SW_* |
cbReserved2 | Зарезервирован. Инициализируйте как 0. |
lpReserved2 | Зарезервирован. Инициализируйте как nil. |
Список допустимых флагов dwFlags:
Флаг |
Описание |
STARTF_USESIZE | Заставляет использовать элементы dvXSize и dwYSize |
STARTF_USESHOWWINDOW | Заставляет использовать элемент wShowWindow |
STARTF_USEPOSITION | Заставляет использовать элементы dwX и dwY |
STARTF_FORCEONFEEDBACK STARTF_FORCEOFFFEEDBACK | Форма курсора при запуске (с "часиками" или без) |
lpProcessInformationИнформация о созданном процессе. Инициализируется самой функцией.
TProcessInformation = record hProcess: THandle; // дескриптор процессаhThread: THandle; // дескриптор первого потока процессаdwProcessId: Longword; // глобальный идентификатор процессаdwThreadId: Longword; // глобальный идентификатор потокаend;
Указатели hProcess и hThread должны быть закрыты в родительском процессе функцией CloseHandle иначе произойдет утечка памяти. CloseHandle не закрывает процесс (поток), а только уменьшает счетчики открытых дескрипторов.
При удачном вызове CreateProcess возвращает true.
Если приложение Win32, то после создания процесса желательно дождаться завершения его инициализации функцией WaitForInputIdle.
uses Windows;...var Rlst: LongBool; StartUpInfo: TStartUpInfo; ProcessInfo: TProcessInformation; Error: integer;begin FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0); with StartUpInfo do begin cb := SizeOf(TStartUpInfo); dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK; wShowWindow := SW_SHOWNORMAL; end; Rlst := CreateProcess('C:WindowsSystem32 otepad.exe', ' c: eadme.txt', nil, nil, false, NORMAL_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo); if Rlst then with ProcessInfo do begin WaitForInputIdle(hProcess, INFINITE); // ждем завершения инициализации CloseHandle(hThread); // закрываем дескриптор процесса CloseHandle(hProcess); // закрываем дескриптор потока endelse Error := GetLastError;end;
Эквивалентный вызов функции:Rlst := CreateProcess(nil, 'notepad c: eadme.txt', nil, nil, false, NORMAL_PRIORITY_CLASS,nil, nil, StartUpInfo, ProcessInfo);
Можно дождаться завершения запущенного процесса и получить код его завершения. Но в этом случае работа потока, который запустил процесс, приостанавливается:
var Rlst: LongBool; StartUpInfo: TStartUpInfo; ProcessInfo: TProcessInformation; Error: integer; ExitCode: Cardinal;begin FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0); with StartUpInfo do begin cb := SizeOf(TStartUpInfo); dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK; wShowWindow := SW_SHOWNORMAL; end; Rlst := CreateProcess('C:WindowsSystem32 otepad.exe', ' c: eadme.txt', nil, nil, false, NORMAL_PRIORITY_CLASS, nil, nil, StartUpInfo, ProcessInfo); if Rlst then with ProcessInfo do begin WaitForInputIdle(hProcess, INFINITE); // ждем завершения инициализации WaitforSingleObject(ProcessInfo.hProcess, INFINITE); // ждем завершения процесса GetExitCodeProcess(ProcessInfo.hProcess, ExitCode); // получаем код завершения CloseHandle(hThread); // закрываем дескриптор процесса CloseHandle(hProcess); // закрываем дескриптор потока endelse Error := GetLastError;end;
Для принудительного завершения запущенного процесса надо вызвать функцию TerminateProcess (до вызова функции CloseHandle).
...
WaitForInputIdle(hProcess, INFINITE); // ждем завершения инициализации Sleep(2000); TerminateProcess(hProcess, NO_ERROR); CloseHandle(hThread); // закрываем дескриптор процесса CloseHandle(hProcess); // закрываем дескриптор потока...
Источник www.delphi.hostmos.ru