从控制台应用创建新控制台?C++
Create new console from console app? C++
我被困在为我的控制台应用程序创建新的控制台窗口,用于记录器。该代码适用于 GUI 应用程序,但不适用于控制台,并且它们需要: 带有DETACHED_PROCESS标志的创建进程函数。
Logger Log;
DWORD PiD;
void __stdcall LoggerCore(PVOID pVoid)
{
AllocConsole();
while(true)
{
SetConsoleTitleA(Log.LoggerTittle());
Sleep(5000);
}
_endthread();
}
char* Logger::LoggerTittle()
{
static char Tittle[55];
sprintf(Tittle, "Debug Logger");
return Tittle;
}
void Logger::LoggerInit()
{
CreateThread( 0 , 0 , (LPTHREAD_START_ROUTINE) LoggerCore , 0 , 0 , &PiD );
}
该代码,当应用程序为 GUI 时创建一个新的控制台,并在新的控制台窗口中显示"Log.ConsoleOutPut(1, c_Green,t_Default,"调试记录器:SomeInfo");"。但所有这些都不适用于控制台应用程序。那么,如何使用CreateProcess在控制台应用程序中制作第二个控制台窗口?感谢您的建议!
所以,我试图重写它,但什么都没有...那对我不起作用。
#include logger.h
char Message[1024];
Logger Log;
DWORD PiD;
/*
void __stdcall LoggerCore(PVOID pVoid)
{
AllocConsole();
while(true)
{
SetConsoleTitleA(Log.LoggerTittle());
Sleep(5000);
}
_endthread();
}
char* Logger::LoggerTittle()
{
static char Tittle[55];
sprintf(Tittle, "Debug Logger");
return Tittle;
}
*/
void Logger::LoggerInit()
{
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle=1;
sa.lpSecurityDescriptor=0;
SetHandleInformation(this->near_end,HANDLE_FLAG_INHERIT,0);
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&pi,sizeof(pi));
ZeroMemory(&si,sizeof(si));
si.cb=sizeof(STARTUPINFO);
si.dwFlags|=STARTF_USESTDHANDLES;
TCHAR program[]=TEXT("???");//need type something here.
TCHAR arguments[100];
if (!CreateProcess(program,arguments,0,0,1,CREATE_NEW_CONSOLE,0,0,&si,&pi))
printf( "CreateProcess failed (%d).n", GetLastError() );
return;
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
this->process=pi.hProcess;
CloseHandle(pi.hThread);
// CreateThread( 0 , 0 , (LPTHREAD_START_ROUTINE) LoggerCore , 0 , 0 , &PiD );
}
void Logger::CheckProcent(char* message)
{
for (UINT i = 0; i <= strlen(message); i++)
{
if(message[i] == '%')
{
for(UINT j = strlen(message); j >= i; j--)
message[j+1] = message[j];
i++;
}
}
}
void Logger::ConsoleOutPut(int WOL, sColor Color, sLogType Type, const char* Format, ...)
{
SYSTEMTIME t;
GetLocalTime(&t);
DWORD dwBytesWritten;
HANDLE Handle = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hStdin;
hStdin = GetStdHandle(STD_INPUT_HANDLE);
if (hStdin == INVALID_HANDLE_VALUE)
ExitProcess(1);
va_list pArguments;
va_start(pArguments, Format);
sprintf(Message,Format, pArguments);
CheckProcent(Message); // "%" Bug Fix
va_end(pArguments);
char currdate[11] = {0};
char outputmsg[2048];
if(WOL == 1)
{
sprintf(currdate, "(%02d:%02d:%02d)", t.wHour, t.wMinute, t.wSecond);
sprintf(outputmsg,"%s %sn", currdate,Message);
}
else
sprintf(outputmsg,"%sn", Message);
switch(Color)
{
case c_BoldGreen:
SetConsoleTextAttribute(this->Handle(FALSE),FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_INTENSITY);
break;
case c_BoldRed:
SetConsoleTextAttribute(this->Handle(FALSE),FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_RED );
break;
case c_Red:
SetConsoleTextAttribute(this->Handle(FALSE),FOREGROUND_RED | FOREGROUND_INTENSITY);
break;
case c_Green:
SetConsoleTextAttribute(this->Handle(FALSE),FOREGROUND_GREEN | FOREGROUND_INTENSITY);
break;
case c_Blue:
SetConsoleTextAttribute(this->Handle(FALSE),FOREGROUND_BLUE | FOREGROUND_INTENSITY);
break;
case c_Cyan:
SetConsoleTextAttribute(this->Handle(FALSE),FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
break;
case c_Yellow:
SetConsoleTextAttribute(this->Handle(FALSE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
break;
case c_Magenta:
SetConsoleTextAttribute(this->Handle(FALSE),FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
break;
case c_Grey:
SetConsoleTextAttribute(this->Handle(FALSE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
break;
}
CreateLog(Type,outputmsg);
WriteFile(this->Handle(FALSE), outputmsg, strlen(outputmsg), &dwBytesWritten, NULL);
SetConsoleTextAttribute(this->Handle(FALSE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
return;
}
HANDLE Logger::Handle(BOOL Input)
{
if(Input==TRUE)
return GetStdHandle(STD_INPUT_HANDLE);
else
return GetStdHandle(STD_OUTPUT_HANDLE);
}
void Logger::CreateLog(sLogType Type,const char* Format, ...)
{
SYSTEMTIME now;
GetLocalTime(&now);
char ConsoleLog[55];
char CommandsLog[55];
char ErrorLog[55];
char Date[55];
char SqlLog[55];
char TestLog[55];
sprintf(Date, ".\Logger\%02d-%02d-%02d\", now.wDay, now.wMonth, now.wYear);
CreateDirectory(Date,NULL);
sprintf(CommandsLog, ".\Logger\%02d-%02d-%02d\Commands.log", now.wDay, now.wMonth, now.wYear);
sprintf(ConsoleLog, ".\Logger\%02d-%02d-%02d\CONSOLE.log", now.wDay, now.wMonth, now.wYear);
sprintf(ErrorLog, ".\Logger\%02d-%02d-%02d\Error.log", now.wDay, now.wMonth, now.wYear);
sprintf(SqlLog, ".\Logger\%02d-%02d-%02d\Sql.log", now.wDay, now.wMonth, now.wYear);
sprintf(TestLog, ".\Logger\%02d-%02d-%02d\Test.log", now.wDay, now.wMonth, now.wYear);
va_list pArguments1;
va_start(pArguments1, Format);
sprintf(Message,Format, pArguments1);
va_end(pArguments1);
switch (Type)
{
case t_NULL:
break;
case t_Error:
{
SaveFile(ErrorLog, Message);
}
break;
case t_Default:
{
SaveFile(ConsoleLog,Message);
}
break;
case t_COMMANDS:
{
SaveFile(ConsoleLog,Message);
SaveFile(CommandsLog,Message);
}
break;
case t_SQL:
{
SaveFile(ConsoleLog,Message);
SaveFile(SqlLog,Message);
}
break;
case t_TEST:
{
SaveFile(TestLog,Message);
}
break;
}
}
void Logger::SaveFile(char *logString,char *Message)
{
FILE *stream;
stream=fopen(logString, "a+" );
fprintf(stream, "%s", Message);
fclose(stream);
}
所以,现在我的问题是 - 创建过程失败<2>,当我设置 TCHAR 程序[]=TEXT("应用程序.exe"); - 当我在 NULL 中设置参数时,他们启动该程序的许多副本 - 他们返回我 <87> 错误...他们将日志发送到主控制台窗口(应用程序窗口)。
你不能。根据 AllocConsole 的文档:
一个进程只能与一个控制台关联,因此如果调用进程已有控制台,则 AllocConsole 函数将失败。
更多信息
您不能同时使用CREATE_NEW_PROCESS
和DETACHED_PROCESS
。请参阅进程创建标志。我想你误解了DETACHED_PROCESS
是什么。从文档中:
DETACHED_PROCESS
对于控制台进程,新进程不会继承其父进程的控制台(默认值)。新进程可以在以后调用 AllocConsole 函数来创建控制台。有关更多信息,请参阅 创建控制台。
此值不能与CREATE_NEW_CONSOLE一起使用。
分离的进程是没有控制台的进程。您无法为没有控制台的进程创建新控制台。
从呼叫中删除DETACHED_PROCESS标志,它应该可以工作。
- C++:将控制台输出存储在宏中更好吗
- 在while循环中输入带有std::cin的字符串后,控制台会输出大量胡言乱语
- SSH通过/sbin/SSH无法读取RSA密钥文件(从控制台运行)
- C++控制台应用程序阻止退出
- 如何修复此iFile以将.txt输出到控制台
- 为什么控制台要求输入,即使代码中没有输入
- 在Qt Creator中,如何在连接到正在运行的进程后查看控制台输出
- 控制台输出在 Qt5 中未正确显示
- C++出现控制台错误.我无法识别源代码的问题
- C++程序不会从 Windows 控制台运行
- 有人可以向我解释为什么控制台输出 0 吗?
- Visual Studio 2017 停止工作,并在打开后显示许多控制台窗口
- 如何从 Win32 C++ 应用程序输出到父控制台窗口?
- Win32 API 控制台光标在 WriteConsole 后不移动
- 如何获取控制台窗口的宽度?
- 如何在 Win32 C++控制台应用程序中调用 UWP 类库
- 如何从Windows控制台调用.exe(C++)以在不同的目录(或任何目录)中创建文件夹?
- 来自Visual Studio中控制台项目的exe文件?
- 为什么即使使用 for 循环遍历我的向量,它也没有输出到控制台?(C++)
- 使用 std::string_view 的子字符串控制台输出