Здравствуйте уважаемые коллеги!
В данной статье напишем программку, которая выполняет команду Ping, при помощи стандартной утилиты Windows Ping.exe
Для начала нарисуем простенький интерфейс для нашей программы:
Нам понадобиться:
— TEdit, в котором будем указывать адрес.
— TMemo, в которую будем выводить результат.
— TButton, которая будет выполнять команду.
Выглядеть оно будет следующим образом:
В первую очередь напишем процедуру, которая непосредственно будет выполнять Ping
procedure DoPing(Address: String; OutText: TStrings); const READ_SIZE = 4096; var SecAttr: TSecurityAttributes; hRP, hWP: THandle; StartInfo: TStartUpInfo; ProcInfo: TProcessInformation; buf: PAnsiChar; ReadSize: DWORD; begin SecAttr.nlength := SizeOf(TSecurityAttributes); SecAttr.binherithandle := True; SecAttr.lpsecuritydescriptor := nil; if Createpipe(hRP, hWP, @SecAttr, 0) then try buf := AllocMem(READ_SIZE + 1); FillChar(StartInfo, SizeOf(TStartUpInfo), #0); StartInfo.cb := SizeOf(TStartUpInfo); StartInfo.hStdOutput := hWP; StartInfo.hStdInput := hRP; StartInfo.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW; StartInfo.wShowWindow := SW_HIDE; if CreateProcess(nil, PChar('ping.exe ' + Address), @SecAttr, @SecAttr, True, NORMAL_PRIORITY_CLASS, nil, nil, StartInfo, ProcInfo) then try while WaitForSingleObject(ProcInfo.hProcess, 100) = WAIT_TIMEOUT do Application.ProcessMessages; ReadSize := READ_SIZE+1; while ReadSize > READ_SIZE do begin ReadFile(hRP, buf[0], READ_SIZE, ReadSize, nil); buf[ReadSize] := #0; OemToAnsi(buf, buf); OutText.Add(String(buf)); end; finally CloseHandle(ProcInfo.hProcess); CloseHandle(ProcInfo.hThread); end; finally FreeMem(buf); CloseHandle(hRP); CloseHandle(hWP); end; end;
На кнопку Ping напишем следующий обработчик:
procedure TfmMain.butPingClick(Sender: TObject); begin butPing.Enabled := False; try memResult.Clear; DoPing(edtAddress.Text, memResult.Lines); finally butPing.Enabled := True; end; end;
Нажав на кнопку получим следующий результат:
Теперь разберем код программы подробнее.
SecAttr: TSecurityAttributes;
Структура для настройки защиты канала передачи данных
- nLength: DWORD — Размер структуры равный SizeOf(TSecurityAttributes)
- lpSecurityDescriptor: Pointer — Указатель на структуру SECURITY_DESCRIPTOR управляющую защитой создаваемого при помощи метода Createpipe канала.
- bInheritHandle: BOOL — Значение указывает может ли создаваемый процесс наследовать дескриптор. Если TRUE, то дескриптор наследуется при создании.
StartInfo: TStartUpInfo;
Структура используется методом CreateProcess, в которой определяются настройки окна создаваемого процесса.
- cb: DWORD — Размер структуры равный SizeOf(TStartUpInfo)
- lpReserved: LPWSTR — Зарезервированное свойство не должно заполнятся.
- lpDesktop: LPWSTR — Имя станции или десктопа для процесса.
- lpTitle: LPWSTR — Для консольных процессов. Задает заголовок окна. Если не указан, то в заголовок выводится имя запускаемого файла.
- dwX: DWORD, dwY: DWORD — Если dwFlags содержит STARTF_USEPOSITION, то данные переменные устанавливают координаты создаваемого окна.
- dwXSize: DWORD, dwYSize: DWORD — Если dwFlags содержит STARTF_USESIZE, то данные переменные задают размеры окна.
- dwXCountChars: DWORD, dwYCountChars: DWORD — Если dwFlags содержит STARTF_USECOUNTCHARS, то данные переменные задают ширину и высоту экранного буфера в символьных строках для консольных приложений.
- dwFillAttribute: DWORD — Если dwFlags содержит STARTF_USEFILLATTRIBUTE, то данный параметр задает цвет текста и фона консольного приложения.
- dwFlags: DWORD — Набор флагов настроек, может содержать любую комбинацию следующих значений:
- STARTF_USESHOWWINDOW — Показывать окно используя настройки параметра wShowWindow
- STARTF_USEPOSITION — Задать позицию окна с координатами из dwX, dwY
- STARTF_USESIZE — Задать размеры окна со значениями dwXSize и dwYSize
- STARTF_USECOUNTCHARS — Задать ширину и высоту экранного буфера в символьных строках со значениями dwXCountChars и dwYCountChars
- STARTF_USEFILLATTRIBUTE — Задать цвет шрифта и фона консольного приложения указанный в dwFillAttribute
- STARTF_FORCEONFEEDBACK — Указывает на то, что курсор находится в режиме обратной связи в течении 2 секунд после вызова CreateProcess.
- STARTF_FORCEOFFFEEDBACK — При создании процесса будет отображаться нормальный курсор.
- STARTF_USESTDHANDLES — Включает стандартный ввод/вывод процесса, обработчик ошибок по указателям заданным в hStdInput, hStdOutput, и hStdError.
- wShowWindow: Word — Настройка показа окна процесса. Может принимать одно из значений констант SW_ из модуля Windows.
- cbReserved2: Word — Должен быть 0.
- lpReserved2: PByte — Должен быть nil.
- hStdInput: THandle — Указатель на обработчик ввода.
- hStdOutput: THandle — Указатель на обработчик вывода.
- hStdError: THandle — Указатель на обработчик ошибки.
ProcInfo: TProcessInformation;
Заполняется функцией CreateProcess и содержит информацию о созданном процессе.
- hProcess: THandle — Дескриптор процесса.
- hThread: THandle — Дескриптор потока.
- dwProcessId: DWORD — Идентификатор процесса.
- dwThreadId: DWORD — Идентификатор потока.
Createpipe
Создание канала передачи данных между процессами.
- hReadPipe: THandle — Идентификатор канала для чтения данных.
- hWritePipe: THandle — Идентификатор канала для записи данных.
- lpPipeAttributes: PSecurityAttributes — Атрибуты защиты
- nSize: DWORD — Кол-во байт памяти зарезервированной под канал.
CreateProcess
Функция создает новый процесс.
- lpApplicationName: LPCWSTR — Строка содержащая имя исполняемого файла.
- lpCommandLine: LPWSTR — Строка содержащая параметры.
- lpProcessAttributes: PSecurityAttributes — Указатель на структуру безопасности процесса.
- lpThreadAttributes: PSecurityAttributes — Указатель на структуру безопасности потока.
- bInheritHandles: BOOL — Флаг наследования. Указывает будет или нет создаваемый процесс наследовать дескрипторы.
- dwCreationFlags: DWORD — Флаги создания процесса. Могут содержать комбинацию из следующих значений:
- CREATE_DEFAULT_ERROR_MODE — Создаваемый процесс не будет наследовать режим ошибки вызывающего процесса. Данный флаг обычно используется для многопоточных приложений.
- CREATE_NEW_CONSOLE — Создает консольный процесс не наследуя параметры родительской консоли. Данный флаг не может использоваться совместно с флагом DETACHED_PROCESS.
- CREATE_NEW_PROCESS_GROUP — Создает новую группу процессов. Группа процессов содержит все процессы, являющиеся наследниками этого корневого процесса.
- CREATE_SEPARATE_WOW_VDM — Флаг запускает новый процесс на приватной Виртуальной DOS Машине (VDM)
- CREATE_SHARED_WOW_VDM — Запускает новый процесс в совместной Виртуальной DOS Машине.
- CREATE_SUSPENDED — Создает процесс, главный поток которого находится в спящем режиме.
- CREATE_UNICODE_ENVIRONMENT — Данный флаг включает использование символов Unicode в параметре lpEnvironment. Если не указан, то используется ANSI.
- DEBUG_PROCESS — Включает режим отладки в создаваемом процессе. Основной процесс при этом становится отладчиком.
- DEBUG_ONLY_THIS_PROCESS — Необходим в том случае, когда вызывающий процесс сам является отлаживаемым.
- DETACHED_PROCESS — Новый процесс не получает доступа к консоли родительского процесса. Не может использоваться совместно с CREATE_NEW_CONSOLE.
Также в качестве флага может быть указан приоритет выполнения процесса:
- HIGH_PRIORITY_CLASS — Высокий приоритет, который забирает себе все ресурсы.
- IDLE_PRIORITY_CLASS — Приоритет, при котором процесс работает только когда система не занята процессами с более высоким приоритетом.
- NORMAL_PRIORITY_CLASS — Обычный приоритет, как у большинства программ.
- REALTIME_PRIORITY_CLASS — Приоритет в реальном времени, который является наивысшим приоритетом даже среди процессов операционной системы. Может приводить к зависанию системы.
- lpEnvironment: Pointer — Среда выполнения процесса, если параметр не указан, то используется среда текущего вызывающего процесса.
- lpCurrentDirectory: LPCWSTR — Путь к каталогу запуска процесса.
- lpStartupInfo: TStartupInfo — Указатель на структуру настройки отображения окна процесса.
- lpProcessInformation: TProcessInformation — Указатель на структуру с настройками процесса.
WaitForSingleObject
Ожидает выполнение дочернего процесса.
- hHandle: THandle — Указатель на процесс.
- dwMilliseconds: DWORD — Кол-во миллисекунд.
ReadFile
Функция чтения данных из файла или устройств ввода/вывода.
- hFile: THandle — Указатель на процесс
- Buffer — Буфер для чтения.
- nNumberOfBytesToRead: DWORD — Кол-во байт, которые необходимо прочитать.
- lpNumberOfBytesRead: DWORD — Кол-во прочитанных байт.
- lpOverlapped: POverlapped — Если чтение производится из файла, то задаются флаги доступа к файлу.
OemToAnsi
Переводит OEM строку (строки заканчивающиеся пустым символом) в ANSI строку.
Исходный код программы можно скачать по этой ссылке.