Текущий архив: 2006.05.07;
Скачать: CL | DM;
Вниз
запуск приложений и получение результатов Найти похожие ветки
← →
ExE © (2006-02-16 10:26) [0]Здравстуйте.
Подкажите пожалуйста вот такую вешь...
Есть приложение, кот. вызывает другое консольное приложение CVS.exe. Это CVS.exe может возвращать результаты (например, ошибку).
Вопрос как их считать из программы на Delphi ?!?
Замучился уже подскажите плиз
← →
kaZaNoVa © (2006-02-16 10:29) [1]запуск через CreateProcess
← →
ExE © (2006-02-16 10:31) [2]CreateProcess (
nil,
pchar(""cvs.exe" "checkout" "
+""-d" "d:\pesok" "
+""-r" "HEAD" "-N" "
+"""+ExctractFileNameNoDir(ParamStr(i))+"""),
nil,
nil,
false,
NORMAL_PRIORITY_CLASS,
nil,
nil,
lpStartupInfo,
lpProcessInformation );
WaitForSingleObject (lpProcessInformation.hProcess,INFINITE);
А где результаты работы CVS.exe прочитать?
← →
BiN © (2006-02-16 10:35) [3]Код завершения процесса можно получить с помощью GetExitCodeProcess.
Другой вопрос, как получить описатель процесса CVS.exe.
Если приложение-загрузчик не предоставляет никаких механизмов контроля и взаимодействия, то как крайний случай можно предложить перехватывать CreateProcess в 9x/me системах и NtCreateProcess в NT-линейке.
← →
ExE © (2006-02-16 10:44) [4]Да, код возврата тоже вешь нужная, но я хочу получить результаты работы этого КОНСОЛЬНОГО приложения...
Ну к примеру.. командная строка..
"
D:\>cvs.exe -parametrs
-----------
revision 1.3
result = 01
-----------
revision 1.4
result = 02
"
Как прочитать в программе эти revision, result??
← →
BiN © (2006-02-16 11:09) [5]
> ExE © (16.02.06 10:44) [4]
>
> Да, код возврата тоже вешь нужная, но я хочу получить результаты
> работы этого КОНСОЛЬНОГО приложения...
> Ну к примеру.. командная строка..
> "
> D:\>cvs.exe -parametrs
> -----------
> revision 1.3
> result = 01
> -----------
> revision 1.4
> result = 02
> "
>
> Как прочитать в программе эти revision, result??
Перенаправить вывод консольного приложения можно, задав в качестве стандартного описателя вывода (hStdOutput и hStdError в STARTUPINFO) описатель заранее созданного канала, из которого впоследствии и считываются данные.
Вот пример навскидку
http://kladovka.net.ru/delphibase/?action=viewfunc&topic=winappctrl&id=10317
← →
BiN © (2006-02-16 11:12) [6]Только будь готов столкнуться с проблемой, когда некоторые консольные приложения создают дополнительные экранные буферы вывода (например telnet). В таких случаях данный подход неприменим.
← →
xShadow © (2006-02-16 11:12) [7]
> Как прочитать в программе эти revision, result??
Для этого нужно получить StdOut приложения и выполнить его разбор.Function GetDosOutput( const CommandLine, WorkDir: String;
var ResultCode: Cardinal ): String;
var StdOutPipeRead, StdOutPipeWrite: THandle;
SA : TSecurityAttributes;
SI : TStartupInfo;
PI : TProcessInformation;
WasOK : Boolean;
Buffer : array[0..255] of Char;
BytesRead : Cardinal;
Line : String;
Begin
Application.ProcessMessages;
With SA do
Begin
nLength := SizeOf( SA );
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
// создаём пайп для перенаправления стандартного вывода
CreatePipe( StdOutPipeRead, // дескриптор чтения
StdOutPipeWrite, // дескриптор записи
@SA, // аттрибуты безопасности
0 // количество байт принятых для пайпа - 0 по умолчанию
);
try
// Создаём дочерний процесс, используя StdOutPipeWrite в качестве стандартного вывода,
// а так же проверяем, чтобы он не показывался на экране.
with SI do
Begin
FillChar( SI, SizeOf( SI ), 0 );
cb := SizeOf( SI );
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow := SW_HIDE; //не показывать окно
hStdInput := GetStdHandle( STD_INPUT_HANDLE ); // стандартный ввод не перенаправляем
hStdOutput := StdOutPipeWrite;
hStdError := StdOutPipeWrite;
end;
// Запускаем компилятор из командной строки
//WorkDir := ExtractFilePath(CommandLine);
WasOK := CreateProcess( nil,
PChar( CommandLine ),
nil,
nil,
True,
0,
nil,
PChar( WorkDir ),
SI,
PI );
// Теперь, когда дескриптор получен, для безопасности закрываем запись.
// Нам не нужно, чтобы произошло случайное чтение или запись.
CloseHandle( StdOutPipeWrite );
// если процесс может быть создан, то дескриптор, это его вывод
if not WasOK then
raise Exception.Create( "Ошибка выполнения или компиляции: " +
Chr( 10 ) + Chr( 13 ) + CommandLine )
else
try
// получаем весь вывод до тех пор, пока DOS-приложение не будет завершено
Line := "";
Repeat
// читаем блок символов (могут содержать возвраты каретки и переводы строки)
WasOK := ReadFile( StdOutPipeRead, Buffer, 255, BytesRead, nil );
// есть ли что-нибудь ещё для чтения?
if BytesRead > 0 then
Begin
// завершаем буфер PChar-ом
Buffer[BytesRead] := #0;
// добавляем буфер в общий вывод
Line := Line + Buffer;
end;
Application.ProcessMessages;
Until not WasOK or ( BytesRead = 0 );
// ждём, пока завершится консольное приложение
WaitForSingleObject( PI.hProcess, INFINITE );
ResultCode := 0;
GetExitCodeProcess( PI.hProcess, ResultCode );
finally
// Закрываем все оставшиеся дескрипторы
CloseHandle( PI.hThread );
CloseHandle( PI.hProcess );
end;
finally
Result := Line;
CloseHandle( StdOutPipeRead );
end;
end;
← →
ExE © (2006-02-16 11:45) [8]xShadow
БОЛЬШОЕ СПАСИБО
Отличный пример
BiN
Спасибо за ссылку
Всем огромное спасибо, спасли!
Страницы: 1 вся ветка
Текущий архив: 2006.05.07;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.009 c