| | | | |
Перенаправление StdOut в TStream | Полный текст материала
Другие публикации автора: Денис
Цитата или краткий комментарий: «... Статья является продолжением темы о перехвате вывода в StdOut дочернего
приложения. ...» |
Важно:- Страница предназначена для обсуждения материала, его содержания, полезности, соответствия действительности и так далее. Смысл не в разборке, а в приближении к истине :о) и пользе для всех.
- Любые другие сообщения или вопросы, а так же личные эмоции в адрес авторов и полемика, не относящаяся к теме обсуждаемого материала, будут удаляться без предупреждения авторов, дабы не мешать жителям нормально общаться.
- При голосовании учитывайте уровень, на который расчитан материал. "Интересность и полезность" имеет смысл оценивать относительно того, кому именно предназначался материал.
- Размер одного сообщений не должен превышать 5К. Если Вам нужно сказать больше, сделайте это за два раза. Или, что в данной ситуации правильнее, напишите свою статью.
Всегда легче осудить сделанное, нежели сделать самому. Поэтому, пожалуйста, соблюдайте правила Королевства и уважайте друг друга.
Добавить свое мнение.
| | Содержит полезные и(или) интересные сведения | [1] | 0 | 0% | | | | Ничего особенно нового и интересного | [2] | 0 | 0% | | | | Написано неверно (обязательно укажите почему) | [3] | 1 | 100% | | Всего проголосовали: 1 | | | Все понятно, материал читается легко | [1] | 1 | 100% | | | | Есть неясности в изложении | [2] | 0 | 0% | | | | Непонятно написано, трудно читается | [3] | 0 | 0% | | Всего проголосовали: 1 |
[Ввод/вывод (StdIn/StdOut)]
Отслеживать это обсуждение
Всего сообщений: 325-04-2005 11:43Денис,
твой код у меня глючит по-страшному, поэтому я его несколько переделал:
Procedure RunAny(CommandLine: string; Str: TStrings);
var
tRead, cWrite, dwAvail: cardinal;
SA: TSecurityAttributes;
PI: TProcessInformation;
SI: TStartupInfo;
sBuff: THandleStream;
StringBuf: TStringList;
ret : Cardinal;
m : TMemoryStream;
fla : boolean;
begin
SA.nLength:=SizeOf(SECURITY_ATTRIBUTES);
SA.bInheritHandle:=True;
SA.lpSecurityDescriptor:=nil;
if not CreatePipe(tRead, cWrite, @SA, 0) then Exit;
ZeroMemory(@SI, SizeOf(TStartupInfo));
SI.cb:=SizeOf(TStartupInfo);
SI.dwFlags:=STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
SI.wShowWindow:=SW_HIDE;
SI.hStdOutput:=cWrite;
if CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, nil, SI, PI)
then begin
Str.Clear();
sBuff := THandleStream.Create(tRead);
StringBuf := TStringList.Create();
m := TMemoryStream.Create;
repeat
Ret := WaitForSingleObject(PI.hProcess, 100);
StringBuf.Clear();
if sBuff.Size > 0 then
begin
fla := (m.Size > 0) and not (PByteArray(m.Memory)^[m.Size - 1] in [13, 10]);
m.Size := 0;
m.LoadFromStream(sBuff);
m.Position := 0;
StringBuf.LoadFromStream(m);
if StringBuf.Count > 0 then
begin
if (Str.Count > 0) and fla then
begin
StringBuf.Strings[0] := Str.Strings[Str.Count-1]+StringBuf.Strings[0];
Str.Delete(Str.Count-1);
end;
end;
Str.AddStrings(StringBuf);
end;
until (Ret <> WAIT_TIMEOUT);
m.Free;
CloseHandle(PI.hProcess);
CloseHandle(PI.hThread);
end;
CloseHandle(tRead);
CloseHandle(cWrite);
end;
В переделанном виде все работает ОК.
Заметь, что надо проверять результат WaitForSingleObject! Именно так мы можем понять, что дочерний процесс завершился.
Успехов!
|
|
25-03-2005 06:30можно конешно обойти:
cmd /c netstat -n | findstr /c:":445"
, но всё же? |
|
25-03-2005 06:23в случае если commandline равен:
netstat -n | findstr /c:":445"
получим казус. |
|
|
|