远程CMD的过程,就是服务器发送命令,客户端执行,客户端把命令交给CMD执行, CMD把执行之后的返回数据交给客户端,客户端返回。其中,CMD与客户端的交互,需要用到管道。此处有例子一个。贴在这里。
// cmdTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <afx.h>
#include <Windows.h>
#include <atlbase.h>
#include <string>
using namespace std;
BOOL CreateCMD(HANDLE &hReadPipe1,HANDLE &hWritePipe1,//匿名管道1读写句柄
HANDLE &hReadPipe2,HANDLE &hWritePipe2,//匿名管道2读写句柄
HANDLE &hProcess)//创建的CMD.EXE进程句柄
{
BOOL ret;
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(sa);
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;
si.lpDesktop = "WinSta0\\Default";
//创建进程且重定向标准输入输出
//将其标准输入设置为hReadPipe2
si.hStdInput = hReadPipe2;
//将其标准输出和错误输出设置为hWritePipe1
si.hStdOutput = si.hStdError = hWritePipe1;
char cmdLine[] = "cmd.exe /k";
PROCESS_INFORMATION pi;
ret=CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&pi);
if (!ret) {
return FALSE;
}
hProcess=pi.hProcess;
CloseHandle(pi.hThread);
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);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hRead1,hWrite1; //读句柄,写句柄
HANDLE hRead2,hWrite2; //读句柄,写句柄
HANDLE hCmd;
CString 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 (ReadCMD(hRead1,result) < 0)
{
printf("ReadCMD 失败 ");
dw = GetLastError();
printf("GetLastError-->%u\n", dw);
ExitProcess(dw);
return -1;
}
printf("%s",result);
result.Empty();
char szBuf[MAX_PATH];
while (true)
{
ZeroMemory(szBuf,MAX_PATH);
gets(szBuf);
if (WriteCMD(szBuf,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;
}
int i= result.Find("\r\n");
result = result.Mid(i+2);
printf("%s",result);
result.Empty();
}
CloseCMD(hRead1,hWrite1,hRead2,hWrite2,hCmd);
system("pause");
return 0;
}