前两天有魅友问如何使用ShellExecuteEx这个API,正好自己也在写一个程序需要用到类似的技术,于是就简单的研究了下。网络是强大的,好好利用就能带给你好的知识。ShellExecuteEx的用法在网络中可以轻松找到使用方法。
首先我们得了解ShellExecuteEx存放在哪个头文件中,这个查MSDN即能了解到:ShellAPI.h。将这个头文件include到代码中就可以使用咯。在MSDN中说明了ShellExecuteEx的作用:Performs an action on a file.很明显他封装了WINDOWS用于打开一份文件的方法,这样程序员就能很简单的打开文件,不需要做巨多的处理。说到这可以知道有另一个API:ShellExecute,这个API则更简单可惜在WINDWOSCE中无法使用他(不知道是不是,我反正没找到),使用ShellExecute就可以直接运用如下的方式打开一份文件:
- ShellExecute(this->m_hWnd,"open","calc.exe","","", SW_SHOW );
- 或
- ShellExecute(this->m_hWnd,"open","notepad.exe",
- "c:\\MyLog.log","",SW_SHOW );
复制代码非常的简单吧,至于其中的理论概念不去了解也罢,只要知道使用即可。
回到本文的主题,即:打开并监控外部应用程序。。 嗯,通过前面的了解我们知道了ShellExecuteEx可以打开任意的WINDOWS文件,但有一个前提,就是文件必须在WINDOWS中有关联的应用程序,这样ShellExecuteEx就会通过设置的参数自动的调用了。
很好,那我们需要打开一个exe不就非常的简单了,是的,直接上代码:
-
- //设置台数
- SHELLEXECUTEINFO ShellInfo;
- memset(&ShellInfo, 0, sizeof(ShellInfo));
- ShellInfo.cbSize = sizeof(ShellInfo);
- ShellInfo.hwnd = NULL;
- ShellInfo.lpVerb = _T("open");//运行方式
- ShellInfo.lpFile = str_filename;//文件全名(包含了整个路径)
- ShellInfo.nShow = SW_SHOWNORMAL;//窗口显示方式
- ShellInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
- //运行吧。。。
- ShellExecuteEx(&ShellInfo);
复制代码在上面的代码中可以发现我分了两段注释,前面一段是设置打开应用程序的各种参数,这里面杂七杂八的设置就多了,就不详细说明了,本文中只要用到上述的代码即能达到目的。
OK,至此打开一个应用程序就实现咯。
接下来说一下如何监控ShellExecuteEx打开的文件呢?这个功能非常有用,也很简单,直接看代码吧:
- void CMainWnd::OpenFile(const TCHAR* str_filename)
- {
- //函数参数验证,代码我就省略了.......
- //设置参数
- SHELLEXECUTEINFO ShellInfo;
- memset(&ShellInfo, 0, sizeof(ShellInfo));
- ShellInfo.cbSize = sizeof(ShellInfo);
- ShellInfo.hwnd = NULL;
- ShellInfo.lpVerb = _T("open");
- ShellInfo.lpFile = str_filename;
- ShellInfo.nShow = SW_SHOWNORMAL;
- ShellInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
- ShellExecuteEx(&ShellInfo);
- ////监控程序
- HANDLE hProcess = ShellInfo.hProcess;
- if (hProcess != 0) {
- WaitForSingleObject(hProcess, INFINITE);
- CloseHandle(hProcess);
- }
- }
- }
复制代码OK,非常简单吧,就比前面的打开文件 代码多了几行代码,我们简单的分析一下代码:
HANDLE hProcess = ShellInfo.hProcess; 这个hProcess即是打开的文件返回的进程句柄,如果是打开的exe自然就是exe的进程句柄了。
if (hProcess != 0) { WaitForSingleObject(hProcess, INFINITE); CloseHandle(hProcess); } 上面这个if中的代码调用了
WaitForSingleObject(hProcess, INFINITE);
这个函数的作用是:Waits until the specified object is in the signaled state or the time-out interval elapses.
也就是说调用了WaitForSingleObject后,程序当前线程就会停止等待指定的对象状态恢复,也就是直到打开的文件关闭就会使当前线程继续。这样一个过程就达到了我们监控所打开文件的目的。
最后那句CloseHandle(hProcess)就是关闭通过ShellExecuteEx打开的文件资源。这样才会释放掉内存及其他系统资源。
嗯嗯,就这样了。。。