远程执行CMD命令部分代码的方法

远程执行CMD命令部分代码的方法

/******************************************************************************
下面代码创建了一个子进程(cmd.exe),并且把cmd.exe的标准输入用第二个管道的
读句柄替换。cmd.exe的标准输出和标准错误输出用第一个管道的写句柄替换。
这两个管道的逻辑示意图如下:
读hReadPipe1写hWritePipe1
(父进程) read<---〔管道一〕<---write 标准输出(cmd.exe子进程)

写hWritePipe2读hReadPipe2
(父进程) write--->〔管道二〕--->read 标准输入(cmd.exe子进程)

函数参数:返回读写管道和建立的进程句柄(在CHCCDlg类里定义这几个全局变量)
******************************************************************************/
BOOL CreateCMD(HANDLE &hReadPipe1,HANDLE &hWritePipe1,//匿名管道1读写句柄
HANDLE &hReadPipe2,HANDLE &hWritePipe2,//匿名管道2读写句柄
HANDLE &hProcess)//创建的CMD.EXE进程句柄
{
BOOL ret;
SECURITY_ATTRIBUTES sa;
sa.nLength=12;sa.lpSecurityDescriptor=0;sa.bInheritHandle=true;
ret=CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0);
if (!ret) {
return FALSE;
}
ret=CreatePipe(&hReadPipe2,&hWritePipe2,&sa,0);
if (!ret) {
return FALSE;
}

STARTUPINFO si;
ZeroMemory(&si,sizeof(si));
si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;

//将其标准输入设置为hReadPipe2
//将其标准输出和错误输出设置为hWritePipe1
//通信逻辑见上图
si.hStdInput = hReadPipe2;
si.hStdOutput = si.hStdError = hWritePipe1;
char cmdLine[] = "cmd.exe";
PROCESS_INFORMATION ProcessInformation;
ret=CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&ProcessInformation);
if (!ret) {
return FALSE;
}
hProcess=ProcessInformation.hProcess;
return TRUE;
}

//****************************************************************************
//此函数用来写已建立的管道
BOOL WriteCMD(CString cmdBuffer,HANDLE hWritePipe2){
DWORD lBytesWrite;
cmdBuffer+="/r/n";
if (!WriteFile(hWritePipe2,(LPTSTR)(LPCTSTR)cmdBuffer,cmdBuffer.GetLength(),&lBytesWrite,NULL)) {
return FALSE;
}
return TRUE;
}
//****************************************************************************
//此函数用来读已建立的管道
BOOL ReadCMD(HANDLE hReadPipe1,CString &cmdResult){
BOOL ret;
DWORD lBytesRead;
char *buffer=new char [1024];
while(true){
memset(buffer,0,1024);
ret=ReadFile(hReadPipe1,buffer,1023,&lBytesRead,0);
if (!ret) {
delete buffer;
return FALSE;
}
buffer[lBytesRead]='/0';
cmdResult += buffer;
if(buffer[lBytesRead-1]=='>') {
delete buffer;
return TRUE;
}
}
delete buffer;
return TRUE;
}
//*****************************************************************************
//此函数用来关闭管道
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);
}
}

//以上函数只需在SOCKET的OnReveive( )函数中调用便可以方便的开一个远程SHELL执行命令