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
    评论
以下是一个简单的实现 Windows 应用程序的代码,可以根据用户输入的成绩计算对应的等级,并给出相应的提示。同时,程序还包含了对无效成绩的处理和退出功能。 ```c++ #include <Windows.h> #include <string> // 定义等级和分数的对应关系 const std::string GRADE_TABLE[] = { "D", "C", "B", "A" }; const int SCORE_TABLE[] = { 0, 60, 80, 90 }; // 窗口标题和控件 ID const char* WINDOW_TITLE = "Grade Calculator"; const int EDIT_CONTROL_ID = 1; const int BUTTON_CONTROL_ID = 2; // 窗口句柄和控件句柄 HWND g_hWnd; HWND g_hEdit; HWND g_hButton; // 处理按钮点击事件 void OnButtonClick() { // 获取用户输入的成绩 char buffer[256]; GetWindowTextA(g_hEdit, buffer, 256); int score = atoi(buffer); // 判断输入的成绩是否有效 if (score < 0 || score > 100) { MessageBoxA(g_hWnd, "Invalid score!", "Error", MB_OK); return; } // 计算对应的等级 int grade = 0; for (int i = 0; i < 4; i++) { if (score >= SCORE_TABLE[i]) { grade = i; } else { break; } } // 显示对应的等级 std::string message = "Grade: " + GRADE_TABLE[grade]; MessageBoxA(g_hWnd, message.c_str(), "Result", MB_OK); } // 处理窗口消息 LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: // 创建编辑框控件 g_hEdit = CreateWindowA("EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 20, 20, 200, 24, hWnd, (HMENU)EDIT_CONTROL_ID, NULL, NULL); // 创建按钮控件 g_hButton = CreateWindowA("BUTTON", "Calculate", WS_CHILD | WS_VISIBLE, 20, 60, 100, 30, hWnd, (HMENU)BUTTON_CONTROL_ID, NULL, NULL); break; case WM_COMMAND: // 处理按钮点击事件 if (LOWORD(wParam) == BUTTON_CONTROL_ID) { OnButtonClick(); } break; case WM_DESTROY: // 退出程序 PostQuitMessage(0); break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; } // 应用程序入口函数 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // 注册窗口类 WNDCLASSA wc = { 0 }; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszClassName = "GradeCalculator"; RegisterClassA(&wc); // 创建窗口 g_hWnd = CreateWindowA("GradeCalculator", WINDOW_TITLE, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 150, NULL, NULL, hInstance, NULL); // 显示窗口 ShowWindow(g_hWnd, nCmdShow); UpdateWindow(g_hWnd); // 消息循环 MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } ``` 这个程序用到了 Win32 API 来创建窗口和控件,并处理用户输入和按钮点击事件。通过判断用户输入的成绩是否有效,计算对应的等级,并给出提示。如果输入的成绩无效,程序会弹出一个提示框告诉用户。程序还包含了退出功能,用户可以通过关闭窗口或者按下 Alt + F4 来退出程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值