摘自 vc知识库 关键代码: //myIDEDlg.cpp UINT CMyIDEDlg::myThread(LPVOID pParam) { PROCESS_INFORMATION pi; STARTUPINFO siStartInfo; SECURITY_ATTRIBUTES saAttr; CString Output, tmp; char command_line[200]; DWORD dwRead; char* buf; int len; HANDLE hRead, hWrite; CMyIDEDlg* pDlg = (CMyIDEDlg*)pParam; // 创建与wSpawn.exe通讯的可继承的匿名管道 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; if (!CreatePipe(&hRead, &hWrite, &saAttr, 0)) { AfxMessageBox("创建管道失败"); return 0; } // 准备wSpawn的命令行,在命令行给出写管道句柄和要wSpawn执行的命令 memset(&pi, 0, sizeof(pi)); // sprintf(command_line, "wspawn -h %d Rar /?", (unsigned int)hWrite); sprintf(command_line, "wspawn -h %d hrd.exe", (unsigned int)hWrite); // sprintf(command_line, "wspawn -h %d 华容道.exe", (unsigned int)hWrite); // 子进程以隐藏方式运行 ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.wShowWindow = SW_HIDE; siStartInfo.dwFlags = STARTF_USESHOWWINDOW; // 创建wSpawn子进程 if (!CreateProcess( NULL, command_line, NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &pi)) { AfxMessageBox("调用wSpawn时失败"); return 0; } // 读管道,并显示wSpawn从管道中返回的输出信息 if(!ReadFile( hRead, &len, sizeof(int), &dwRead, NULL) || dwRead == 0) return 0; while(len) { buf = new char[len + 1]; memset(buf, 0, len + 1); if(!ReadFile( hRead, buf, len, &dwRead, NULL) || dwRead == 0) return 0; // 将返回信息中的"/n"替换为Edit Box可识别的"/r/n" tmp = buf; tmp.Replace("/n", "/r/n"); Output += tmp; // 将结果显示在Edit Box中,并刷新对话框 // pDlg->m_edit1.SetWindowText(Output); pDlg->m_edit1.SetWindowText(buf); // pDlg->InvalidateRect(NULL); pDlg->m_edit1.LineScroll(pDlg->m_edit1.GetLineCount()); pDlg->UpdateWindow(); delete[] buf; if(!ReadFile( hRead, &len, sizeof(int), &dwRead, NULL) || dwRead == 0) return 0; } // 等待wSpawn结束 WaitForSingleObject(pi.hProcess, 30000); // 关闭管道句柄 CloseHandle(hRead); CloseHandle(hWrite); return 0; } void CMyIDEDlg::OnOK() { AfxBeginThread(myThread, this); // InvalidateRect(NULL); CMyIDEDlg* pDlg = this; pDlg->m_edit1.LineScroll(pDlg->m_edit1.GetLineCount()); UpdateWindow(); } //wSpawn.cpp #include <stdlib.h> #include <stdio.h> #include <string.h> #include <string> #include <windows.h> using namespace std; void exit_friendly(void) { puts("请不要单独运行wSpawn."); exit(0); } int main( int argc, char *argv[] ) { HANDLE hWrite = NULL; DWORD dwWrited; int i = 0, ret = 0, len = 0; char psBuffer[256]; FILE* child_output; string command_line = ""; // 检查命令行,如存在管道句柄,则将其转换为HANDLE类型 if (argc < 2) exit_friendly(); if (!stricmp(argv[1], "-h")) { if (argc < 4) exit_friendly(); hWrite = (HANDLE)atoi(argv[2]); i = 3; } else i = 1; // 提取要执行的命令 for (; i < argc; i++) { command_line += argv[i]; command_line += " "; } // 使用_popen创建子进程并重定向其标准输出到文件指针中 if( (child_output = _popen( command_line.c_str(), "rt" )) == NULL ) exit( 1 ); while( !feof( child_output ) ) { if( fgets( psBuffer, 255, child_output ) != NULL ) { if (hWrite) { // 将子进程的标准输出写入管道,提供给自己的父进程 // 格式是先写数据块长度(0表示结束),再写数据块内容 len = strlen(psBuffer); WriteFile(hWrite, &len, sizeof(int), &dwWrited, NULL); WriteFile(hWrite, psBuffer, len, &dwWrited, NULL); } else // 如命令行未提供管道句柄,则直接打印输出 printf(psBuffer); } } // 写“0”表示所有数据都已写完 len = 0; if (hWrite) WriteFile(hWrite, &len, sizeof(int), &dwWrited, NULL); return _pclose( child_output ); }