平时写程序时经常会遇到要执行一个外部程序实例或者某个命令行的情况,这可以使用CreateProcess来实现。
由于我们程序中通常只是将外部程序或者一个命令行运行起来,并不需要进行后续的控制,于是我将这个操作封装成了一个方便快速操作的函数CreateProcessQuick,一般情况下,应用程序名称不需要指定,我们只需指定后面的命令行参数。如果是运行notepad程序,则只需要指定lpCommandLine为"notepad"。
近期所做的一个功能是在程序中指定打印一个html文件,路径已知。使用processexplorer查看打印文件对话框的命令行为
"rundll32.exe" C:\Windows\system32\mshtml.dll,PrintHTML "C:\Users\cashey\Desktop\basicshow.tem.html"
注:即"rundll32.exe" C:\Windows\system32\mshtml.dll,PrintHTML "文件完整路径"
#include <windows.h> BOOL CreateProcessQuick(LPCTSTR lpApplicationName, LPTSTR lpCommandLine = NULL) { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); BOOL bRet = CreateProcess(lpApplicationName, lpCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return bRet; } int main() { LPTSTR lpCommandLine = TEXT("\"rundll32.exe\" C:\\Windows\\system32\\mshtml.dll,PrintHTML \"C:\\Users\\cashey\\Desktop\\basicshow.tem.html\""); CreateProcessQuick(NULL, lpCommandLine); return 0; }
注意CreateProcessQuick代码中在调用CreateProcess之后调用了再次CloseHandle。这是为了防止内核对象泄漏,因为我们创建了这个进程之后并不需要在本进程中对其进行控制,所以线程和进程句柄都可以关闭掉。注意,这里CloseHandle只是关闭掉了句柄,并不会终止掉我们创建的进程,因为进程是进行“引用计数”的,只要进程句柄引用计数没有降为0,则不会将进程的内核对象清理掉。(参考《Windows核心编程》)