Привет всем. Раньше частенько лазил на этот форум за подсказками, т.к. проблемы, с которыми сталкивался в болшей части были далеко не уникальными, но вот по текущему вопросу чойта ничего не могу найти.
И так. Есть приложение батник-заменитель. Т.е. предполагается, что программа сама найдет местонахождение всех нужных параметров, и пользователь самостоятельно в более свободной форме-не-блокноте, с русскими коментариями сможет уточнить настройки.
По нажатию кнопки запускается консольное приложение в окне (SW_SHOWNORMAL). Использую
CreateProcess.
В окне - чтобы пользователь следил за процессом выполнения программы так же как и раньше. Ведь батник тоже запускал эту же консольную программу.
Цель программы - написать руским по белому результат выполнения операции, по скольку пользователь М или Ж 50+ лет, в англицком и компах нибум-бум. Т.е. надо чтобы "нажал кнопку" - "получил большими буквами ОК/неОК" .
поскольку
Код:
GetExitCodeProcess(ProcessInfo.hProcess, Result);
возвращает "успех" в фактчески в неуспешных случаях (т.е. программа сама, а не CreateProcess, вычислила ошибку и успешно завершила работу(например, если указаный ей в параметрах файл не того формата)), я решил скопировать текст, выводимый на экран, в отдельный буфер, и по ключевым словам дополнительно определять исход операции.
Для этого пользую след. код:
Код:
procedure TForm1.GetConsoleText ();
var
conWnd : HWND;
PID : DWORD;
conHandle : THandle;
bufInfo : CONSOLE_SCREEN_BUFFER_INFO;
p : PChar;
i : Integer;
read : DWORD;
ss : ansistring;
Crd : _COORD;
begin
conWnd := FindWindow(nil, PChar(CLIAddr));//CLIAddr -
GetWindowThreadProcessId(conWnd, @PID);
if AttachConsole(PID) then
begin
conHandle := GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(conHandle, BufInfo);
GetMem(p, BufInfo.dwMaximumWindowSize.X + 1);
try
for i := Memo1.Lines.Count downto MemTextLines do
Memo1.Lines.Delete(i);
output := '';
for i :=Memo1.Lines.Count - MemTextLines to BufInfo.dwSize.Y - 1 do
begin
Crd.X := 0;
Crd.Y := i;
ReadConsoleOutputCharacter(conHandle, p, BufInfo.dwMaximumWindowSize.X, Crd, read);
ss := StrPas(p);
ss := Trim(ss);
if (ss[Length(ss)] = 'X')
then
SetLength(ss, Length(ss) - 1);
if (ss <> '') and (Length(ss) > 2) then
begin
ss := Trim(ss);
output := output + ss + Chr($0D) + Chr($0A);
Application.ProcessMessages;
end;
end;
cd.Y := BufInfo.dwSize.Y;
Application.ProcessMessages;
finally
FreeMem(p, BufInfo.dwMaximumWindowSize.X + 1);
end;
FreeConsole();
end;
end;
Вроде все чудесно работет, без проблем ваще, все красиво, все отрабатывает.. Сидел я, значит, довольный, пока не решил закрыть консольное приложение руками (нажав на керстик), и не ждать завершения операции.. но, закрылась не только консоль, но и все мое приложение!
Если консольное приложение отрабатывает все до конца и само закрывается с помощью FreeConsole(), этой проблемы не возникает.
Как побороть эту неприятность? Поделитесь, пожалуйста, опытом, если есть таковой.
Спасибо.