如何使cmd的输入和输出重定向到管道中(用这种方法可以将指令写入cmd并抓取输出)
/
//??????????????????????????????????????????????????????????????? ? ? ? ? ? ? ? ? ? ??? //
//???????? ------- 如何使cmd的輸入和輸出重定向到管道中 -------?????? //
//??????? ------- 用這種方法可以將指令寫入cmd并抓取輸出 -------???? //
//???????????????????????????????????????????????????????????????????????????????????? //
//??? --------- chendana's implements, modified by chenth ---------??? //
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
HANDLE hRead1,hWrite1;?? //讀句柄,寫句柄
HANDLE hRead2,hWrite2;?? //讀句柄,寫句柄
HANDLE hCmd;
int CreateCMD(HANDLE &hReadPipe1,HANDLE &hWritePipe1,//匿名管道1讀寫句柄
??? ??? ??? ?? HANDLE &hReadPipe2,HANDLE &hWritePipe2,//匿名管道2讀寫句柄
??? ??? ??? ?? HANDLE &hProcess)//創建的CMD.EXE進程句柄
{
??? int ret;
??? SECURITY_ATTRIBUTES sa;
??? sa.nLength=12;
??? sa.lpSecurityDescriptor=0;
??? sa.bInheritHandle=true;
??? ret=CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0);
??? if (ret == 0)
??? {
??? ??? return -1;
??? }
??? ret=CreatePipe(&hReadPipe2,&hWritePipe2,&sa,0);
??? if (ret == 0)
??? {
??? ??? return -1;
??? }
??? STARTUPINFO si;
??? ZeroMemory(&si,sizeof(si));
??? si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
??? si.wShowWindow = SW_SHOW;//SW_HIDE
??? //創建進程且重定向標準輸入輸出
??? //將其標準輸入設置為hReadPipe2
??? //將其標準輸出和錯誤輸出設置為hWritePipe1
??? //通信邏輯見上圖
??? si.hStdInput = hReadPipe2;
??? si.hStdOutput = si.hStdError = hWritePipe1;
??? char cmdLine[] = "cmd";
??? PROCESS_INFORMATION ProcessInformation;
??? ret=CreateProcess(NULL,(LPSTR)cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&ProcessInformation);
??? if (ret == 0)
??? {
??? ??? return -1;
??? }
??? hProcess=ProcessInformation.hProcess;
??? return 0;
}
//****************************************************************************
//此函數用來寫已建立的管道
int WriteCMD(char* cmdBuffer,HANDLE hWritePipe2)
{
??? DWORD lBytesWrite;
??? char cmd_tmp[1024]="";
??? printf("writing.../n");
??? sprintf_s(cmd_tmp,1024,"%s%s",cmdBuffer,"/r/n");
??? if (!WriteFile(hWritePipe2,(LPTSTR)cmd_tmp,strlen(cmd_tmp),&lBytesWrite,NULL))
??? {
??? ??? return -1;
??? }
??? return 0;
}
//****************************************************************************
//此函數用來讀已建立的管道
int ReadCMD(HANDLE hReadPipe1,string &cmdResult){
??? BOOL ret;
??? DWORD lBytesRead;
??? char *buffer=new char [1024];
??? while(true)
??? {
??? ??? printf("reading.../n");
??? ??? Sleep(99);
??? ??? memset(buffer,0,1024);
??? ??? ret=ReadFile(hReadPipe1,buffer,1023,&lBytesRead,0);
??? ??? if (ret == 0)
??? ??? {
??? ??? ??? delete buffer;
??? ??? ??? return -1;
??? ??? }
??? ??? buffer[lBytesRead]='/0';
??????? cmdResult += buffer;
??? ??? if(buffer[lBytesRead-1]=='>')
??? ??? {
??? ??? ??? delete buffer;
??? ??? ??? return 0;
??? ??? }
??? }
??? delete buffer;
??? return 0;
}
//*****************************************************************************
//此函數用來關閉管道
void CloseCMD(HANDLE hReadPipe1,HANDLE hWritePipe1,//匿名管道1讀寫句柄
??? ??? ??? ? HANDLE hReadPipe2,HANDLE hWritePipe2,//匿名管道2讀寫句柄
??? ??? ??? ? HANDLE hProcess)//創建的CMD.EXE進程句柄
{
??? CloseHandle(hReadPipe1);
??? CloseHandle(hWritePipe1);
??? CloseHandle(hWritePipe2);
??? CloseHandle(hReadPipe2);
??? TerminateProcess(hProcess,0);
}
//*****************************************************************************
//此函數用來清空管道數據
void EmptyPipe(HANDLE hReadPipe1){
??? BOOL ret;
??? DWORD bytesRead;
??? char *buffer=new char [1024];
??? while(true)
??? {
??? ??? memset(buffer,0,1024);
??? ??? ret=PeekNamedPipe(hReadPipe1,buffer,1024,&bytesRead,0,0);
??? ??? if (bytesRead==0||!ret)
??? ??? {
??? ??? ??? delete buffer;
??? ??? ??? return;
??? ??? }
??? ??? ReadFile(hReadPipe1,buffer,bytesRead,&bytesRead,0);
??? }
}
//?? ------------------ Sample codes by chenth ------------------?? //
int main( int argc, char *argv[] )
{
??? string result;
??? DWORD dw;
???
??? if (CreateCMD(hRead1,hWrite1,hRead2,hWrite2,hCmd) < 0)
??? {
??? ??? printf("CreateCMD 失敗?? ");
??? ??? dw = GetLastError();
??? ??? printf("GetLastError-->%u/n", dw);
??? ??? ExitProcess(dw);
??? ??? return -1;
??? }
??? if (WriteCMD("dir",hWrite2) < 0)
??? {
??? ??? printf("WriteCMD 失敗?? ");
??? ??? dw = GetLastError();
??? ??? printf("GetLastError-->%u/n", dw);
??? ??? ExitProcess(dw);
??? ??? return -1;
??? }
??? if (ReadCMD(hRead1,result) < 0)
??? {
??? ??? printf("ReadCMD 失敗?? ");
??? ??? dw = GetLastError();
??? ??? printf("GetLastError-->%u/n", dw);
??? ??? ExitProcess(dw);
??? ??? return -1;
??? }
??? printf("**********************************************/n");
??? printf("%s/n",result.c_str());
??? printf("**********************************************/n");
??? CloseCMD(hRead1,hWrite1,hRead2,hWrite2,hCmd);
??? return 0;
}
?
//很重要一點:需要在IDE中把編碼設置成“多字節字符集(MBCS)”而不是UNICODE!為了這個我折騰了大半天。
總結
以上是生活随笔為你收集整理的如何使cmd的输入和输出重定向到管道中(用这种方法可以将指令写入cmd并抓取输出)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GetLastError返回值的意义--
- 下一篇: 蛋花花上征信吗