我坚持为我的控制台应用程序创建新的控制台窗口,用于记录器。该代码适用于GUI应用程序,但不适用于控制台,它们需要:带有DETACHED_PROCESS标志的CreateProcess函数。
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 );
}
该代码,当app为GUI时创建一个新控制台,并显示“Log.ConsoleOutPut(1,c_Green,t_Default,”Debug Logger: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 %s\n", currdate,Message);
}
else
sprintf(outputmsg,"%s\n", 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);
}
所以,现在我的问题是 - CreateProcess失败&lt; 2&gt;,当我设置TCHAR program [] = TEXT(“application.exe”); - 当我设置为NULL时,他们会启动该程序的许多副本 - 他们返回我&lt; 87&gt;错误......他们将日志发送到主控制台窗口(应用程序窗口)。
答案 0 :(得分:2)
你做不到。根据{{3}}的文档:
进程只能与一个控制台关联,因此如果调用进程已有控制台,则AllocConsole函数将失败。
您不能同时使用CREATE_NEW_PROCESS
和DETACHED_PROCESS
。见AllocConsole。我想你误解了DETACHED_PROCESS
是什么。来自文档:
<强> DETACHED_PROCESS 强>
对于控制台进程,新进程不会继承其父进程控制台(默认值)。新进程可以稍后调用AllocConsole函数来创建控制台。有关更多信息,请参阅创建控制台。
此值不能与CREATE_NEW_CONSOLE一起使用。
分离进程是没有控制台的进程。您无法为没有控制台的进程创建新控制台。
从您的通话中删除DETACHED_PROCESS标志,它应该可以正常工作。