• 大小: 6KB
    文件类型: .zip
    金币: 1
    下载: 0 次
    发布日期: 2021-06-09
  • 语言: 其他
  • 标签: stdout  redirect  

资源简介

可利用本方法在没有源码的情况下,将console程序的标准输出重定向到自己的程序中来。网上很多关于此类方法的描述,经实验大多在标准Unix和Linux上可用,有个别在VC2010通过匿名管道方式可用,但在VS2015的CRT运行时库下失效,主要是*stdout = *hf;语句失效导致,本代码重新通过命名管道方式得以通用实现,在VS2010、VS2015下均能得到正确结果。

资源截图

代码片段和文件信息

#include “stdio.h“
#include “windows.h“
#include “io.h“
#include 
#include 

#define _O_TEXT 0x4000 /* file mode is text (translated) */
#define BUF_SIZE (4096)
HANDLE m_hOutputReadTmp = INVALID_HANDLE_VALUE;
// HANDLE m_hOutputWrite = INVALID_HANDLE_VALUE;
void DisplayMsg(char* szMsg)
{
  OutputDebugStringA(szMsg);
}

//callback function of stdout redirect:
void RedirectStdOutCallback(char* buf unsigned int bytes)
{ //the data is redirected into the buf[].
  DisplayMsg(buf);
}

DWORD WINAPI ReadStdoutThread(LPVOID lpvThreadParam)
{
  HANDLE hStdRead = m_hOutputReadTmp;
  char lpBuffer[BUF_SIZE];
  DWORD nBytesRead=0;
  while (TRUE){
    if (!ReadFile(hStdRead lpBuffer sizeof(lpBuffer)-1 &nBytesRead NULL)|| !nBytesRead){
      DWORD result = GetLastError();
      if (result == ERROR_IO_PENDING){
        Yield();
        continue;
      }
//       if (result == ERROR_HANDLE_EOF || result == ERROR_BROKEN_PIPE)
//         break;
      DisplayMsg(“std redirect reading failed.“);//Something bad happened.
      break;
    }
    if(nBytesRead <= 3){
      // Windows has a habit of sending 1 or 2 characters of every message and then sending
      // the rest in a second message.  This is “ok“ really except our Console class is hardly
      // free of overhead so it‘s helpful if we can concatenate the couple of messages together.
      // But we don‘t want to break the ability to print progressive status bars like ‘....‘
      // so I use a clever Yield/Peek loop combo that keeps reading as long as there‘s new data
      // immediately being fed to our pipe.
      DWORD u32_avail = 0;
      do{
        Yield();
        if (!PeekNamedPipe(hStdRead 0 0 0 &u32_avail 0))
          break;
        if (u32_avail == 0)
          break;
        DWORD loopread=0;
        if (!ReadFile(hStdRead &lpBuffer[nBytesRead] sizeof(lpBuffer) - nBytesRead - 1 &loopread NULL)|| !loopread)
          break;
        nBytesRead+=loopread;
      }while(nBytesRead    }

    //get the output of printf function:
    lpBuffer[nBytesRead] = ‘\0‘;
    //replace your code here. Do it yourself.
    RedirectStdOutCallback(lpBuffer nBytesRead);
  }
  return 0;
}

bool StdoutRedirect(FILE* stdstream)
{
  bool bRet = false;
if (!stdstream)
return bRet;
  FILE *hf = NULL;
do {

//   if (!CreatePipe(&m_hOutputReadTmp &m_hOutputWrite 0 0)){
//     DisplayMsg(“CreatePipe“);
//     break;
//   }
const char * stream_name = (stdstream == stderr ? “stderr“ : “stdout“);
char pipe_name[128] = { ‘\0‘ };
sprintf(pipe_name “\\\\.\\pipe\\stdredirect_%s%d“ stream_name GetCurrentProcessId());
m_hOutputReadTmp = CreateNamedPipe(pipe_name PIPE_ACCESS_INBOUND 0 1 BUF_SIZE BUF_SIZE 0 NULL);
if (m_hOutputReadTmp == INVALID_HANDLE_VALUE)
break;
//   int hCrt;
    hf = freopen(pipe_name “wb“ stdstream);
//  //AllocConsole();
//   hCrt = _open_osfhandle((long)m_hOutpu

 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----
     文件         888  2018-09-07 21:48  stdredirect.sln
     文件        4375  2018-09-08 13:59  stdredirect.vcxproj
     文件         506  2018-09-07 21:48  stdredirect.vcxproj.filters
     文件         143  2018-09-07 20:18  stdredirect.vcxproj.user
     文件        2559  2018-09-07 21:46  标准输出(stdout)重定向.txt
     文件        3822  2018-09-08 14:31  stdredirect.cpp

评论

共有 条评论