【问题标题】:Piping console output from WinMain when running from a console从控制台运行时从 WinMain 管道控制台输出
【发布时间】:2020-06-05 06:13:31
【问题描述】:

我正在尝试从控制台从 VCL 表单应用程序中的 WinMain 函数传输标准输出。

特别是,我需要在控制台中执行此操作:

mywinprogram.exe -v > toMyFile.txt 

-v 代表版本。传递的信息只是应用程序的版本。

我可以使用此处的答案将输出控制台: How do I get console output in C++ with a Windows program?

但将输出通过管道传输到文件不起作用。

当不带任何参数启动时,应用程序的行为应该像一个“普通”的 Windows 应用程序。

以这种方式获取信息的能力是为了自动构建系统的工作。

【问题讨论】:

  • 然后会发生什么?
  • @nsm 输出发送到控制台,创建的文件为空
  • @TedLyngmo 我正在使用你的答案并且得到了它的工作。正要奖励答案,但您似乎已将其从帖子中删除?
  • @TotteKarlsson 哦,真的吗? :-) 我删除了它,因为我认为它不起作用 :-D 现在取消删除它。

标签: c++ c++builder vcl winmain


【解决方案1】:

这是我在Sev 的答案中找到的版本。

首先调用这个函数。_tWinMain():

#include <cstdio>
#include <fcntl.h>
#include <io.h>

void RedirectIOToConsole() {
    if (AttachConsole(ATTACH_PARENT_PROCESS)==false) return;

    HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    int SystemOutput = _open_osfhandle(intptr_t(ConsoleOutput), _O_TEXT);

    // check if output is a console and not redirected to a file
    if(isatty(SystemOutput)==false) return; // return if it's not a TTY

    FILE *COutputHandle = _fdopen(SystemOutput, "w");

    // Get STDERR handle
    HANDLE ConsoleError = GetStdHandle(STD_ERROR_HANDLE);
    int SystemError = _open_osfhandle(intptr_t(ConsoleError), _O_TEXT);
    FILE *CErrorHandle = _fdopen(SystemError, "w");

    // Get STDIN handle
    HANDLE ConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
    int SystemInput = _open_osfhandle(intptr_t(ConsoleInput), _O_TEXT);
    FILE *CInputHandle = _fdopen(SystemInput, "r");

    //make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog point to console as well
    ios::sync_with_stdio(true);

    // Redirect the CRT standard input, output, and error handles to the console
    freopen_s(&CInputHandle, "CONIN$", "r", stdin);
    freopen_s(&COutputHandle, "CONOUT$", "w", stdout);
    freopen_s(&CErrorHandle, "CONOUT$", "w", stderr);

    //Clear the error state for each of the C++ standard stream objects.
    std::wcout.clear();
    std::cout.clear();
    std::wcerr.clear();
    std::cerr.clear();
    std::wcin.clear();
    std::cin.clear();
}

【讨论】:

  • 感谢您的回复!不允许此应用程序生成额外的控制台。仅在请求时将某些信息输出到控制台(该信息用于自动构建系统)。有什么方法可以抑制额外控制台的生成?
  • @TotteKarlsson 这正是我正在寻找的 :-) 我几乎可以肯定我在 C++ Builder 4 中做过类似的事情——但那是很久以前的事了。哦,好吧,当雷米看到这个,他会解决的。
  • 我试过你的方法,效果很好。完美的!但是,我正在更新我的问题以定义更多所需的行为。
  • @TotteKarlsson 新版本...似乎可以在 WSL(Windows 上的 Unbunto)提示符下工作,但不能来自经典的 CMD.EXE 提示符... :-/
  • 确认这适用于 powershell 和 bash 控制台,但不适用于“常规”cmd 控制台。
猜你喜欢
  • 2019-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-08
  • 2013-07-28
  • 1970-01-01
  • 2022-11-03
  • 1970-01-01
相关资源
最近更新 更多