C++标准输入输出重定向

22 篇文章 0 订阅
//ProcessStdInOut.cpp
//用法:
//    argv[1]是子进程的包含路径的完整可执行文件名
//    argv[2]是代替子程序StdIn的输入文件
//    argv[3]是代替子程序StdOut的输出文件
//    ProcessStdInOut C:\test.exe my_in.in my_out.out
//编译:
//    cl ProcessStdInOut.cpp
//功能:
//    把子进程的标准输入重定向到自己的文件输入,
//    并把子进程的标准输出重定向到自己的文件输出

#include <stdio.h>
#include <windows.h>
#define BUFSIZE 4096
int main(int argc, char *argv[])
{
	//在CreatePipe、CreateProcess等Create系列函数中,
	//通常都有一个SECURITY_ATTRIBUTES类型的参数
	SECURITY_ATTRIBUTES saAttr = {0};
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
	//若把该参数的bInheritHandle项设为TRUE,
	//则它创建出来的句柄可被子进程继承。
	//例如,用CreatePipe创建的管道可用于CreateProcess创建的进程
	saAttr.bInheritHandle = TRUE; 
	saAttr.lpSecurityDescriptor = NULL;
	
	//ChildIn_Write是子进程的输入句柄,ChildIn_Read是父进程用于写入子进程输入的句柄
	HANDLE ChildIn_Read, ChildIn_Write;
	CreatePipe(&ChildIn_Read, &ChildIn_Write, &saAttr, 0);
	//设置子进程不能继承接收输入管道的另一端:ChildIn_Write
	SetHandleInformation(ChildIn_Write, HANDLE_FLAG_INHERIT, 0);
	//ChildOut_Write是子进程的输出句柄,ChildOut_Read是父进程用于读取子进程输出的句柄
	HANDLE ChildOut_Read, ChildOut_Write;
	CreatePipe(&ChildOut_Read, &ChildOut_Write, &saAttr, 0);
	//设置子进程不能继承发送输出管道的另一端:ChildOut_Read
	SetHandleInformation(ChildOut_Read, HANDLE_FLAG_INHERIT, 0);
	
	//CreateProcess的第一个参数
	STARTUPINFO StartupInfo = {0};
	StartupInfo.cb = sizeof(STARTUPINFO);
	//将标准输出和错误输出定向到我们建立的ChildOut_Write上
	StartupInfo.hStdError = ChildOut_Write; 
	StartupInfo.hStdOutput = ChildOut_Write;
	//将标准输入定向到我们建立的ChildIn_Read上
	StartupInfo.hStdInput = ChildIn_Read;
	//设置子进程接受StdIn以及StdOut的重定向
	StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
	
	//CreateProcess的第二个参数
	PROCESS_INFORMATION ProcessInfo = {0};
	
	CreateProcess(NULL, argv[1], NULL, NULL, TRUE, NULL, NULL, NULL, &StartupInfo, &ProcessInfo);
	
	//读入文件输入,并将其传递给子进程的标准输入
	HANDLE InputFile = CreateFile(argv[2], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
	BOOL flag = FALSE;
	while (true)
	{
		char buffer[BUFSIZE] = {0};
		DWORD BytesRead, BytesWritten;
		//从文件读入
		flag = ReadFile(InputFile, buffer, BUFSIZE, &BytesRead, NULL);
		if (!flag || (BytesRead == 0)) break;
		//输出到子进程
		flag = WriteFile(ChildIn_Write, buffer, BytesRead, &BytesWritten, NULL);
		if (!flag) break;
	}
	CloseHandle(InputFile);
	//关闭父进程的输入管道,否则若父进程没有输入,子进程会一直被挂起
	CloseHandle(ChildIn_Write);
	
	//这里不需要等待子进程结束
	
	//关闭子进程的输出管道,否则若子进程没有输出,父进程会一直被挂起
	CloseHandle(ChildOut_Write);
	//读取子进程的标准输出,并将其传递给文件输出
	HANDLE OutputFile = CreateFile(argv[3], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	while (true)
	{
		char buffer[BUFSIZE] = {0};
		DWORD BytesRead, BytesWritten;
		//从子进程读入
		flag = ReadFile(ChildOut_Read, buffer, BUFSIZE, &BytesRead, NULL);
		if (!flag || (BytesRead == 0)) break;
		//输出到文件
		flag = WriteFile(OutputFile, buffer, BytesRead, &BytesWritten, NULL);
		if (!flag) break;
	}
	CloseHandle(OutputFile);
	
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值