gpt4 book ai didi

cygwin - 从 cygwin shell 启动时写入标准输出的位置在哪里,没有重定向

转载 作者:行者123 更新时间:2023-12-03 22:42:19 30 4
gpt4 key购买 nike

我有一个应用程序,我们称之为 myapp.exe,它是双模式控制台/GUI,构建为/SUBSYSTEM:WINDOWS(有一个 3KB 的小垫片 myapp.com 导致 cmd.exe 等待显示新提示。)

如果我从命令提示符启动:

  • myapp -> cmd.exe 运行运行 myapp.exe 的 myapp.com。 stdout 最初是一个分离的控制台,使用 AttachConsolefreopen("CONOUT$", "w", stdout)我的输出出现在命令框中。好的
  • myapp.exe -> cmd.exe 过早显示提示(已知问题),否则同上。不是正常的使用场景。
  • myapp > log -> stdout 是一个文件,正常使用std::cout最终在文件中。好的

  • 如果我从 Windows 资源管理器启动:
  • myapp.com -> 控制台被创建,标准输出是控制台,输出进入控制台。与对整个程序使用/SUBSYSTEM:CONSOLE 的结果相同,只是我在 myapp.com 时添加了一个暂停。是控制台中的唯一进程。不是正常的使用场景。
  • myapp.exe -> stdout 是一个 NULL 句柄,我检测到这个并 Hook std::cout到图形用户界面。好的

  • 如果我从 Matlab shell 启动:
  • system('myapp')system('myapp.com')system('myapp.exe') -> 对于所有三种变体,标准输出通过管道传输到 MatLab。好的

  • 如果我从 cygwin bash shell 启动:
  • ./myapp.com -> 就像从 cmd.exe 启动一样,输出出现在命令框中。好的
  • ./myapp -> (bash 找到 ./myapp.exe )。 这是破案子 . stdout 是一个非 NULL 句柄,但输出无处可去。这是从 bash 运行程序的正常情况,需要修复!
  • ./myapp > log -> 就像从带有文件重定向的 cmd.exe 启动一样。好的
  • ./myapp | cat -> 类似于文件重定向,除了输出在控制台窗口上结束。好的

  • 有谁知道 cygwin 在启动/SUBSYSTEM:WINDOWS 进程时将什么设置为标准输出以及我如何绑定(bind) std::cout给它?或者至少告诉我如何找出我从 GetStdHandle(STD_OUTPUT_HANDLE)返回的句柄类型。 ?

    我的程序是用 Visual C++ 2010 编写的,没有 /clr ,以防万一。操作系统是 Windows 7 64 位。

    编辑:要求提供更多信息。

    CYGWIN 环境变量为空(或不存在)。
    GetFileType()返回 FILE_TYPE_UNKNOWN . GetLastError()返回 6 (ERROR_INVALID_HANDLE) .在调用 AttachConsole() 之前或之后检查都没有关系.

    但是,如果我只是忽略无效句柄和 freopen("CONOUT$", "w", stdout)然后一切正常。我只是缺少一种区分(破坏的)控制台输出和文件重定向的方法,以及 GetFileType()前提是。

    编辑:最终代码:
    bool is_console(HANDLE h)
    {
    if (!h) return false;

    ::AttachConsole(ATTACH_PARENT_PROCESS);

    if (FILE_TYPE_UNKNOWN == ::GetFileType(h) && ERROR_INVALID_HANDLE == GetLastError()) {
    /* workaround cygwin brokenness */
    h = ::CreateFile(_T("CONOUT$"), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (h) {
    ::CloseHandle(h);
    return true;
    }
    }

    CONSOLE_FONT_INFO cfi;
    return ::GetCurrentConsoleFont(h, FALSE, &cfi) != 0;
    }


    bool init( void )
    {
    HANDLE out = ::GetStdHandle(STD_OUTPUT_HANDLE);

    if (out) {
    /* stdout exists, might be console, file, or pipe */
    if (is_console(out)) {
    #pragma warning(push)
    #pragma warning(disable: 4996)
    freopen("CONOUT$", "w", stdout);
    #pragma warning(pop)
    }
    //std::stringstream msg;
    //DWORD result = ::GetFileType(out);
    //DWORD lasterror = ::GetLastError();
    //msg << result << std::ends;
    //::MessageBoxA(NULL, msg.str().c_str(), "GetFileType", MB_OK);
    //if (result == FILE_TYPE_UNKNOWN) {
    // msg.str(std::string());
    // msg << lasterror << std::ends;
    // ::MessageBoxA(NULL, msg.str().c_str(), "GetLastError", MB_OK);
    //}
    return true;
    }
    else {
    /* no text-mode stdout, launch GUI (actual code removed) */
    }
    }

    最佳答案

    GetFileType()函数允许区分某些类型的句柄,特别是控制台、管道、文件和损坏的句柄。

    关于cygwin - 从 cygwin shell 启动时写入标准输出的位置在哪里,没有重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4028353/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com