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