線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2035
推到 Plurk!
推到 Facebook!

如何擷取DOS的輸出-->請不要打我

答題得分者是:sryang
blue
中階會員


發表:170
回覆:136
積分:81
註冊:2002-04-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-11-11 09:43:41 IP:59.120.xxx.xxx 訂閱
Hi,各位先進大家好:
為了擷取DOS的輸出,找了一些先進的作法,使用Createpipe & Createprocess,
在一般的DOS命令使用上是可正常運作,
但....現在使用了一個microsoft imagex 的 備份軟體,
卻是需等到完全執行完,才會將結果顯示出來,
不知有那位先進遇過?
在DOS下,它明明是一行行地顯示到螢幕上,
謝謝!

procedure RunDosInMemo(DosApp:String;AMemo:TMemo);
const
ReadBuffer = 2048;
var
Security:TSecurityAttributes;
ReadPipe,WritePipe:THandle;
Start:TStartUpInfo;
ProcessInfo:TProcessInformation;
Buffer:Pchar;
BytesRead:DWord;
Apprunning:DWord;
begin
Security.nLength := sizeOf(TSecurityAttributes);
Security.bInheritHandle := true;
Security.lpSecurityDeforbiddenor := nil;
if Createpipe (ReadPipe,WritePipe,@Security,0) then
begin
Buffer := AllocMem(ReadBuffer);
FillChar(Start,Sizeof(Start),#0);
Start.cb := sizeOf(Start);
Start.hStdOutput := WritePipe;
Start.hStdInput := ReadPipe;
Start.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
Start.wShowWindow := SW_HIDE;
if CreateProcess(nil,PChar(DosApp),@Security,@Security,true,NORMAL_PRIORITY_CLASS,nil,nil,Start,ProcessInfo) then
begin
Repeat
Apprunning := WaitForSingleObject(ProcessInfo.hProcess,100);
Repeat
BytesRead := 0;
ReadFile(ReadPipe,Buffer[0],ReadBuffer,BytesRead,nil);
Buffer[BytesRead]:= #0;
AMemo.Text := AMemo.Text String(Buffer);
until (BytesRead < ReadBuffer);
Application.ProcessMessages;
until (Apprunning <> WAIT_TIMEOUT );
end;

FreeMem(Buffer);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ReadPipe);
CloseHandle(WritePipe);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
RunDosInMemo('ping 192.168.1.10 -t',Memo1);
end;

procedure TForm1.Memo1Change(Sender: TObject);
begin
SendMessage(Memo1.handle,WM_VSCROLL,SB_BOTTOM,0);
end;
sryang
尊榮會員


發表:39
回覆:762
積分:920
註冊:2002-06-27

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-11-11 11:02:55 IP:59.125.xxx.xxx 訂閱
你自己標明的紅色部份,只要搬動一行 code 就好

[code delphi]
Repeat
Apprunning := WaitForSingleObject(ProcessInfo.hProcess,100);
Repeat
BytesRead := 0;
ReadFile(ReadPipe,Buffer[0],ReadBuffer,BytesRead,nil);
Buffer[BytesRead]:= #0;
AMemo.Text := AMemo.Text String(Buffer);
Application.ProcessMessages; // 搬到這裡
until (BytesRead < ReadBuffer);
// Application.ProcessMessages; // 這一行搬到內層迴圈
until (Apprunning <> WAIT_TIMEOUT);
[/code]
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
編輯記錄
sryang 重新編輯於 2008-11-11 11:04:05, 註解 無‧
sryang 重新編輯於 2008-11-11 11:04:25, 註解 無‧
blue
中階會員


發表:170
回覆:136
積分:81
註冊:2002-04-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-11-11 11:36:29 IP:59.120.xxx.xxx 訂閱
Hi,先進您好:
小弟的主要問題是這段程式的運作是可正常顯示,
但是....若是執行 Windows AIK 的 Imagex.exe 卻是無法正常顯示,
不知道 Imagex.exe 有何特殊的寫法(同樣是輸出到DOS畫面),
謝謝!

===================引 用 sryang 文 章===================
你自己標明的紅色部份,只要搬動一行 code 就好

[code delphi]
Repeat
Apprunning := WaitForSingleObject(ProcessInfo.hProcess,100);
Repeat
BytesRead := 0;
ReadFile(ReadPipe,Buffer[0],ReadBuffer,BytesRead,nil);
Buffer[BytesRead]:= #0;
AMemo.Text := AMemo.Text String(Buffer);
Application.ProcessMessages; // 搬到這裡
until (BytesRead < ReadBuffer);
// Application.ProcessMessages; // 這一行搬到內層迴圈
until (Apprunning <> WAIT_TIMEOUT);
[/code]
wscken
初階會員


發表:28
回覆:75
積分:45
註冊:2003-08-05

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-11-13 10:53:13 IP:203.66.xxx.xxx 訂閱
請問一下,為什麼 Security.lpSecurityDeforbiddenor := nil;
這行我編譯會過不去,是我的系統少了什麼東西嗎?
而且這樣的做法,雖然會一行一行讀取近來,可是常常會發生卡住的情形,
比如說,打入cmd而已,就常會卡住。

sryang
尊榮會員


發表:39
回覆:762
積分:920
註冊:2002-06-27

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-11-13 11:09:55 IP:59.125.xxx.xxx 訂閱
又仔細看了一次你提供的程式碼,發覺你只處理了 stdin 以及 stdout,沒有處理 stderr
試著加入紅色這一行看看

Start.cb := sizeOf(Start);
Start.hStdOutput := WritePipe;
Start.hStdError := WritePipe;
Start.hStdInput := ReadPipe;
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
編輯記錄
sryang 重新編輯於 2008-11-13 11:10:24, 註解 無‧
blue
中階會員


發表:170
回覆:136
積分:81
註冊:2002-04-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-11-14 05:27:57 IP:219.81.xxx.xxx 訂閱
Hi,您好:
這一行改成 Security.lpSecurityDescriptor:=nil;
另,打入CMD卡住的意思是....?
這段程式是隱藏DOS的畫面,
但,將其輸出導入到Memo的內容,
打入CMD後就沒有後續的動作了....
謝謝!
===================引 用 wscken 文 章===================
請問一下,為什麼 Security.lpSecurityDeforbiddenor := nil;
這行我編譯會過不去,是我的系統少了什麼東西嗎?
而且這樣的做法,雖然會一行一行讀取近來,可是常常會發生卡住的情形,
比如說,打入cmd而已,就常會卡住。

blue
中階會員


發表:170
回覆:136
積分:81
註冊:2002-04-15

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-11-14 05:35:35 IP:219.81.xxx.xxx 訂閱
Hi, 先進您好:
stderr的部份小弟有加,
其實小弟共找到三個版本的這段程式,
使用其他的Dos command都是一行一行的導入其輸出沒有問題,
唯獨 imagex.exe 是直到最後才一次顯示其過程,
當然,小弟也可以用其他找到的軟體取代 imagex.exe,
只是很好奇, imagex 是如何做到的,
謝謝!

===================引 用 sryang 文 章===================
又仔細看了一次你提供的程式碼,發覺你只處理了 stdin 以及 stdout,沒有處理 stderr
試著加入紅色這一行看看

Start.cb := sizeOf(Start);
Start.hStdOutput := WritePipe;
Start.hStdError := WritePipe;
Start.hStdInput := ReadPipe;
系統時間:2024-05-06 8:13:29
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!