使用管道(C和WIndows)时,似乎无法打印子进程的标准输出

使用管道(C和WIndows)时,似乎无法打印子进程的标准输出,c,windows,C,Windows,我似乎无法让它工作,我已经试了又试。在momenet它只是打印出这个 #include <stdio.h> #include <string.h> #include <windows.h> #define BUFSIZE 2048 HANDLE stdout_write, stdout_read; void create_pipe(void) { SECURITY_ATTRIBUTES attr; attr.nLength = sizeo

我似乎无法让它工作,我已经试了又试。在momenet它只是打印出这个

#include <stdio.h>
#include <string.h>
#include <windows.h>

#define BUFSIZE 2048

HANDLE stdout_write, stdout_read;

void create_pipe(void)
{
    SECURITY_ATTRIBUTES attr;
    attr.nLength = sizeof(SECURITY_ATTRIBUTES);
    attr.bInheritHandle = TRUE;
    attr.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&stdout_read, &stdout_write, &attr, 0)) {
        printf("CreatePipe() failed\n");
    } else {
        printf("CreatePipe() success\n");
    }

    if (!SetHandleInformation(stdout_read, HANDLE_FLAG_INHERIT, 0)) {
        printf("SetHandleInformation() failed\n");
    } else {
        printf("SetHandleInformation() success\n");
    }
}


void read_pipe_output(void)
{
    char buf[BUFSIZE] = {0};
    DWORD dwRead = 0;
    BOOL bsuccess = 0;

    for (;;) {
        bsuccess = ReadFile(stdout_read, buf, BUFSIZE, &dwRead, NULL);
        if( ! bsuccess || dwRead == 0 ) break;
    }

    printf("buf: %s\n", &buf[0]);
}


int main(int argc, char *argv[])
{
    char *fuck = "C:\\Windows\\System32\\cmd.exe";
    char *cmd = "C:\\Windows\\System32\\cmd.exe /c dir";

    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    memset(&si, 0x0, sizeof(si));
    memset(&pi, 0x0, sizeof(pi));

    si.cb = sizeof(STARTUPINFO);
    si.wShowWindow = FALSE;
    si.hStdOutput = stdout_write;
    si.hStdError = stdout_write;
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

    create_pipe();

    if (!CreateProcessA(fuck, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
       printf("error\n");
    } else {
        CloseHandle(stdout_write);
    }

    read_pipe_output();
  



    CloseHandle(stdout_read);
    printf("completed\n");
    
    return 0;
}
#包括
#包括
#包括
#定义bufsize2048
处理标准输出写入、标准输出读取;
void创建管道(void)
{
安全属性属性属性;
attr.nLength=sizeof(安全属性);
attr.bInheritHandle=TRUE;
attr.lpSecurityDescriptor=NULL;
如果(!CreatePipe(&stdout\u read,&stdout\u write,&attr,0)){
printf(“CreatePipe()失败\n”);
}否则{
printf(“CreatePipe()成功\n”);
}
if(!SetHandleInformation(标准输出读取,句柄标志继承,0)){
printf(“SetHandleInformation()失败\n”);
}否则{
printf(“SetHandleInformation()成功\n”);
}
}
无效读取\管道\输出(无效)
{
char buf[BUFSIZE]={0};
DWORD dwRead=0;
boolbsuccess=0;
对于(;;){
bsuccess=ReadFile(stdout_read,buf,BUFSIZE,&dwRead,NULL);
如果(!bsucces | | dwRead==0)中断;
}
printf(“buf:%s\n”和&buf[0]);
}
int main(int argc,char*argv[])
{
char*fuck=“C:\\Windows\\System32\\cmd.exe”;
char*cmd=“C:\\Windows\\System32\\cmd.exe/C dir”;
STARTUPINFO si;
处理信息;
memset(&si,0x0,sizeof(si));
memset(&pi,0x0,sizeof(pi));
si.cb=sizeof(STARTUPINFO);
si.wShowWindow=FALSE;
si.hStdOutput=stdout\u write;
si.hStdError=stdout\u write;
si.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
创建_管道();
if(!CreateProcessA(fuck,cmd,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)){
printf(“错误\n”);
}否则{
闭合手柄(stdout_write);
}
读取管道输出();
闭合手柄(标准读数);
printf(“已完成的”);
返回0;
}
我想打印“ls”的输出,它工作得很好,但我想使用管道,这样我就可以对输出数据进行处理


感谢您的帮助

阅读问题,因为它已编辑为包含我的答案。我将在这里包括代码也

#include <stdio.h>
#include <string.h>
#include <windows.h>

#define BUFSIZE 2048

HANDLE stdout_write, stdout_read;

void create_pipe(void)
{
    SECURITY_ATTRIBUTES attr;
    attr.nLength = sizeof(SECURITY_ATTRIBUTES);
    attr.bInheritHandle = TRUE;
    attr.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&stdout_read, &stdout_write, &attr, 0)) {
        printf("CreatePipe() failed\n");
    } else {
        printf("CreatePipe() success\n");
    }

    if (!SetHandleInformation(stdout_read, HANDLE_FLAG_INHERIT, 0)) {
        printf("SetHandleInformation() failed\n");
    } else {
        printf("SetHandleInformation() success\n");
    }
}


void read_pipe_output(void)
{
    char buf[BUFSIZE];
    DWORD dwRead = 0;
    BOOL bsuccess = 0;

    memset(&buf, 0x0, sizeof(buf));

    for (;;) {
        bsuccess = ReadFile(stdout_read, buf, BUFSIZE, &dwRead, NULL);
        if( ! bsuccess || dwRead == 0 ) break;
    }

    printf("buf: %s\n", &buf[0]);
}


int main(int argc, char *argv[])
{
    char *cmd = "ls";

    create_pipe();

    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    memset(&si, 0x0, sizeof(si));
    memset(&pi, 0x0, sizeof(pi));

    si.cb = sizeof(STARTUPINFO);
    si.wShowWindow = FALSE;
    si.hStdOutput = stdout_write;
    si.hStdError = stdout_write;
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

    if (!CreateProcessA(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
       printf("error\n");
    } else {
        printf("CreateProcess() success\n");
        CloseHandle(stdout_write);
    }

    
    WaitForSingleObject( pi.hProcess, INFINITE );

    read_pipe_output();

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    CloseHandle(stdout_read);
    printf("completed\n");
    
    return 0;
}
#包括
#包括
#包括
#定义bufsize2048
处理标准输出写入、标准输出读取;
void创建管道(void)
{
安全属性属性属性;
attr.nLength=sizeof(安全属性);
attr.bInheritHandle=TRUE;
attr.lpSecurityDescriptor=NULL;
如果(!CreatePipe(&stdout\u read,&stdout\u write,&attr,0)){
printf(“CreatePipe()失败\n”);
}否则{
printf(“CreatePipe()成功\n”);
}
if(!SetHandleInformation(标准输出读取,句柄标志继承,0)){
printf(“SetHandleInformation()失败\n”);
}否则{
printf(“SetHandleInformation()成功\n”);
}
}
无效读取\管道\输出(无效)
{
字符buf[BUFSIZE];
DWORD dwRead=0;
boolbsuccess=0;
memset(&buf,0x0,sizeof(buf));
对于(;;){
bsuccess=ReadFile(stdout_read,buf,BUFSIZE,&dwRead,NULL);
如果(!bsucces | | dwRead==0)中断;
}
printf(“buf:%s\n”和&buf[0]);
}
int main(int argc,char*argv[])
{
char*cmd=“ls”;
创建_管道();
STARTUPINFO si;
处理信息;
memset(&si,0x0,sizeof(si));
memset(&pi,0x0,sizeof(pi));
si.cb=sizeof(STARTUPINFO);
si.wShowWindow=FALSE;
si.hStdOutput=stdout\u write;
si.hStdError=stdout\u write;
si.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if(!CreateProcessA(NULL,cmd,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi)){
printf(“错误\n”);
}否则{
printf(“CreateProcess()成功\n”);
闭合手柄(stdout_write);
}
WaitForSingleObject(pi.hProcess,无限);
读取管道输出();
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
闭合手柄(标准读数);
printf(“已完成的”);
返回0;
}

windows上的
ls
是什么?哈哈,我明白你的意思了。但是我在没有管道的情况下测试了它,它把目录的内容打印出来了吗?我会用“dir”试一下,然后lol。编辑:我用“dir”试过,但还是一样。。。使用“ls”没有问题。
stdout\u write
在写入
si.hStdOutput
si.hStdError
时未初始化。使用
STARTF\u usedhandles
时,还应初始化
hStdInput
成员。要打印字符,应使用
%c
,而不是
%s
printf(“buf:%c\n”,buf[0])。调用
CreateProcess
时,如果
bInheritHandles
设置为FALSE,则当您要使用
STARTF\u USESTDHANDLES
时,应将其设置为TRUE@nevilad i use attr.bInheritHandle=TRUE;不是错的吗?解释或指出原始代码的错误也会改善答案是的,有很多问题。您没有使
stdout\u read
可继承,您没有初始化
hStdInput
成员
STARTUPINFO
,但能够从
stdout\u read
读取子进程输出。孩子如何知道自己应该写到标准输出读取?另一个问题是如何使用
CreateProcess
运行
ls
dir
。此链接()说明至少应使用
cmd/c dir
@nevilad运行
dir
(您提供的链接中的最后一个答案回答了有关ls和dir的问题…我确实认为可能是这样的lol。)至少我现在知道只需要使用cmd/c命令,但这就是它的工作原理。答案中的代码是错误的-它使用了
char*cmd=“ls”,问题的原始代码相同,但问题的最后编辑版本是正确的,它使用
char*cmd=“C:\\Windows\\System32\\cmd.exe/C dir”。更正答案。