| Главная | |
Delphi |
WinAPIОбновление: Захват вывода из консольного приложенияВ предыдущей статье было описано, как перехватить вывод из 32-разрядного консольного приложения. Как это сделать с 16-разрядным приложением? Есть новая функция. Это обходит проблему с 16-разрядными приложениями. Будьте осторожны при вызове command.com, так как мы ожидаем окончания процесса, а command.com ждет ввода пользователя... function GetConsoleOutput(const CommandLine: string): string;
var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutFile, AppProcess, AppThread : THandle;
RootDir, WorkDir, StdOutFileName:string;
const
FUNC_NAME = 'GetConsoleOuput';
begin
try
StdOutFile:=0;
AppProcess:=0;
AppThread:=0;
Result:='';
// инициализируем каталог
RootDir:=ExtractFilePath(ParamStr(0));
WorkDir:=ExtractFilePath(CommandLine);
// проверяем WorkDir
if not (FileSearch(ExtractFileName(CommandLine),WorkDir) <> '') then
WorkDir:=RootDir;
// инициализируем атрибуты защиты файла вывода
FillChar(SA,SizeOf(SA),#0);
SA.nLength:=SizeOf(SA);
SA.lpSecurityDescriptor:= nil;
SA.bInheritHandle:= True;
// Создаем файл вывода
StdOutFileName:= RootDir + 'output.tmp';
StdOutFile:=CreateFile(PChar(StdOutFileName),
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
@SA,
CREATE_ALWAYS, // всегда создавать его
FILE_ATTRIBUTE_TEMPORARY or // Будет кэш в памяти,
// если возможно
FILE_FLAG_WRITE_THROUGH,
0);
// Проверяем дескриптор вывода
if StdOutFile = INVALID_HANDLE_VALUE then
raise Exception.CreateFmt('Function %s() failed!' + #10#13 +
'Command line = %s', [FUNC_NAME,CommandLine]);
// инициализируем Startup Info
FillChar(SI, SizeOf(SI), #0);
with SI do begin
cb:= SizeOf(SI);
dwFlags:= STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow:= SW_HIDE;
hStdInput:= GetStdHandle(STD_INPUT_HANDLE);
hStdError:= StdOutFile;
hStdOutput:= StdOutFile;
end;
// Создаем процесс
if CreateProcess(nil>, PChar(CommandLine), nil, nil,
True, 0, nil,
PChar(WorkDir), SI, PI) then begin
WaitForSingleObject(PI.hProcess,INFINITE);
AppProcess:= PI.hProcess;
AppThread:= PI.hThread;
end
else
raise Exception.CreateFmt('CreateProcess() in function %s() failed!'
+ #10#13 + 'Command line = %s', [FUNC_NAME, CommandLine]);
CloseHandle(StdOutFile);
StdOutFile:=0;
with TStringList.Create do
try
LoadFromFile(StdOutFileName);
Result:= Text;
finally
Free;
end;
finally
// Закрываем дескрипторы
if StdOutFile <> 0 then CloseHandle(StdOutFile);
if AppProcess <> 0 then CloseHandle(AppProcess);
if AppThread <> 0 then CloseHandle(AppThread);
// Удаляем файл вывода
if FileExists(StdOutFileName) then DeleteFile(StdOutFileName);
end;
end;
Источник: www.delphi3000.com |
|
|
||
| Copyright (c) Авраменко С. Н. 2008. |