从控制台应用程序创建新控制台? C++

2024-03-28

我一直坚持为我的控制台应用程序和记录器创建新的控制台窗口。该代码适用于 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 );
}

该代码在应用程序为 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 失败 ,当我设置 TCHAR program[]=TEXT("application.exe"); 时- 当我将参数设置为 NULL 时,他们启动该程序的许多副本 - 他们返回我 错误...并且他们将日志发送到主控制台窗口(应用程序窗口)。


你不能。根据文档分配控制台 http://msdn.microsoft.com/en-us/library/windows/desktop/ms681944%28v=vs.85%29.aspx:

一个进程只能与一个控制台关联,因此如果调用进程已经有一个控制台,则 AllocConsole 函数将失败。

更多信息

你不能使用CREATE_NEW_PROCESS and DETACHED_PROCESS一起。看进程创建标志 http://msdn.microsoft.com/en-us/library/windows/desktop/ms684863%28v=vs.85%29.aspx。我认为你误解了什么DETACHED_PROCESS是。从文档中:

分离进程

对于控制台进程,新进程不会继承其父进程的控制台(默认)。新进程可以稍后调用AllocConsole函数来创建控制台。有关更多信息,请参阅创建控制台。

该值不能与 CREATE_NEW_CONSOLE 一起使用。

分离进程是没有控制台的进程。您无法为没有控制台的进程创建新控制台。

从您的调用中删除 DETACHED_PROCESS 标志,它应该可以工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从控制台应用程序创建新控制台? C++ 的相关文章

随机推荐

  • 如何使用 uibinder 创建带有子级的 gwt 复合组件?

    我想创建一个组件来装饰它的子组件 例如 mycomponent ui xml
  • formData.has() 不是一个函数[重复]

    这个问题在这里已经有答案了 我正在尝试执行简单的 ajax 文件上传 但收到 未捕获的类型错误 formData has 不是函数 如果我还注释掉 formData has 检查函数并将其替换为 formData append myResu
  • MS Azure Web 角色 - 如何指定 Webroot 驱动器存储大小

    我正在开发一个非常大且复杂的企业 Web 应用程序 托管在 azure 中 注意到 Web 根目录位于 E 盘 我还注意到 C 驱动器的大小为 490GB 但有趣的是 E盘上的Web根目录大小只有1GB 有什么方法可以指定您要安装的驱动器
  • 如何保护此代码免遭 SQL 注入?有点困惑

    我已经阅读了各种来源 但我不确定如何将它们实现到我的代码中 我想知道是否有人可以帮我快速完成它 一旦我在代码中被展示如何做到这一点 我想我就能学会它 这是来自我在网上找到的 AJAX 自动完成 尽管我看到它由于 queryString 或其
  • 使用php将图像保存到服务器

    嘿 我有以下脚本 基本上是一个闪存文件向它发送一些数据 它创建一个图像 然后为用户打开一个另存为对话框 以便他们可以将图像保存到系统中 问题来了 如何我还要将图像保存到我的服务器吗
  • Laravel - 多对多多态关系

    我正在努力反对 Laravel 5 7 中的多态关系定义 数据情况如下 我有一个用户模型 一个产品模型和一个销售模型 我基本上想为我的用户构建一个愿望清单 它可以包含商品和产品 并且我希望在那里有一个多态关系 因为我将不得不添加新类型的东西
  • AWS S3 中有乐观锁吗?

    我在 s3 中有一个 excel 文件 由于不同的程序读取和写入它 我需要保证每个程序都写入它们读取的版本 S3仅保证新创建对象的读后一致性 以及覆盖和删除对象的最终一致性 如果您的 Excel 文件足够小 小于 400kb 您可以将其存储
  • TYPO3 表单多复选框部分

    我尝试编辑核心文件 form Resources Private Frontend Partials Field Field html 以更改前端中的 html 输出 如果我更改该文件 它不会产生任何影响 如果我更改核心文件 form Re
  • 同时显示两个片段

    From FragmentPagerAdapter in case 0我实例化了fragment A我想显示的这个片段显示里面的两个片段frag A 视图未显示 我的 FragmentPagerAdapter 由主类调用来填充 viewpa
  • 如何使用 VS 2008 和 IE 完全禁用 JavaScript 错误

    我试图防止 VS 因 JS 错误而中断 我有以下设置 在 IE 下 Tools gt Internet Settings gt Advanced tab gt Browsing Disable script debugging Intern
  • Jquery Ajax CORS + HttpOnly Cookie

    我已经在我当前的项目中使用了 CORS 尽管我似乎无法正常工作的一件事是 cookie 现在我得到了 cookie 服务器发出它并将其发送下来 firefox 接受它 我可以在 firebug cookies 部分看到它 然而 当我对该服务
  • 如何使用 Swashbuckle.AspNetCore 将自定义泛型类型公开为 Swagger 架构中的字符串

    我有一个自定义泛型类型 大致如下所示 public struct Foo
  • Scrapy:如何在蜘蛛中使用项目以及如何将项目发送到管道?

    我是新来的scrapy我的任务很简单 对于给定的电子商务网站 抓取所有网站页面 寻找产品页面 如果 URL 指向产品页面 创建一个项目 处理项目以将其存储在数据库中 我创建了蜘蛛 但产品只是打印在一个简单的文件中 我的问题是关于项目结构 如
  • 连接两个具有交替值的数组

    连接两个具有交替值的数组的最佳方法是什么 比方说array1 is 1 3 5 7 array2 is 2 4 6 8 我想将这两个数组组合起来 结果是 1 2 3 4 5 6 7 8 In Java int a1 1 3 5 7 int
  • ajax jquery 总是运行错误

    每次我运行我的 ajax jquery 函数时 我都会收到一个错误 这适用于我所有的 ajax 调用 这是我的代码的示例 function FindContact CompanyName DivisionName FirstName Las
  • 如何使用 Python 制作时间表的图像/PDF

    我正在解决时间表安排问题 并希望以 PDF 或图像集的形式打印最终输出 我有多个部分 每个部分都有自己的时间表 我为每个部分创建了一个二维数组 该数组的大小为 5 x 5 5 天 每天有 5 个时段 数组的每个索引代表一个讲座时段 现在 这
  • printf 上的分段错误 - NASM 64 位 Linux

    我尝试使用输入四个浮点数scanf 将它们存储到堆栈中 然后使用vmovupd将它们复制到寄存器以供使用 我的问题是 当我尝试输出这 4 个数字时 程序段错误位于printf 我认为这是堆栈的问题 但我尝试多次弹出 一次多条指令 但无济于事
  • 前端和后端应该由不同的控制器处理吗?

    在我之前的学习项目中 我总是使用单个控制器 但现在我想知道这是否是好的做法 甚至总是可能的 在所有 RESTful Rails 教程中 控制器都有一个show an edit and an index看法 如果授权用户登录 则edit视图变
  • C# 将 XPath 与 XmlDocument 结合使用 - 无法选择命名空间中的节点(返回 null)

    我正在尝试做一些应该很简单的事情 但我遇到了可怕的麻烦 我已经尝试过 StackOverflow 中多个类似问题的代码 但没有成功 我正在尝试通过澳大利亚政府的 ABN 查询来获取各种信息 以下是匿名返回 XML 值
  • 从控制台应用程序创建新控制台? C++

    我一直坚持为我的控制台应用程序和记录器创建新的控制台窗口 该代码适用于 GUI 应用程序 但不适用于控制台 并且它们需要 带有 DETACHED PROCESS 标志的 CreateProcess 函数 Logger Log DWORD P