用管道将cmd.exe信息输出到窗口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| void CParentDlg::OnBnClickedButton3() { SECURITY_ATTRIBUTES sa = {}; sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; ::CreatePipe(&m_hSelfRead, &m_hCmdWrite, &sa, 0); ::CreatePipe(&m_hCmdRead, &m_hSelfWrite, &sa, 0);
STARTUPINFO si = {}; si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = m_hCmdRead; si.hStdOutput = m_hCmdWrite;
PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); if (!CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) ) { printf("CreateProcess failed (%d).\n", GetLastError()); return; } CloseHandle(pi.hProcess); CloseHandle(pi.hThread); }
void CParentDlg::OnBnClickedButton4() { CString strBuf; GetDlgItemText(EDT_COMD, strBuf); strBuf += "\r\n"; BOOL bRet = WriteFile(m_hSelfWrite, strBuf.GetBuffer(), strBuf.GetLength(), NULL, NULL); if (!bRet) { AfxMessageBox("写入管道失败"); } }
void CParentDlg::OnBnClickedButton5() { DWORD dwBytesAvail = 0; BOOL bRet = ::PeekNamedPipe(m_hSelfRead, NULL, 0, NULL, &dwBytesAvail, NULL); if (!bRet) { AfxMessageBox("无法查看管道剩余数据"); return; } if (dwBytesAvail > 0) { CString strBuf; DWORD dwBytesToRead = 0; BOOL bRet = ::ReadFile( m_hSelfRead, strBuf.GetBufferSetLength(MAXBYTE), MAXBYTE, &dwBytesToRead, NULL ); if (!bRet) { AfxMessageBox("读取数据失败"); return; } strBuf.ReleaseBuffer(dwBytesToRead); SetDlgItemText(EDT_SHOW, strBuf); } }
|
分析:
1 2 3 4 5 6 7 8 9
| ::CreatePipe(&m_hSelfRead, &m_hCmdWrite, &sa, 0); ::CreatePipe(&m_hCmdRead, &m_hSelfWrite, &sa, 0);
STARTUPINFO si = {}; si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = m_hCmdRead; si.hStdOutput = m_hCmdWrite;
|
第一个管道:::CreatePipe(&m_hSelfRead, &m_hCmdWrite, &sa, 0);
- **
m_hSelfRead
**:父进程读取句柄。父进程通过这个句柄从管道中读取数据,即从子进程 cmd.exe
的输出中读取数据。
- **
m_hCmdWrite
**:子进程写入句柄。子进程通过这个句柄向管道中写入数据,即将 cmd.exe
的输出写入管道。
第二个管道:::CreatePipe(&m_hCmdRead, &m_hSelfWrite, &sa, 0);
- **
m_hCmdRead
**:子进程读取句柄。子进程通过这个句柄从管道中读取数据,即从父进程输入的数据。
- **
m_hSelfWrite
**:父进程写入句柄。父进程通过这个句柄向管道中写入数据,即将命令输入到 cmd.exe
。
在 STARTUPINFO
结构体中,si.hStdInput
和 si.hStdOutput
应该分别设置为用于输入和输出的管道句柄,以便父进程可以通过这些句柄与子进程 cmd.exe
进行通信。正确的设置方式:
- **
si.hStdInput
**:设置为子进程的读取句柄 m_hCmdRead
(由句柄m_hSelfWrite写入,m_hCmdRead在子进程读出)这意味着子进程将从此管道读取数据。
- **
si.hStdOutput
**:设置为子进程的写入句柄 m_hCmdWrite
(由句柄m_hCmdWrite写入,由m_hSelfRead在父进程读出),这意味着子进程将把输出数据写入此管道。