#1楼 2009-03-30 18:13 guest[未注册用户]
WinExec已不推荐使用,保留它是为兼容win16.
近日我也在研究此问题,想:在程序中调用外部程序并且能够判断程序是否执行完成,以便于后续处理。
搜到一篇:
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);
以上是我個人的心得, 如有什麼不妥, 請多多指教, 文筆不順的地方, 請多
見諒!