You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CreateProcess重定向输出到命名管道时ReadFile返回233的问题

问题描述

尝试通过CreateProcess执行命令,将STDOUT重定向到本地服务器创建的命名管道,客户端连接管道接收输出,但客户端调用ReadFile时返回错误码233(ERROR_PIPE_NOT_CONNECTED)。

服务器端代码

命名管道创建代码

char pipeunc[MAX_PATH];
SECURITY_DESCRIPTOR sd;
SECURITY_ATTRIBUTES sa;

// Setup DACL for NamedPipe
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
SetSecurityDescriptorControl(&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED);
sa = { sizeof(sa), &sd, FALSE };

sprintf(pipeunc, "\\\\.\\pipe\\%s", pipename);

// Create the named-pipe
HANDLE pipe = CreateNamedPipeA(
    pipeunc,
    PIPE_ACCESS_OUTBOUND,
    PIPE_TYPE_MESSAGE,
    PIPE_UNLIMITED_INSTANCES,
    0,
    0,
    0,
    &sa
);

if (pipe == NULL) {
    fprintf(fd, "Error: CreateNamedPipeA: %d\n", GetLastError());
    return NULL;
}

CreateProcess重定向代码

HANDLE pipeh;
STARTUPINFOA sinfo;
PROCESS_INFORMATION pinfo;
bool res;

pipeh = remote::SetupNamedPipe(pipe_name, fd);

memset(&sinfo, 0, sizeof(sinfo));
sinfo.cb = sizeof(sinfo);
sinfo.dwFlags |= STARTF_USESTDHANDLES;

sinfo.hStdOutput = sinfo.hStdError = pipeh; // Redirect output to named-pipe

// Wait until client connects.
ConnectNamedPipe(pipeh, NULL);
SetHandleInformation(pipeh, HANDLE_FLAG_INHERIT, 0);

res = CreateProcessA(
    NULL,
    const_cast<LPSTR>(cmd),
    NULL,
    NULL,
    TRUE,
    0,
    NULL,
    NULL,
    &sinfo,
    &pinfo
);

客户端代码

连接命名管道代码

static HANDLE pipeh;

// Create a handle to the remote pipe
pipeh = CreateFileA(
    const_cast<LPCSTR>(PipeName),
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    0,
    NULL
);

ReadFile读取代码

while(1){
    res = ReadFile(
        pipeh_read, // is the same handle(pipeh)
        buf,
        PIPE_MAX_READ_SIZE,
        NULL,
        NULL
    );
    printf("%s\n", buf);

    if (!res) {
        puts("Process returned.");
#ifdef DEBUG
        printf("ReadFile code: %d\n", GetLastError());
#endif
        return;
    }

}
错误码233(ERROR_PIPE_NOT_CONNECTED)原因及修复方案

错误码233表示管道连接已断开或未正确建立,以下是核心问题和修复步骤:

  • 管道句柄继承标志设置时机错误:
    服务器端在ConnectNamedPipe后立即取消句柄继承属性,导致CreateProcess无法将句柄传递给子进程,子进程写入管道失败,连接断开。
    修复:将SetHandleInformation移至CreateProcess之后执行,确保子进程已继承句柄:

    res = CreateProcessA(...);
    if (res) {
        SetHandleInformation(pipeh, HANDLE_FLAG_INHERIT, 0);
        WaitForSingleObject(pinfo.hProcess, INFINITE);
        CloseHandle(pinfo.hProcess);
        CloseHandle(pinfo.hThread);
        CloseHandle(pipeh);
    }
    
  • 未检查ConnectNamedPipe返回值:
    ConnectNamedPipe可能因客户端连接异常失败,未处理会导致后续操作使用无效句柄。
    修复:添加返回值检查:

    BOOL connectResult = ConnectNamedPipe(pipeh, NULL);
    if (!connectResult && GetLastError() != ERROR_PIPE_CONNECTED) {
        fprintf(fd, "Error: ConnectNamedPipe: %d\n", GetLastError());
        CloseHandle(pipeh);
        return NULL;
    }
    
  • ReadFile未传递字节数指针:
    消息类型管道需要获取实际读取字节数,否则无法正确终止字符串,引发读取逻辑错误。
    修复:修改ReadFile调用,传入字节数变量并添加字符串终止符:

    DWORD bytesRead;
    while(1){
        res = ReadFile(
            pipeh,
            buf,
            PIPE_MAX_READ_SIZE - 1,
            &bytesRead,
            NULL
        );
        if (!res) {
            DWORD err = GetLastError();
            err == ERROR_BROKEN_PIPE ? puts("Pipe closed by server.") : printf("ReadFile error: %d\n", err);
            return;
        }
        buf[bytesRead] = '\0';
        printf("%s\n", buf);
    }
    
  • 未正确关闭服务器端管道句柄:
    子进程退出后未关闭管道句柄,客户端无法感知连接断开,引发233错误。
    修复:子进程退出后关闭管道句柄:

    WaitForSingleObject(pinfo.hProcess, INFINITE);
    CloseHandle(pinfo.hProcess);
    CloseHandle(pinfo.hThread);
    CloseHandle(pipeh);
    
  • 客户端未检查CreateFile返回值:
    客户端未验证管道连接是否成功,若CreateFile失败,后续ReadFile使用无效句柄导致错误。
    修复:添加连接检查:

    pipeh = CreateFileA(...);
    if (pipeh == INVALID_HANDLE_VALUE) {
        printf("Failed to connect pipe: %d\n", GetLastError());
        return;
    }
    

内容的提问来源于stack exchange,提问作者zbx0310

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 19:20:07