擷取 dos 下程式產生的結果 |
|
鈴鐺
初階會員 發表:33 回覆:81 積分:35 註冊:2002-03-13 發送簡訊給我 |
|
ddy
站務副站長 發表:262 回覆:2105 積分:1169 註冊:2002-07-13 發送簡訊給我 |
|
鈴鐺
初階會員 發表:33 回覆:81 積分:35 註冊:2002-03-13 發送簡訊給我 |
|
ddy
站務副站長 發表:262 回覆:2105 積分:1169 註冊:2002-07-13 發送簡訊給我 |
//用Delphi 語法表示
Memo1.Clear; Memo1.Lines.Add('delete tmp');
Memo1.Lines.Add('delete tmp1');
Memo1.Lines.Add('route print > tmp');
Memo1.Lines.SaveToFile('tmp1.bat');
Memo1.Clear;
WinExec('tmp1.bat',SW_HIDE );
Memo1.Lines.LoadFromFile('tmp');
我就是這個意思…:p
雖然沒什麼技術,不過也還蠻好用的^^ 噓~~~~~~沉思中… 發表人 - ddy 於 2002/08/05 22:58:55
|
鈴鐺
初階會員 發表:33 回覆:81 積分:35 註冊:2002-03-13 發送簡訊給我 |
謝謝啦! 果然簡潔好用!
引言: //用Delphi 語法表示 Memo1.Clear; Memo1.Lines.Add('delete tmp'); Memo1.Lines.Add('delete tmp1'); Memo1.Lines.Add('route print > tmp'); Memo1.Lines.SaveToFile('tmp1.bat'); Memo1.Clear; WinExec('tmp1.bat',SW_HIDE ); Memo1.Lines.LoadFromFile('tmp'); 我就是這個意思…:p 雖然沒什麼技術,不過也還蠻好用的^^ 噓~~~~~~沉思中… 發表人 - ddy 於 2002/08/05 22:58:55 |
lcsboy
版主 發表:87 回覆:622 積分:394 註冊:2002-06-18 發送簡訊給我 |
WinExec, ShellExecute, CreateProcess的使用心得報告:
這幾個指令, 我想, 書上會講得不多, 就算有講也是有限, 尤其是CreateProcess更是少之又少 /_\ . 拜讀幾個論譠的討論, 實作了一天之後, 我找到了自己的Total Solution
而且, 更簡單, 不用理Microsoft搞出來的一堆Struct(又臭又長, 佔Code Size
而且又沒有比較快, 這樣子玩, 才能顯示出功力嗎?) 一般, 如果要以完全用程式實作, 讀回DOS傳出來的Message
1.CreatePipe
2.CreateProcess
3.WaitForSingleObject
(這樣的寫法, 想玩的人可以跟我拿我的Source Code)
然後再從開啟的Pipe Handle當作檔案的方式, 讀回來
問題來啦!
1. 如果是WinNT/Win2000/WinXP 還要先搞定SECURITY_ATTRIBUTES這個struct
然後塞來塞去, 才把它塞好(真的是有夠美國時間的啦)
2. 就算你完成了以上的事, CreateProcess只能對有檔案存在的執行檔執行,
DIR這個內部指令我實作不出來, 當然, 你可以別的方式去執行內部指令.
而且, 大概只能執行.EXE .COM .BAT
3. 最要命的靈異現象來啦, 我要Run的DOS程式, 如果直接開個Dos Box, 然
後去執行, 是秀不出result, 但是用Alt Enter=>全螢幕, 就看得到結果
同樣的現象, 用CreatePipe是抓不到的, 結果, 問了幾個高手, 還是試不
出來, 除非CreateProcess可以開出來個全螢幕(但醜, 且弄不出來).
所以, 我幹嘛發神經玩這個又臭又長的玩法 於是乎, 我放棄了這個又難, 又爛的方法, /_\, 但其實我之前早就實作出來了
只是覺得自己的code寫得很難看, 想用高級技巧, 結果->高技巧, 不一定高滿
意, 哎, 於是回想了一下, 用導入文字檔的方式, 也就是以上幾位所說的方法
作個小小的整理 如果我有很多程式想要一次Run完, 但是呢? OS是多工作業, 它會一次Run完,
如果要執行的幾個程式有先後順序, 怎麼讓它作完一個再作下一個呢? 最好又
是可以傳回Message的唷, 而且我不想只有Run .exe .com .bat的. 為此CreateProcess不用再列入考慮, 更別說用它了. 而WinExec和ShellExecute呢? 為了要讓WaitForSingleObject用, 需要一個Handle, 而且還想Run .bmp呀 .txt的, 馬上就想到Shellexecute囉, 而且還可以開IE呢! 發e-mail耶, 真是我的最愛呀, 所以, WinExec也不用了, 因此就來好好的給它玩
ShellExecute ^_^ 如果要等待作完再作下一動:
HANDLE hProg;
hProg=ShellExecute(NULL, NULL, "chkdsk", NULL, NULL, SW_SHOW);
WaitForSingleObject(hProg, INIFINTE);
嘿嘿! 夠Smart吧 如果要知道DOS的程式Run了什麼, 就是用大家熟知的老方法">" ^^, 導到文字
檔, 而且呀, 我那個開Dos Box執行了看不到result的程式, 把它導到text file居然可以看到result唷, 贊, 用ShellExecute和WaiteForSingleObject
搭配真是簡單好用, 而且code size和速度都很棒唷. 不過要注意的是
1. ShellExecute的參數是另外擺的唷
Ex: hProg=ShellExecute(NULL, NULL, "check", "> Result.TXT", NULL, SW_SOHW);
2. 因為導到文字檔, 之後又要讀回來, WaitForSingleObject保證程式執行完
才結束, 但不保證文字檔已經寫完唷, 所以在WaitForSingleObject後, 直
接讀Result.TXT有可能會出槌, 我最後的解法是
while(!(FileExists(Result.TXT)));
取代WaitForSingleObject是粉棒的啦 ^^
3. 如果可能常在導入文字檔, 最好在程式執行前後, 把這個Result.TXT砍掉
以防萬一, 因為我的程式就是要用來作重覆事情, 可以這樣作
While(FileExists(Result.TXT))
DeleteFile(Result.TXT);
一直砍, 砍到不見為此. 因為, OS是多工的, 如果你是一個程式執行完要等
另一個的, 就不能大意, 這樣才能達到程式one by one的執行唷 總結
1. 我只要執行一個程式WinExec, ShellExecute, CreateProcess那個最好用?
Ans:ShellExecute. 2. 我要等程式作完再繼續往下作
HANDLE hProg=ShellExecute(.........);
WaitForSingleObject(hProg); 3. 我要等程式作完再繼續往下作, 而且要知道DOS程式Run完的結果
While(FileExists(Result.TXT))
DeleteFile(Result.TXT); HANDLE hProg=ShellExecute(NULL, NULL, 執行檔名, "> Result.TXT",
NULL, SW_SHOW);
while(!(FileExists(Result.TXT)));
........
While(FileExists(Result.TXT))
DeleteFile(Result.TXT); 以上是我個人的心得, 如有什麼不妥, 請多多指教, 文筆不順的地方, 請多
見諒!
|
ddy
站務副站長 發表:262 回覆:2105 積分:1169 註冊:2002-07-13 發送簡訊給我 |
lcsboy兄
果然有研究精神…值得學習…呵呵
有時自己也會陷入所謂的"高深技巧"的迷思
小弟倒是覺得,能完成需求又兼顧開發時程不失為好方法…(哈…為自己懶找藉口) console mode 似乎被Windows 用戶遺忘了
想想Linux 的環境,Win API未必有相似的功能對應
還是基本的輸入輸出轉向等原始的指令有較高的相容性 最近在試著寫Dynamic DNS (for Linux) --仿DNS2Go的功能
深深覺得一堆文字設定檔看似沒有系統,卻能影響系統的功能
提供程式設計人員最大的想像空間 噓~~~~~~沉思中…
|
rhythm
一般會員 發表:7 回覆:5 積分:2 註冊:2002-08-07 發送簡訊給我 |
引言: 謝謝啦! 果然簡潔好用!引言: //用Delphi 語法表示 Memo1.Clear; Memo1.Lines.Add('delete tmp'); Memo1.Lines.Add('delete tmp1'); Memo1.Lines.Add('route print > tmp'); Memo1.Lines.SaveToFile('tmp1.bat'); Memo1.Clear; WinExec('tmp1.bat',SW_HIDE ); Memo1.Lines.LoadFromFile('tmp'); 我就是這個意思…:p 雖然沒什麼技術,不過也還蠻好用的^^ 噓~~~~~~沉思中… 發表人 - ddy 於 2002/08/05 22:58:55不好意思,請問一下ㄛ... 用這樣的結果Memo裡面的print結果好像會暫存一次耶 為什麼會有這樣的結果呢????? |
ddy
站務副站長 發表:262 回覆:2105 積分:1169 註冊:2002-07-13 發送簡訊給我 |
|
arcsin
一般會員 發表:4 回覆:3 積分:1 註冊:2003-03-06 發送簡訊給我 |
引言: //用Delphi 語法表示 Memo1.Clear; Memo1.Lines.Add('delete tmp'); Memo1.Lines.Add('delete tmp1'); Memo1.Lines.Add('route print > tmp'); Memo1.Lines.SaveToFile('tmp1.bat'); Memo1.Clear; WinExec('tmp1.bat',SW_HIDE ); Memo1.Lines.LoadFromFile('tmp'); 我就是這個意思…:p 雖然沒什麼技術,不過也還蠻好用的^^ 噓~~~~~~沉思中… 發表人 - ddy 於 2002/08/05 22:58:55儅所調用的Dos程序運行時間較長時, 有可能在tmp文件產生前就調用了LoadFormFile(), 會出現Cannot open file 的錯誤。 |
arcsin
一般會員 發表:4 回覆:3 積分:1 註冊:2003-03-06 發送簡訊給我 |
引言: //用Delphi 語法表示 Memo1.Clear; Memo1.Lines.Add('delete tmp'); Memo1.Lines.Add('delete tmp1'); Memo1.Lines.Add('route print > tmp'); Memo1.Lines.SaveToFile('tmp1.bat'); Memo1.Clear; WinExec('tmp1.bat',SW_HIDE ); Memo1.Lines.LoadFromFile('tmp'); 我就是這個意思…:p 雖然沒什麼技術,不過也還蠻好用的^^ 噓~~~~~~沉思中… 發表人 - ddy 於 2002/08/05 22:58:55儅所調用的Dos程序運行時間較長時, 有可能在tmp文件產生前就調用了LoadFormFile(), 會出現Cannot open file 的錯誤。 |
lcsboy
版主 發表:87 回覆:622 積分:394 註冊:2002-06-18 發送簡訊給我 |
|
bruce0211
版主 發表:157 回覆:668 積分:279 註冊:2002-06-13 發送簡訊給我 |
|
lcsboy
版主 發表:87 回覆:622 積分:394 註冊:2002-06-18 發送簡訊給我 |
|
william
版主 發表:66 回覆:2535 積分:3048 註冊:2002-07-11 發送簡訊給我 |
|
japhenchen
高階會員 發表:51 回覆:444 積分:184 註冊:2003-07-23 發送簡訊給我 |
乖乖的用CREATEPROCESS吧,以下就是等待外部程式運行完成後才繼續執行其他程式的動作,視窗也是隱藏起來不顯示(連工作列都不會出現),不然被轉向輸出的檔案還沒完成,就會LOADFROMFILE失敗唷!
function ExecuteAndWaitnv(const CommandLine : string) : cardinal; const ErrUINT = High(Cardinal); var tSI : TStartupInfo; tPI : TProcessInformation; dwI : DWORD; VarU : UINT; begin Result := ErrUINT; FillChar(tSI, sizeof(TStartupInfo), 0); tSI.cb := sizeof(TStartupInfo); tSI.dwFlags := STARTF_USESHOWWINDOW; tSI.wShowWindow:=SW_HIDE; if (CreateProcess(nil, pchar(CommandLine), nil, nil, False, CREATE_NEW_PROCESS_GROUP or NORMAL_PRIORITY_CLASS or 0, nil, nil, tSI, tPI)) then begin dwI := WaitForSingleObject(tPI.hProcess, INFINITE); if (dwI = WAIT_OBJECT_0) then if (GetExitCodeProcess(tPI.hProcess, dwI)) then Result := dwI; CloseHandle(tPI.hProcess); CloseHandle(tPI.hThread); end; end;我不懂,不懂,不懂....所以我才來ktop學工夫 |
Theodore
一般會員 發表:11 回覆:10 積分:4 註冊:2003-05-15 發送簡訊給我 |
我有個類似的問題, 希望能得到各位前輩的指教.
我用 shellexecute(.............,SW_HIDE) 及 CreateProcess 的 SW_HIDE
想執行個程式不會搶現在視窗的focus, 例如: 我正用 Mediaplayer 全螢幕看
電影, 用上述的方式, 都已設 SW_HIDE, 還是會讓我看的電影縮成原大小
(focus 還是在電影), 可是我想連那瞬間的focus 都不要被搶掉而導致電影
大小被干擾, 該怎麼做呢....? 發表人 - Theodore 於 2004/03/10 11:36:54
|
aAlan
一般會員 發表:38 回覆:24 積分:12 註冊:2004-07-23 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |