⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 executor.cpp

📁 一个完全使用MFC框架开发的C++编译器的代码。功能十分强大可以编译大型程序。
💻 CPP
字号:
// ---- executor.cpp

#include "stdafx.h"
#include "executor.h"

Executor* Executor::executor;

Executor::Executor(const char* exename)
{
	running = false;
	successfulrun = false;
	Exename = exename;
	pinfo.dwProcessId = 0;
	pinfo.dwThreadId = 0;
	pinfo.hProcess = 0;
	pinfo.hThread = 0;
	m_hStdin = INVALID_HANDLE_VALUE;
	m_hStderr = INVALID_HANDLE_VALUE;
	m_hStdout = INVALID_HANDLE_VALUE;
	executor = this;
}

Executor::~Executor()
{
	shutdown();
	executor = 0;
}

void Executor::Run(const char* params)
{
	if (!running)	{
		successfulrun = true;
		Args = params;
		SECURITY_ATTRIBUTES sa = {
			sizeof(SECURITY_ATTRIBUTES), 
				0, true
		};
		AfxBeginThread(&Executor::DoRun, 0);
	}
}

UINT Executor::DoRun(void* params)
{
	ASSERT(executor != 0);
	executor->runapplication();
	return 0;
}

void Executor::runapplication()
{
	bool bIsConsole = theApp.IsConsoleApplication();

	SECURITY_ATTRIBUTES sa = {
		sizeof(SECURITY_ATTRIBUTES), 
			0, true
	};

	CString strCmdLine(Args.c_str());

	if (bIsConsole)	{
		AllocConsole();
		// ---- parse stdin redirection from the command line
		CString strRedirectedStdin;
		int index = strCmdLine.Find('<');
		if (index != -1)
			theApp.ParseFileSpec(strRedirectedStdin, strCmdLine, index);
		if (BuildStdin(strRedirectedStdin) == INVALID_HANDLE_VALUE)	{
			CString strErr("Cannot open redirected stdin ");
			strErr += strRedirectedStdin;
			AfxMessageBox(strErr, MB_ICONSTOP);
			FreeConsole();
			return;
		}

		// ---- parse stdout redirection from the command line
		CString strRedirectedStdout;
		index = strCmdLine.Find('>');
		bool append = false;
		if (index != -1 && index < strCmdLine.GetLength()-1)	{
			if (strCmdLine[index+1] == '>')	{
				index++;
				append = true;
			}
			theApp.ParseFileSpec(strRedirectedStdout, strCmdLine, index);
		}
		if (BuildStdout(strRedirectedStdout, append) == INVALID_HANDLE_VALUE)	{
			CString strErr("Cannot create redirected stdout ");
			strErr += strRedirectedStdout;
			AfxMessageBox(strErr, MB_ICONSTOP);
			FreeConsole();
			return;
		}
		BuildStderr();
	}

	DWORD dwflags = bIsConsole ? STARTF_USESTDHANDLES : 0;
	STARTUPINFO suinfo = {
		sizeof(STARTUPINFO),				// cb
		0, 0,								// reserved
		0,									// lpTitle
		0, 0,								// dwX, dwY
		0, 0,								// dwXSize, dwYSize
		0, 0,								// dwXCountChars, dwYCountChars
		0,									// dwFillAttribute
		dwflags,							// dwFlags
		0,									// wShowWindow
		0, 0,								// reserved
		m_hStdin,							// hStdInput;
		m_hStdout,							// hStdOutput;
		m_hStderr,							// hStdError;
	};
	const char* exe    = Exename.c_str();
	std::string s(Exename+' '+strCmdLine.GetBuffer(0));
	const char* params = s.c_str();

	exitcode = 0;

	successfulrun = CreateProcess(
								0,
								const_cast<char*>(params),
								&sa,&sa,
								true,
								0,
								0,
								0,
								&suinfo,
								&pinfo) != false;
	if (successfulrun)	{
		running = true;
		do	{
			Sleep(100L);
			GetExitCodeProcess(pinfo.hProcess, &exitcode);
		} while (exitcode == STILL_ACTIVE);
		running = false;

		if (bIsConsole)	{
			char msg[] = "\nPress Enter to return to Quincy...";
			DWORD ct;
			TCHAR bf;
			WriteConsole(GetStdHandle(STD_ERROR_HANDLE), msg, sizeof msg - 1, &ct, 0);
			SetConsoleMode(m_hStdin, ENABLE_LINE_INPUT);
			ReadConsole(m_hStdin, &bf, 1, &ct, 0);
		}
	}
	else	{
		AfxMessageBox(CString(exe) + "\nCannot execute program", MB_ICONSTOP);
		exitcode = -1;
	}
	shutdown();
}

HANDLE Executor::BuildStdin(const CString& rstrPath)
{
	CloseConsoleHandle(m_hStdin, STD_INPUT_HANDLE);
	if (rstrPath.IsEmpty())
		m_hStdin = GetStdHandle(STD_INPUT_HANDLE);
	else	{
		SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), 0, true };
		m_hStdin = CreateFile(rstrPath, GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
	}
	return m_hStdin;
}
HANDLE Executor::BuildStdout(const CString& rstrPath, bool append)
{
	CloseConsoleHandle(m_hStdout,STD_OUTPUT_HANDLE);
	if (rstrPath.IsEmpty())
		m_hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
	else	{
		SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), 0, true };
		m_hStdout = CreateFile(rstrPath, 
			GENERIC_WRITE, 
			FILE_SHARE_READ | FILE_SHARE_WRITE, 
			&sa, 
			(append ? OPEN_ALWAYS : CREATE_ALWAYS), 
			FILE_ATTRIBUTE_NORMAL, 0);
		if (append)
			SetFilePointer(m_hStdout, 0, 0, FILE_END);
	}
	return m_hStdout;
}

HANDLE Executor::BuildStderr(const CString& rstrPath)
{
	CloseConsoleHandle(m_hStderr,STD_ERROR_HANDLE);
	if (rstrPath.IsEmpty())
		m_hStderr = GetStdHandle(STD_ERROR_HANDLE);
	else	{
		SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), 0, true };
		m_hStderr = CreateFile(rstrPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
	}
	return m_hStderr;
}

HANDLE Executor::BuildStderr()
{
	m_hStderr = GetStdHandle(STD_ERROR_HANDLE);
	return m_hStderr;
}

void Executor::CloseConsoleHandle(HANDLE& hStd, DWORD stdhandle)
{
	if (hStd != INVALID_HANDLE_VALUE)	{
		if (hStd != GetStdHandle(stdhandle))
			CloseHandle(hStd);
		hStd = INVALID_HANDLE_VALUE;
	}
}

void Executor::CloseConsoleHandles()
{
	CloseConsoleHandle(m_hStdin, STD_INPUT_HANDLE);
	CloseConsoleHandle(m_hStdout,STD_OUTPUT_HANDLE);
	CloseConsoleHandle(m_hStderr,STD_ERROR_HANDLE);
}

void Executor::closehandle(HANDLE& handle)
{
	if (handle)	{
		CloseHandle(handle);
		handle = 0;
	}
}

void Executor::shutdown()
{
	closehandle(pinfo.hThread);
	closehandle(pinfo.hProcess);
	pinfo.dwProcessId = 0;
	pinfo.dwThreadId = 0;
	CloseConsoleHandles();
	FreeConsole();
	running = false;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -