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

📄 consoleapp.cpp

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

#include "stdafx.h"
#include "consoleapp.h"

ConsoleApp* ConsoleApp::consoleapp;

ConsoleApp::ConsoleApp(const char* exename, void (*termfunc)(), void (*cbfunc)(DWORD))
{
	hOutputReadTmp = 0;
	hInputWriteTmp = 0;
	hOutputRead = 0;
	hOutputWrite = 0;
	hInputRead = 0;
	hInputWrite = 0;
	hErrorWrite = 0;
	running = false;
	successfulrun = false;
	Exename = exename;
	InputReady = cbfunc;
	Termfunc = termfunc;
	consoleapp = 0;
	exitcode = 0;
	pinfo.dwProcessId = 0;
	pinfo.dwThreadId = 0;
	pinfo.hProcess = 0;
	pinfo.hThread = 0;
}

ConsoleApp::~ConsoleApp()
{
	Stop();
	shutdown();
}

void ConsoleApp::Run(const char* params)
{
	if (!running)	{
		shutdown();			// in case an earlier instance was running
		successfulrun = true;
		consoleapp = this;
		bufferct = 0;
		Args = params;

		SECURITY_ATTRIBUTES sa = {
			sizeof(SECURITY_ATTRIBUTES), 
				0, true
		};
		HANDLE hProc = GetCurrentProcess();
		CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0);
		DuplicateHandle(hProc, hOutputWrite, hProc, 
				&hErrorWrite, 0, true, DUPLICATE_SAME_ACCESS);
		CreatePipe(&hInputRead, &hInputWriteTmp, &sa, 0);
		DuplicateHandle(hProc, hOutputReadTmp, hProc, 
				&hOutputRead, 0, false, DUPLICATE_SAME_ACCESS);
		DuplicateHandle(hProc, hInputWriteTmp, hProc, 
			&hInputWrite, 0, false, DUPLICATE_SAME_ACCESS);
		AfxBeginThread(&ConsoleApp::DoRun, 0);
		closehandle(hOutputReadTmp);
		closehandle(hInputWriteTmp);
	}
}

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

UINT ConsoleApp::DoRun(void*)
{
	ASSERT(consoleapp != 0);
	consoleapp->runapplication();
	return 0;
}

void ConsoleApp::runapplication()
{
	SECURITY_ATTRIBUTES sa = {
		sizeof(SECURITY_ATTRIBUTES), 
			0, false
	};
	STARTUPINFO suinfo = {
		sizeof(STARTUPINFO),	// cb
		0, 0,					// reserved
		0,						// lpTitle
		0, 0,					// dwX, dwY
		0, 0,					// dwXSize, dwYSize
		0, 0,					// dwXCountChars, dwYCountChars
		0,						// dwFillAttribute
		STARTF_USESTDHANDLES |
		STARTF_USESHOWWINDOW,	// dwFlags
		SW_HIDE,				// wShowWindow
		0, 0,					// reserved
		hInputRead,				// hStdInput;
		hOutputWrite,			// hStdOutput;
		hErrorWrite,			// hStdError;
	};


	std::string s(Exename+Args);
	const char* params = s.c_str();

	exitcode = 0;

	successfulrun = CreateProcess(
								0,
								const_cast<char*>(params),
								&sa,0,
								true, 
								0,
								0,
								0,
								&suinfo,
								&pinfo) != false;
	closehandle(hOutputWrite);
	closehandle(hInputRead );
	closehandle(hErrorWrite);
	if (successfulrun)	{
		running = true;
		do	{
			Sleep(100L);
			flushbuffer();
			GetExitCodeProcess(pinfo.hProcess, &exitcode);
		} while (running && exitcode == STILL_ACTIVE);
		running = false;
	}
	else	{
		AfxMessageBox(CString(Exename.c_str()) + "\nCannot execute console program", MB_ICONSTOP);
		exitcode = -1;
	}
	if (Termfunc != 0)
		Termfunc();
}

void ConsoleApp::WriteConsole(const char* cmd)
{
	DWORD ct;
	WriteFile(hInputWrite, cmd, strlen(cmd), &ct, 0);
	WriteFile(hInputWrite, "\n", 1, &ct, 0);
}


void ConsoleApp::flushbuffer()
{
	DWORD ct = 0;
	do {
		fillbuffer();
		if (InputReady == 0 || !PeekNamedPipe(hOutputRead, 0, 0, 0, &ct, 0))
			break;
	} while (ct > 0);
}


void ConsoleApp::fillbuffer()
{
	if (hOutputRead != 0 && InputReady != 0)	{
		DWORD ct = 0;
		PeekNamedPipe(hOutputRead, 0, 0, 0, &ct, 0);
		if (ct != 0)	{
			DWORD ict;
			char c;
			while (ct-- > 0 && ReadFile(hOutputRead, &c, 1, &ict, 0) && ict != 0)	{
				if (c != '\r')	{
					if (c != '\n')
						buffer.push(c);
					int size = buffer.size();
					if ((c == '\n' || ct == 0) && size != 0)	{
						InputReady(size);
					}
				}
			}
		}
	}
}

int ConsoleApp::ReadConsole(char* line, unsigned int nchars)
{
	int n = 0;
	while (buffer.size() > 0 && nchars > 0)	{
		*(line + n++) = buffer.front();
		buffer.pop();
		--nchars;
	}
	*(line+n) = '\0';
	return n;
}

void ConsoleApp::Stop()
{
	shutdown();
}

void ConsoleApp::shutdown()
{
	TerminateProcess(pinfo.hProcess, exitcode);
	closehandle(pinfo.hThread);
	closehandle(pinfo.hProcess);
	closehandle(hInputWrite);
	closehandle(hOutputRead);
	pinfo.dwProcessId = 0;
	pinfo.dwThreadId = 0;
	running = false;
}

⌨️ 快捷键说明

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