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("\r\n\r\n");

		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、下面是程序截图:










最后,程序源代码:http://download.csdn.net/detail/wwkaven/7555011

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值