В этой статье реализуется запуск консольной программы в Delphi и отображаются выходные данные консольной программы в элементе управления Memo.
На работе мне нужно было вручную компилировать программы J2ME. Я начал писать пакетную программу, но ее было очень сложно использовать, поэтому я хотел использовать Delphi для создания интегрированного инструмента компиляции. Однако все инструменты компиляции Java являются консольными программами. записать вывод консольной программы и отобразить ее в Memo. Проверив некоторую информацию в Интернете и неоднократно протестировав, я нашел способ ее реализации, надеюсь, это будет полезно всем:
PROcedure TMainForm.RunDosInMemo(const DosApp: string; AMemo: TMemo);
константа
{Установить размер ReadBuffer}
ЧтениеБуфер = 2400;
вар
Безопасность: TSecurityAttributes;
ReadPipe, WritePipe: THandle;
начало: TStartUpInfo;
Информация о Процессе: ТПроцессИнформация;
Буфер: PChar;
Чтение байтов: DWord;
Буф: строка;
начинать
с безопасностью сделать
начинать
nlength:= SizeOf(TSecurityAttributes);
binherithandle: = правда;
lpsecuritydescriptor:= ноль;
конец;
{Создайте именованный канал для захвата вывода консольной программы}
если Createpipe(ReadPipe, WritePipe, @Security, 0), то
начинать
Буфер:= AllocMem(ReadBuffer + 1);
FillChar(Начало, Размер(Начало), #0)
{Установим атрибуты запуска консольной программы}
с началом сделать
начинать
cb:= SizeOf(начало);
start.lpReserved:= ноль;
lpDesktop: = ноль;
lpTitle := ноль;
двХ: = 0;
двY := 0;
dwXSize: = 0;
dwYSize: = 0;
dwXCountChars: = 0;
dwYCountChars: = 0;
dwFillAttribute: = 0;
cbReserved2:= 0;
lpReserved2:= ноль;
hStdOutput := WritePipe; //Направляем вывод в созданный нами WritePipe;
hStdInput := ReadPipe; //Прямой ввод в созданный нами ReadPipe;
hStdError := WritePipe; // Направляем вывод ошибки в созданный нами WritePipe
dwFlags:= STARTF_USESTDHANDLES или STARTF_USESHOWWINDOW;
wShowWindow := SW_HIDE;//Скрываем окно
конец;
пытаться
{Создаем дочерний процесс и запускаем консольную программу}
если CreateProcess(nil, PChar(DosApp), @Security, @Security, true,
NORMAL_PRIORITY_CLASS,
ноль, ноль, старт, ProcessInfo), затем
начинать
{Подождите, пока процесс завершится}
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
{Выключите выход... Я его сначала не отключил. В результате, если выхода не будет, программа умрет. }
CloseHandle(WritePipe);
Но := '';
{Прочитайте вывод консольной программы}
повторить
БайтсЧтение:= 0;
ReadFile(ReadPipe, Buffer[0], ReadBuffer, BytesRead, ноль);
Буфер[BytesRead] := #0;
OemToAnsi(Буфер, Буфер);
Buf := Buf + строка(Буфер);
до тех пор, пока (BytesRead <ReadBuffer);
ОтправитьОтладка (Буф);
{Разделить по символам новой строки и отобразить в Memo}
пока pos(#10, Buf) > 0 делаю
начинать
AMemo.Lines.Add(Copy(Buf, 1, pos(#10, Buf) - 1));
Удалить(Buf, 1, pos(#10, Buf));
конец;
конец;
окончательно
FreeMem(Буфер);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ReadPipe);
конец;
конец;
конец;