C++实现重定向命令以及管道命令

// >命令

char* Get_Char(char **command,int count) {
	int len = Get_Count(command[count - 1]);
	char *wth = new char[len + 1];
	for (int i = 0; i < len; i++) {
		wth[i] = command[count - 1][i];
	}
	wth[len] = '\0';
	return wth;
}

DWORD Get_Actuall(char *p) {  //获得缓冲区数据实际的大小
	int i = 0;
	while (p[i] != '\0') {
		i++;
	}
	return i;
}

wchar_t *char2LPCTSTR(char **command, int count) {

	int len = Get_Count(command[count - 1]);
	wchar_t *wth = new wchar_t[len + 1];
	for (int i = 0; i < len; i++) {
		wth[i] = command[count - 1][i];
	}
	wth[len] = '\0';
	return wth;
}

wchar_t *char2LPCTSTR(char *p) {  //将char *转换为wchar_t

	int len = Get_Count(p);
	wchar_t *wth = new wchar_t[len + 1];
	for (int i = 0; i < len; i++) {
		wth[i] = p[i];
	}
	wth[len] = '\0';
	return wth;
}

TCHAR *char2TCHAR(char **command, int count) {

	int len = Get_Count(command[count - 1]);
	TCHAR *wth = new TCHAR[len + 1];
	for (int i = 0; i < len; i++) {
		wth[i] = command[count - 1][i];
	}
	wth[len] = '\0';
	return wth;
}
// >

void Redirection_1(char **&command,int count) {
	wchar_t *path = char2LPCTSTR(command,count);
	LPCTSTR  outputFile = path;
	SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
	HANDLE hFile = CreateFile(
		outputFile,
		GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		&sa,
		TRUNCATE_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL);

	if (hFile == INVALID_HANDLE_VALUE) {
		//int err = GetLastError();
		return;
	}

	STARTUPINFO si = { sizeof(si) };
	PROCESS_INFORMATION pi = { 0 };
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si.wShowWindow = SW_HIDE; //不显示创建的进程的窗口
	si.hStdOutput = hFile;//重定向输出句柄为之前创建的文件句柄
	TCHAR *cmdline = char2TCHAR(command,1);
	//SetFilePointer(hFile, 0, NULL, FILE_END);  
	if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) {
		//等待打开的进程结束并关闭相关句柄
		WaitForSingleObject(pi.hProcess, INFINITE);
		::CloseHandle(pi.hThread);
		::CloseHandle(pi.hProcess);
	} else {
		int err = GetLastError();
	}
	//关闭文件句柄
	CloseHandle(hFile);

}

// >>命令
void Redirection_2(char **&command, int count) {
	wchar_t *path = char2LPCTSTR(command, count);
	LPCTSTR  outputFile = path;
	SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
	HANDLE hFile = CreateFile(
		outputFile,
		GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		&sa,
		OPEN_ALWAYS /*| TRUNCATE_EXISTING*/,
		FILE_ATTRIBUTE_NORMAL,
		NULL);

	if (hFile == INVALID_HANDLE_VALUE) {
		//int err = GetLastError();
		return;
	}

	STARTUPINFO si = { sizeof(si) };
	PROCESS_INFORMATION pi = { 0 };
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si.wShowWindow = SW_HIDE; //不显示创建的进程的窗口
	si.hStdOutput = hFile;//重定向输出句柄为之前创建的文件句柄
	TCHAR *cmdline = char2TCHAR(command, 1);
	SetFilePointer(hFile, 0, NULL, FILE_END);  //定位到文件尾部
	if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) {
		//等待打开的进程结束并关闭相关句柄
		WaitForSingleObject(pi.hProcess, INFINITE);
		::CloseHandle(pi.hThread);
		::CloseHandle(pi.hProcess);
	}
	else {
		int err = GetLastError();
	}
	//关闭文件句柄
	CloseHandle(hFile);
}

// <命令
void Redirection_3(char **&command, int count) {
	wchar_t *path = char2LPCTSTR(command, count);
	LPCTSTR  inputFile = path;
	SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
	HANDLE hFile = CreateFile(
		inputFile,
		GENERIC_READ,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		&sa,
		OPEN_ALWAYS /*| TRUNCATE_EXISTING*/,
		FILE_ATTRIBUTE_NORMAL,
		NULL);

	if (hFile == INVALID_HANDLE_VALUE) {
		//int err = GetLastError();
		return;
	}

	//以下是为了验证读取的正确性
	char *p = "temp.txt";
	wchar_t *path1 = char2LPCTSTR(p);
	LPCTSTR  outputFile = path1;
	HANDLE hOutput = CreateFile(
		outputFile, 
		GENERIC_WRITE, 
		0, 
		&sa, 
		CREATE_ALWAYS, 
		FILE_ATTRIBUTE_NORMAL, 
		NULL);
	if (hOutput == INVALID_HANDLE_VALUE) {
		return;
	}
	//以上是为了验证读取的正确性

	STARTUPINFO si = { sizeof(si) };
	PROCESS_INFORMATION pi = { 0 };
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;;
	si.wShowWindow = SW_HIDE; //不显示创建的进程的窗口
	si.hStdInput = hFile;//重定向输入句柄为之前创建的文件句柄
	si.hStdOutput = hOutput; //重定向输出句柄为之前创建的文件句柄
	TCHAR *cmdline = char2TCHAR(command, 1);
	if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) {
		//等待打开的进程结束并关闭相关句柄
		WaitForSingleObject(pi.hProcess, INFINITE);
		::CloseHandle(pi.hThread);
		::CloseHandle(pi.hProcess);
	}
	else {
		int err = GetLastError();
	}
	//关闭文件句柄
	CloseHandle(hFile);
	CloseHandle(hOutput);
}

// <<命令
void Redirection_4(char **&command, int count) {
	
	HANDLE hRead = NULL;
	HANDLE hWrite = NULL;

	SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
	// 新创建的进程继承管道读写句柄
	if (FALSE == CreatePipe(&hRead, &hWrite, &sa, 0)) {
		return;
	}

	if (NULL == hRead || NULL == hWrite) {
		return;
	}
	char *buf = Get_Char(command,count);
	DWORD dwWrite;
	WriteFile(hWrite, buf, Get_Actuall(buf), &dwWrite, NULL); //将数据写入管道的输入端
	CloseHandle(hWrite);
	//创建进程,从管道输出端读取数据

	//以下是为了验证读取的正确性
	char *p = "temp.txt";
	wchar_t *path1 = char2LPCTSTR(p);
	LPCTSTR  outputFile = path1;
	HANDLE hOutput = CreateFile(
		outputFile,
		GENERIC_WRITE,
		0,
		&sa,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if (hOutput == INVALID_HANDLE_VALUE) {
		return;
	}
	//以下是为了验证读取的正确性

	STARTUPINFO si = { sizeof(si) };
	PROCESS_INFORMATION pi = { 0 };
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;;
	si.wShowWindow = SW_HIDE; //不显示创建的进程的窗口
	si.hStdInput = hRead;//重定向输入句柄为之前创建的管道读出句柄
	si.hStdOutput = hOutput; //重定向输出句柄为之前创建的文件句柄
	TCHAR *cmdline = char2TCHAR(command, 1);
	if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) {
		//等待打开的进程结束并关闭相关句柄
		WaitForSingleObject(pi.hProcess, INFINITE);
		::CloseHandle(pi.hThread);
		::CloseHandle(pi.hProcess);
	}
	else {
		int err = GetLastError();
	}
	
	//关闭管道读写句柄
	CloseHandle(hRead);
	CloseHandle(hOutput);

}

// |命令
void Redirection_5(char **&command, int count) {  //这里利用文件读写
	//const char *path1 = Get_Char(command, count);
	//const char *path2 = Get_Char(command, 1);

	HANDLE hRead = NULL;
	HANDLE hWrite = NULL;

	SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE }; 
	// 新创建的进程继承管道读写句柄
	if (FALSE == CreatePipe(&hRead, &hWrite, &sa, 0)) {
		return;
	}

	if (NULL == hRead || NULL == hWrite) {
		return;
	}
	
	//创建进程,从管道输出端读取数据

	//以下是为了验证读取的正确性
	char *p = "temp.txt";
	wchar_t *path1 = char2LPCTSTR(p);
	LPCTSTR  outputFile = path1;
	HANDLE hOutput = CreateFile(
		outputFile,
		GENERIC_WRITE,
		0,
		&sa,
		CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if (hOutput == INVALID_HANDLE_VALUE) {
		return;
	}
	//以上是为了验证读取的正确性

	//输出进程,输出定位到管道的输入端
	STARTUPINFO si = { sizeof(si) };
	PROCESS_INFORMATION pi = { 0 };
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si.wShowWindow = SW_HIDE; //不显示创建的进程的窗口
	//si.hStdInput = hRead;//重定向输入句柄为之前创建的管道读出句柄
	si.hStdOutput = hWrite; //重定向输出句柄为之前创建的管道输入句柄
	TCHAR *cmdline = char2TCHAR(command, 1);
	if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) {
		//等待打开的进程结束并关闭相关句柄
		WaitForSingleObject(pi.hProcess, INFINITE);
		::CloseHandle(pi.hThread);
		::CloseHandle(pi.hProcess);
	}
	else {
		int err = GetLastError();
	}
	CloseHandle(hWrite); //关闭管道输入句柄

	//输入进程,输入定位到管道的输出端
	STARTUPINFO si1 = { sizeof(si1) };
	PROCESS_INFORMATION pi1 = { 0 };
	si1.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si1.wShowWindow = SW_HIDE; //不显示创建的进程的窗口
	si1.hStdInput = hRead;//重定向输入句柄为之前创建的管道读出句柄
	si1.hStdOutput = hOutput; //重定向输出句柄为之前创建的管道输入句柄
	TCHAR *cmdline1 = char2TCHAR(command, count);
	if (CreateProcess(NULL, cmdline1, NULL, NULL, TRUE, NULL, NULL, NULL, &si1, &pi1)) {
		//等待打开的进程结束并关闭相关句柄
		WaitForSingleObject(pi1.hProcess, INFINITE);
		::CloseHandle(pi1.hThread);
		::CloseHandle(pi1.hProcess);
	}
	else {
		int err = GetLastError();
	}

	//关闭管道读句柄
	CloseHandle(hRead);
	CloseHandle(hOutput); //关闭文件句柄
}

 

你可能感兴趣的:(C++)