VC中调用CMD命令并获取调用结果
主要实现方法是建立一个新进程,用于运行一个隐藏窗口的CMD程序,进而通过匿名管道获取执行结果。注意一点,这样的方法每执行一条命令都会打开一个新的CMD窗口,只不过普通命令在执行完后会自动关闭。但是,ping命令加上参数“-t”,将会一直执行,所以相对应的CMD窗口也会一直存在,需要自行关闭。
另外,外了防止程序假死,创建一个新线程用于获取执行CMD命令的结果。
下面是具体实现:
1、创建基于对对话框的应用程序,放置两个Edit控件,使用默认ID,再添加一个按钮。
声明一个线程函数:
// 声明线程函数 static DWORD WINAPI ThreadFun(LPVOID lpParam);
2、声明几个全局变量
// 全局变量 HANDLE h1 = NULL; // 线程句柄 DWORD pid = 0; // 保存cmd窗口的PID CString inputCmd, outputCmd; // 保存cmd命令和返回的结果 CEdit * m_edit; // 输出框
3、线程函数的实现:
/************************************************************************/ /* 线程函数 */ /************************************************************************/ DWORD WINAPI CSysCmdTestDlg::ThreadFun(LPVOID lpParam) { SECURITY_ATTRIBUTES sa; HANDLE hRead,hWrite; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; //使用系统默认的安全描述符 sa.bInheritHandle = TRUE; //创建的进程继承句柄 if (!CreatePipe(&hRead,&hWrite,&sa,0)) //创建匿名管道 { ::MessageBox(NULL,"CreatePipe Failed!","提示",MB_OK | MB_ICONWARNING); return 0; } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si,sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); GetStartupInfo(&si); si.hStdError = hWrite; si.hStdOutput = hWrite; //新创建进程的标准输出连在写管道一端 si.wShowWindow = SW_HIDE; //隐藏窗口 si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; char cmdline[200]; CString tmp,stredit2; tmp.Format("cmd /C %s",inputCmd); // inputCmd为输入的cmd命令 sprintf(cmdline,"%s",tmp); if (!CreateProcess(NULL,cmdline,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)) //创建子进程 { ::MessageBox(NULL,"CreateProcess Failed!","提示",MB_OK | MB_ICONWARNING); return 0; } pid = pi.dwProcessId; CloseHandle(hWrite); //关闭管道句柄 char buffer[4096] = {0}; DWORD bytesRead; while (true) { if (ReadFile(hRead,buffer,4095,&bytesRead,NULL) == NULL) //读取管道 break; CString temp; temp = buffer; // outpuuCmd为输出的结果 temp += _T(" "); outputCmd += temp; //显示输出信息到编辑框,并刷新窗口 int len = outputCmd.GetLength(); m_edit->SetWindowText(outputCmd); m_edit->SetSel(len, len); } CloseHandle(hRead); return 1; }
4、添加一个按钮,响应函数为:
void CSysCmdTestDlg::OnButton1() { // TODO: Add your control notification handler code here GetDlgItemText(IDC_EDIT2,inputCmd); //获取编辑框中输入的命令行 // 关闭CMD窗口 ::SendMessage(GetWindowHandleByPID(pid), WM_CLOSE, NULL, NULL); // 销毁线程 CloseHandle(h1); // 创建线程 h1 = ::CreateThread(NULL, 0, ThreadFun, NULL, 0, 0); }
5、程序退出时的一些处理:
响应WM_CLOSE消息
void CSysCmdTestDlg::OnClose() { // TODO: Add your message handler code here and/or call default // 关闭CMD窗口 ::SendMessage(GetWindowHandleByPID(pid), WM_CLOSE, NULL, NULL); // 销毁线程 CloseHandle(h1); CDialog::OnClose(); }
6、下面是程序截图:
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: C++ 操作cmd并返回结果
- 下一篇: laravel 关于图片路径问题的一个坑