WinAPI: WinExec - 运行外部程序

//声明
WinExec(
  lpCmdLine: LPCSTR; {文件名和参数; 如没指定路径会按以下顺序查找: 程序目录/当前目录/System32/Windows/PATH环境变量}
  uCmdShow: UINT     {启动选项}
): UINT;

//返回值:
大于 31                    {调用成功}
等于 0                     {内存不足}
ERROR_FILE_NOT_FOUND = 2{文件名错误}
ERROR_PATH_NOT_FOUND = 3{路径名错误}
ERROR_BAD_FORMAT     = 11; {EXE 文件无效}

//uCmdShow 参数可选值:
SW_HIDE            = 0; {隐藏, 并且任务栏也没有最小化图标}
SW_SHOWNORMAL      = 1; {用最近的大小和位置显示, 激活}
SW_NORMAL          = 1; {同 SW_SHOWNORMAL}
SW_SHOWMINIMIZED   = 2; {最小化, 激活}
SW_SHOWMAXIMIZED   = 3; {最大化, 激活}
SW_MAXIMIZE        = 3; {同 SW_SHOWMAXIMIZED}
SW_SHOWNOACTIVATE  = 4; {用最近的大小和位置显示, 不激活}
SW_SHOW            = 5; {同 SW_SHOWNORMAL}
SW_MINIMIZE        = 6; {最小化, 不激活}
SW_SHOWMINNOACTIVE = 7; {同 SW_MINIMIZE}
SW_SHOWNA          = 8; {同 SW_SHOWNOACTIVATE}
SW_RESTORE         = 9; {同 SW_SHOWNORMAL}
SW_SHOWDEFAULT     = 10; {同 SW_SHOWNORMAL}
SW_MAX             = 10; {同 SW_SHOWNORMAL}

    
    
//举例, 启动记事本: procedure TForm1.Button1Click(Sender: TObject); begin   WinExec('notepad.exe', SW_SHOWNORMAL); end;
posted on 2008-02-13 14:14 万一 阅读(8910) 评论(8) 编辑 收藏

FeedBack:
1696675
#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);

以上是我個人的心得, 如有什麼不妥, 請多多指教, 文筆不順的地方, 請多
見諒!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值