欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

使用CreatePipe实现双通道与本地cmd.exe进程的通信(附带源代码和可下载的编译程序,完全免费)

最编程 2024-08-02 09:10:58
...

大家好,又见面了,我是你们的朋友全栈君。

简介:

在本地,用父进程创建一个cmd.exe子进程,这个子进程的输入输出被重定向到两条匿名管道,从而实现与父进程通信。父进程输入命令到一条管道,子进程读取后执行并输出到另一条管道,父进程读取后输出到窗口。 此版本源代码借鉴并修改、优化了前人的创作,详见:https://blog.****.net/aq782645210/article/details/16370409 中的评论

源代码:

#include <stdio.h>
#include <WINDOWS.H>
#define SEND_BUFF_SIZE 1024
 
//实现去除执行结果中的 "命令\n"
void print(char *cmdstr)
{ 
   
	while(*((char*)cmdstr++)!='\n');
	printf(cmdstr);
}
 
 
 
int main()
{ 
   
	HANDLE hReadPipe1,hWritePipe1,hReadPipe2,hWritePipe2; //四个HANDLE 用来创建两个管道
	CHAR Buff[SEND_BUFF_SIZE] = { 
   0};
    CHAR sendBuff[SEND_BUFF_SIZE] = ("dir \n");
 
	//安全属性的东西
    SECURITY_ATTRIBUTES sa;
    sa.nLength=sizeof(sa);
    sa.lpSecurityDescriptor=0;
    sa.bInheritHandle=true;    
    int ret;
	
    if(!CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0))//创建两个匿名管道,以改变DOS的标准输入输出
    { 
   
        return -1;
    }
    if(!CreatePipe(&hReadPipe2,&hWritePipe2,&sa,0))
    { 
   
        return -1;
    }
	
	//启动信息
    STARTUPINFO si;
    ZeroMemory(&si,sizeof(si));
    //GetStartupInfo(&si);
    si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdInput = hReadPipe2;
    si.hStdOutput = si.hStdError = hWritePipe1;
	
    char cmdLine[256] = { 
   0};
    GetSystemDirectory(cmdLine,sizeof(cmdLine));
    strcat(cmdLine, ("\\cmd.exe"));
	
    PROCESS_INFORMATION ProcessInformation;
    if(CreateProcess(cmdLine,NULL,NULL,NULL,TRUE,0,NULL,NULL,&si,&ProcessInformation) == 0)
    { 
   
        return -1;
    }
	
 
    unsigned long lBytesRead,lBytesWrite;//存放实际读写字节的变量
	
	while(TRUE){ 
   
		lBytesRead=0;
		Sleep(50);//等待cmd程序执行
		ret=PeekNamedPipe(hReadPipe1,Buff,SEND_BUFF_SIZE,&lBytesRead,0,0);//管道是否有数据可读
		if(lBytesRead)    
		{ 
   
            //第一次可以读到cmd的初始化信息
            ret=ReadFile(hReadPipe1,Buff,SEND_BUFF_SIZE,&lBytesRead,0);//读取管道里的数据
            //如果读到数据,则对数据进行下一步处理
			print(Buff);
			ZeroMemory(Buff,sizeof(Buff));	
		}
		else{ 
   //管道中无数据时输入命令,以回车结束
			
			char ch;
			int count=0;
			ZeroMemory(sendBuff,sizeof(sendBuff));
			while((ch=getchar())!='\n')
			{ 
   
				sendBuff[count]=ch;
				count++;
			}
			sendBuff[count++]='\n';

			if(!WriteFile(hWritePipe2, sendBuff,count,&lBytesWrite,0))//写入数据 
			{ 
   
				printf("WriteFile Error!!\n");
				return -1;
			}
			//等待cmd程序执行
			Sleep(100);
		}
	}
    
}

编译好的程序:

https://pan.baidu.com/s/1VUtnTyqMHnv588RcJweohQ