use qmake to build console pauser
This commit is contained in:
parent
cdb4cc215f
commit
729938f941
|
@ -2,5 +2,6 @@ TEMPLATE = subdirs
|
|||
|
||||
SUBDIRS += \
|
||||
# ../QScintilla/src/qscintilla.pro \
|
||||
RedPandaIDE
|
||||
RedPandaIDE \
|
||||
consolepauser
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
QT -= gui
|
||||
|
||||
CONFIG += c++11 console
|
||||
CONFIG -= app_bundle
|
||||
|
||||
# You can make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
win32: {
|
||||
SOURCES += \
|
||||
main.windows.cpp
|
||||
}
|
||||
|
||||
unix: {
|
||||
SOURCES += \
|
||||
main.unix.cpp
|
||||
}
|
||||
|
||||
CONFIG += lrelease
|
||||
CONFIG += embed_translations
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* This file is part of Red Panda Dev-C++ 7
|
||||
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
* This file is part of Red Panda Dev-C++ 7
|
||||
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
using std::string;
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <conio.h>
|
||||
|
||||
#define MAX_COMMAND_LENGTH 32768
|
||||
#define MAX_ERROR_LENGTH 2048
|
||||
|
||||
enum RunProgramFlag {
|
||||
RPF_PAUSE_CONSOLE = 0x0001,
|
||||
RPF_REDIRECT_INPUT = 0x0002
|
||||
};
|
||||
|
||||
HANDLE hJob;
|
||||
|
||||
LONGLONG GetClockTick() {
|
||||
LARGE_INTEGER dummy;
|
||||
QueryPerformanceCounter(&dummy);
|
||||
return dummy.QuadPart;
|
||||
}
|
||||
|
||||
LONGLONG GetClockFrequency() {
|
||||
LARGE_INTEGER dummy;
|
||||
QueryPerformanceFrequency(&dummy);
|
||||
return dummy.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
string GetErrorMessage() {
|
||||
string result(MAX_ERROR_LENGTH,0);
|
||||
FormatMessageA(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),&result[0],result.size(),NULL);
|
||||
|
||||
// Clear newlines at end of string
|
||||
for(int i = result.length()-1;i >= 0;i--) {
|
||||
if(isspace(result[i])) {
|
||||
result[i] = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void PauseExit(int exitcode, bool reInp) {
|
||||
HANDLE hInp=NULL;
|
||||
if (reInp) {
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = TRUE;
|
||||
|
||||
HANDLE hInp = CreateFileA("CONIN$", GENERIC_WRITE | GENERIC_READ,
|
||||
FILE_SHARE_READ , &sa, OPEN_EXISTING, /*FILE_ATTRIBUTE_NORMAL*/0, NULL);
|
||||
//si.hStdInput = hInp;
|
||||
SetStdHandle(STD_INPUT_HANDLE,hInp);
|
||||
freopen("CONIN$","r",stdin);
|
||||
}
|
||||
FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
|
||||
fflush(stdin);
|
||||
printf("\n");
|
||||
printf("Press ANY key to exit...");
|
||||
getch();
|
||||
if (reInp) {
|
||||
CloseHandle(hInp);
|
||||
}
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
string GetCommand(int argc,char** argv,bool &reInp,bool &pauseAfterExit) {
|
||||
string result;
|
||||
int flags = atoi(argv[1]);
|
||||
reInp = flags & RPF_REDIRECT_INPUT;
|
||||
pauseAfterExit = flags & RPF_PAUSE_CONSOLE;
|
||||
for(int i = 2;i < argc;i++) {
|
||||
// Quote the argument in case the path name contains spaces
|
||||
result += string("\"") + string(argv[i]) + string("\"");
|
||||
|
||||
// Add a space except for the last argument
|
||||
if(i != (argc-1)) {
|
||||
result += string(" ");
|
||||
}
|
||||
}
|
||||
|
||||
if(result.length() > MAX_COMMAND_LENGTH) {
|
||||
printf("\n--------------------------------");
|
||||
printf("\nError: Length of command line string is over %d characters\n",MAX_COMMAND_LENGTH);
|
||||
PauseExit(EXIT_FAILURE,reInp);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DWORD ExecuteCommand(string& command,bool reInp) {
|
||||
STARTUPINFOA si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
memset(&si,0,sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
memset(&pi,0,sizeof(pi));
|
||||
|
||||
DWORD dwCreationFlags = CREATE_BREAKAWAY_FROM_JOB;
|
||||
|
||||
|
||||
if(!CreateProcessA(NULL, (LPSTR)command.c_str(), NULL, NULL, true, dwCreationFlags, NULL, NULL, &si, &pi)) {
|
||||
printf("\n--------------------------------");
|
||||
printf("\nFailed to execute \"%s\":",command.c_str());
|
||||
printf("\nError %lu: %s\n",GetLastError(),GetErrorMessage().c_str());
|
||||
PauseExit(EXIT_FAILURE,reInp);
|
||||
}
|
||||
WINBOOL bSuccess = AssignProcessToJobObject( hJob, pi.hProcess );
|
||||
if ( bSuccess == FALSE ) {
|
||||
printf( "AssignProcessToJobObject failed: error %d\n", GetLastError() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
WaitForSingleObject(pi.hProcess, INFINITE); // Wait for it to finish
|
||||
|
||||
|
||||
DWORD result = 0;
|
||||
GetExitCodeProcess(pi.hProcess, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
// First make sure we aren't going to read nonexistent arrays
|
||||
if(argc < 3) {
|
||||
printf("\n--------------------------------");
|
||||
printf("\nUsage: ConsolePauser.exe <0|1> <filename> <parameters>\n");
|
||||
printf("\n 1 means the STDIN is redirected by Dev-CPP;0 means not\n");
|
||||
PauseExit(EXIT_SUCCESS,false);
|
||||
}
|
||||
|
||||
// Make us look like the paused program
|
||||
SetConsoleTitleA(argv[2]);
|
||||
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = FALSE;
|
||||
|
||||
hJob= CreateJobObject( &sa, NULL );
|
||||
|
||||
if ( hJob == NULL ) {
|
||||
printf( "CreateJobObject failed: error %d\n", GetLastError() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION info = { 0 };
|
||||
info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||
WINBOOL bSuccess = SetInformationJobObject( hJob, JobObjectExtendedLimitInformation, &info, sizeof( info ) );
|
||||
if ( bSuccess == FALSE ) {
|
||||
printf( "SetInformationJobObject failed: error %d\n", GetLastError() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool reInp;
|
||||
bool pauseAfterExit;
|
||||
// Then build the to-run application command
|
||||
string command = GetCommand(argc,argv,reInp, pauseAfterExit);
|
||||
HANDLE hOutput = NULL;
|
||||
if (reInp) {
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = TRUE;
|
||||
|
||||
hOutput = CreateFileA("CONOUT$", GENERIC_WRITE | GENERIC_READ,
|
||||
FILE_SHARE_WRITE , &sa, OPEN_EXISTING, /*FILE_ATTRIBUTE_NORMAL*/0, NULL);
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, hOutput);
|
||||
SetStdHandle(STD_ERROR_HANDLE, hOutput);
|
||||
freopen("CONOUT$","w+",stdout);
|
||||
freopen("CONOUT$","w+",stderr);
|
||||
} else {
|
||||
FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
|
||||
}
|
||||
|
||||
HANDLE hSharedMemory=INVALID_HANDLE_VALUE;
|
||||
int BUF_SIZE=1024;
|
||||
char* pBuf=nullptr;
|
||||
hSharedMemory = OpenFileMappingA(
|
||||
FILE_MAP_ALL_ACCESS,
|
||||
FALSE,
|
||||
"RED_PANDA_IDE_CONSOLE_PAUSER20211223"
|
||||
);
|
||||
if (hSharedMemory != NULL)
|
||||
{
|
||||
pBuf = (char*) MapViewOfFile(hSharedMemory, // handle to map object
|
||||
FILE_MAP_ALL_ACCESS, // read/write permission
|
||||
0,
|
||||
0,
|
||||
BUF_SIZE);
|
||||
} else {
|
||||
printf("can't open shared memory!");
|
||||
}
|
||||
|
||||
// Save starting timestamp
|
||||
LONGLONG starttime = GetClockTick();
|
||||
|
||||
// Then execute said command
|
||||
DWORD returnvalue = ExecuteCommand(command,reInp);
|
||||
|
||||
// Get ending timestamp
|
||||
LONGLONG endtime = GetClockTick();
|
||||
double seconds = (endtime - starttime) / (double)GetClockFrequency();
|
||||
|
||||
if (pBuf) {
|
||||
strcpy(pBuf,"FINISHED");
|
||||
}
|
||||
|
||||
// Done? Print return value of executed program
|
||||
printf("\n--------------------------------");
|
||||
printf("\nProcess exited after %.4g seconds with return value %lu\n",seconds,returnvalue);
|
||||
if (pauseAfterExit)
|
||||
PauseExit(returnvalue,reInp);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
/ConsolePauser.layout
|
||||
/Makefile.win
|
||||
/ConsolePauser.exe
|
||||
/main.o
|
|
@ -1,74 +0,0 @@
|
|||
[Project]
|
||||
FileName = ConsolePauser.dev
|
||||
Name = ConsolePauser
|
||||
Type = 1
|
||||
Ver = 3
|
||||
ObjFiles =
|
||||
Includes =
|
||||
Libs =
|
||||
PrivateResource =
|
||||
ResourceIncludes =
|
||||
MakeIncludes =
|
||||
Compiler =
|
||||
CppCompiler =
|
||||
Linker =
|
||||
IsCpp = 1
|
||||
Icon =
|
||||
ExeOutput =
|
||||
ObjectOutput =
|
||||
LogOutput =
|
||||
LogOutputEnabled = 0
|
||||
OverrideOutput = 0
|
||||
OverrideOutputName = ConsolePauser.exe
|
||||
HostApplication =
|
||||
Folders =
|
||||
CommandLine =
|
||||
UseCustomMakefile = 0
|
||||
CustomMakefile =
|
||||
IncludeVersionInfo = 0
|
||||
SupportXPThemes = 0
|
||||
CompilerSet = 0
|
||||
CompilerSettings = 000000a000000000000010001
|
||||
UnitCount = 1
|
||||
UsePrecompiledHeader = 0
|
||||
PrecompiledHeader =
|
||||
UseUTF8 = 0
|
||||
StaticLink = 1
|
||||
AddCharset = 1
|
||||
Encoding = AUTO
|
||||
CompilerSetType = 0
|
||||
|
||||
|
||||
[VersionInfo]
|
||||
Major = 1
|
||||
Minor = 0
|
||||
Release = 0
|
||||
Build = 0
|
||||
LanguageID = 1033
|
||||
CharsetID = 1252
|
||||
CompanyName =
|
||||
FileVersion = 1.0.0.0
|
||||
FileDescription = Developed using the Dev-C++ IDE
|
||||
InternalName =
|
||||
LegalCopyright =
|
||||
LegalTrademarks =
|
||||
OriginalFilename =
|
||||
ProductName =
|
||||
ProductVersion = 1.0.0.0
|
||||
AutoIncBuildNr = 0
|
||||
SyncProduct = 1
|
||||
|
||||
|
||||
[Unit1]
|
||||
FileName = main.cpp
|
||||
CompileCpp = 1
|
||||
Folder =
|
||||
Compile = 1
|
||||
Link = 1
|
||||
Priority = 1000
|
||||
OverrideBuildCmd = 0
|
||||
BuildCmd =
|
||||
UseUTF8 = 1
|
||||
DetectEncoding = 1
|
||||
Encoding = 0
|
||||
FileEncoding = AUTO
|
|
@ -1,238 +0,0 @@
|
|||
/*
|
||||
* This file is part of Red Panda Dev-C++ 7
|
||||
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
using std::string;
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <conio.h>
|
||||
|
||||
#define MAX_COMMAND_LENGTH 32768
|
||||
#define MAX_ERROR_LENGTH 2048
|
||||
|
||||
enum RunProgramFlag {
|
||||
RPF_PAUSE_CONSOLE = 0x0001,
|
||||
RPF_REDIRECT_INPUT = 0x0002
|
||||
};
|
||||
|
||||
HANDLE hJob;
|
||||
|
||||
LONGLONG GetClockTick() {
|
||||
LARGE_INTEGER dummy;
|
||||
QueryPerformanceCounter(&dummy);
|
||||
return dummy.QuadPart;
|
||||
}
|
||||
|
||||
LONGLONG GetClockFrequency() {
|
||||
LARGE_INTEGER dummy;
|
||||
QueryPerformanceFrequency(&dummy);
|
||||
return dummy.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
string GetErrorMessage() {
|
||||
string result(MAX_ERROR_LENGTH,0);
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),&result[0],result.size(),NULL);
|
||||
|
||||
// Clear newlines at end of string
|
||||
for(int i = result.length()-1;i >= 0;i--) {
|
||||
if(isspace(result[i])) {
|
||||
result[i] = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void PauseExit(int exitcode, bool reInp) {
|
||||
HANDLE hInp=NULL;
|
||||
if (reInp) {
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = TRUE;
|
||||
|
||||
HANDLE hInp = CreateFile("CONIN$", GENERIC_WRITE | GENERIC_READ,
|
||||
FILE_SHARE_READ , &sa, OPEN_EXISTING, /*FILE_ATTRIBUTE_NORMAL*/0, NULL);
|
||||
//si.hStdInput = hInp;
|
||||
SetStdHandle(STD_INPUT_HANDLE,hInp);
|
||||
freopen("CONIN$","r",stdin);
|
||||
}
|
||||
FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
|
||||
fflush(stdin);
|
||||
printf("\n");
|
||||
printf("Press ANY key to exit...");
|
||||
getch();
|
||||
if (reInp) {
|
||||
CloseHandle(hInp);
|
||||
}
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
string GetCommand(int argc,char** argv,bool &reInp,bool &pauseAfterExit) {
|
||||
string result;
|
||||
int flags = atoi(argv[1]);
|
||||
reInp = flags & RPF_REDIRECT_INPUT;
|
||||
pauseAfterExit = flags & RPF_PAUSE_CONSOLE;
|
||||
for(int i = 2;i < argc;i++) {
|
||||
// Quote the argument in case the path name contains spaces
|
||||
result += string("\"") + string(argv[i]) + string("\"");
|
||||
|
||||
// Add a space except for the last argument
|
||||
if(i != (argc-1)) {
|
||||
result += string(" ");
|
||||
}
|
||||
}
|
||||
|
||||
if(result.length() > MAX_COMMAND_LENGTH) {
|
||||
printf("\n--------------------------------");
|
||||
printf("\nError: Length of command line string is over %d characters\n",MAX_COMMAND_LENGTH);
|
||||
PauseExit(EXIT_FAILURE,reInp);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DWORD ExecuteCommand(string& command,bool reInp) {
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
memset(&si,0,sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
memset(&pi,0,sizeof(pi));
|
||||
|
||||
DWORD dwCreationFlags = CREATE_BREAKAWAY_FROM_JOB;
|
||||
|
||||
|
||||
if(!CreateProcess(NULL, (LPSTR)command.c_str(), NULL, NULL, true, dwCreationFlags, NULL, NULL, &si, &pi)) {
|
||||
printf("\n--------------------------------");
|
||||
printf("\nFailed to execute \"%s\":",command.c_str());
|
||||
printf("\nError %lu: %s\n",GetLastError(),GetErrorMessage().c_str());
|
||||
PauseExit(EXIT_FAILURE,reInp);
|
||||
}
|
||||
WINBOOL bSuccess = AssignProcessToJobObject( hJob, pi.hProcess );
|
||||
if ( bSuccess == FALSE ) {
|
||||
printf( "AssignProcessToJobObject failed: error %d\n", GetLastError() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
WaitForSingleObject(pi.hProcess, INFINITE); // Wait for it to finish
|
||||
|
||||
|
||||
DWORD result = 0;
|
||||
GetExitCodeProcess(pi.hProcess, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
// First make sure we aren't going to read nonexistent arrays
|
||||
if(argc < 3) {
|
||||
printf("\n--------------------------------");
|
||||
printf("\nUsage: ConsolePauser.exe <0|1> <filename> <parameters>\n");
|
||||
printf("\n 1 means the STDIN is redirected by Dev-CPP;0 means not\n");
|
||||
PauseExit(EXIT_SUCCESS,false);
|
||||
}
|
||||
|
||||
// Make us look like the paused program
|
||||
SetConsoleTitle(argv[2]);
|
||||
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = FALSE;
|
||||
|
||||
hJob= CreateJobObject( &sa, NULL );
|
||||
|
||||
if ( hJob == NULL ) {
|
||||
printf( "CreateJobObject failed: error %d\n", GetLastError() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION info = { 0 };
|
||||
info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||
WINBOOL bSuccess = SetInformationJobObject( hJob, JobObjectExtendedLimitInformation, &info, sizeof( info ) );
|
||||
if ( bSuccess == FALSE ) {
|
||||
printf( "SetInformationJobObject failed: error %d\n", GetLastError() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool reInp;
|
||||
bool pauseAfterExit;
|
||||
// Then build the to-run application command
|
||||
string command = GetCommand(argc,argv,reInp, pauseAfterExit);
|
||||
HANDLE hOutput = NULL;
|
||||
if (reInp) {
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = TRUE;
|
||||
|
||||
hOutput = CreateFile("CONOUT$", GENERIC_WRITE | GENERIC_READ,
|
||||
FILE_SHARE_WRITE , &sa, OPEN_EXISTING, /*FILE_ATTRIBUTE_NORMAL*/0, NULL);
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, hOutput);
|
||||
SetStdHandle(STD_ERROR_HANDLE, hOutput);
|
||||
freopen("CONOUT$","w+",stdout);
|
||||
freopen("CONOUT$","w+",stderr);
|
||||
} else {
|
||||
FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
|
||||
}
|
||||
|
||||
HANDLE hSharedMemory=INVALID_HANDLE_VALUE;
|
||||
int BUF_SIZE=1024;
|
||||
char* pBuf=nullptr;
|
||||
hSharedMemory = OpenFileMappingA(
|
||||
FILE_MAP_ALL_ACCESS,
|
||||
FALSE,
|
||||
"RED_PANDA_IDE_CONSOLE_PAUSER20211223"
|
||||
);
|
||||
if (hSharedMemory != NULL)
|
||||
{
|
||||
pBuf = (char*) MapViewOfFile(hSharedMemory, // handle to map object
|
||||
FILE_MAP_ALL_ACCESS, // read/write permission
|
||||
0,
|
||||
0,
|
||||
BUF_SIZE);
|
||||
} else {
|
||||
printf("can't open shared memory!");
|
||||
}
|
||||
|
||||
// Save starting timestamp
|
||||
LONGLONG starttime = GetClockTick();
|
||||
|
||||
// Then execute said command
|
||||
DWORD returnvalue = ExecuteCommand(command,reInp);
|
||||
|
||||
// Get ending timestamp
|
||||
LONGLONG endtime = GetClockTick();
|
||||
double seconds = (endtime - starttime) / (double)GetClockFrequency();
|
||||
|
||||
if (pBuf) {
|
||||
strcpy(pBuf,"FINISHED");
|
||||
}
|
||||
|
||||
// Done? Print return value of executed program
|
||||
printf("\n--------------------------------");
|
||||
printf("\nProcess exited after %.4g seconds with return value %lu\n",seconds,returnvalue);
|
||||
if (pauseAfterExit)
|
||||
PauseExit(returnvalue,reInp);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue