【问题标题】:No output while trying to redirect cmd.exe stdout尝试重定向 cmd.exe 标准输出时没有输出
【发布时间】:2014-05-06 19:00:43
【问题描述】:

我编写了一个小程序,它应该通过给它一个命令来重定向 cmd.exe 标准输出,并使用管道来获取输入。

程序在使用ipconfig 之类的命令时运行良好,但是当我尝试将tasklist 作为命令传递时,程序就会卡住并且不会得到任何输出。

代码如下:

#include <Windows.h>
#include <tchar.h>
#include <iostream>

#define BUFFSIZE 100000

int wmain(int argc, wchar_t* argv[])
{    
    HANDLE  hReadPipe, hWritePipe;
    SECURITY_ATTRIBUTES saAttr;
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;
    if (CreatePipe(&hReadPipe, &hWritePipe, &saAttr, 0) != 0)
    {
        STARTUPINFO structStartUpInfo;
        ZeroMemory(&structStartUpInfo, sizeof(STARTUPINFO));
        structStartUpInfo.cb = sizeof(STARTUPINFO);
        structStartUpInfo.wShowWindow = SW_HIDE;
        structStartUpInfo.hStdInput = hReadPipe;
        structStartUpInfo.hStdOutput = hWritePipe;
        structStartUpInfo.dwFlags = STARTF_USESTDHANDLES;
        PROCESS_INFORMATION structProcInf;
        ZeroMemory(&structProcInf, sizeof(PROCESS_INFORMATION));
        if (CreateProcess(NULL, L"tasklist", NULL, NULL, TRUE, NORM    AL_PRIORITY_CLASS, NULL, NULL, &structStartUpInfo, &structProcInf) != 0)
        {
            WaitForSingleObject(structProcInf.hProcess, INFINITE);
            CHAR output[BUFFSIZE];
            DWORD wdByteToRead = BUFFSIZE;
            DWORD dwByteread;
            ReadFile(hReadPipe, output, wdByteToRead, &dwByteread, NULL);
            std::string final = output;
            final = final.substr(0, dwByteread);
            std::cout << final.c_str();
        }
    }
    return 0;

我该如何解决这个问题?

【问题讨论】:

    标签: c++ windows pipe


    【解决方案1】:

    管道具有最大缓冲区大小。 tasklist 可能正在写入缓冲区大小而不会阻塞,但之后写入时会阻塞。

    通过查看您的代码,子进程需要读取自己的输入以避免阻塞。

    你需要调用CreatePipe两次,然后为自己(父进程)保留一对的读取管道和另一对的写入管道,并提供前一对的写入管道和读取管道后一对子进程。

    即便如此,管道也有一个最大的缓冲区大小。为避免子进程阻塞,必须在父进程中不断从管道中读取。

    编辑:如果您不打算写入子进程,您也可以关闭管道的父级写入端或将hStdInput 设置为零。

    此外,您应该初始化hStdError,或者使用另一个管道的写入端或将其设置为零。

    基于(其中一个)Microsoft C 运行时的程序在标准句柄为零时会简单地忽略它,但其他程序可能不会,因此使用 3 对管道可能是最安全的方法。但是,您还必须从该管道中读取数据,以避免子进程在写入时阻塞,尽管不太可能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-08
      • 1970-01-01
      • 2014-01-20
      • 2011-12-08
      • 1970-01-01
      相关资源
      最近更新 更多