📄 consoleapp.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 + -