Winapi 取消管道的IO

Winapi 取消管道的IO,winapi,pipe,Winapi,Pipe,我正在使用CreatePipe将stdin/out从进程重定向到我的进程 到目前为止效果还不错。问题是当我想要终止等待客户机进程写入内容的线程时 我可以使用CancelIoEx,但这只适用于Vista+,我还需要一个XP解决方案。如果没有CancelIoEx,另一个线程中的ReadFile将永远不会返回 我也不能使用重叠的ReadFile,因为使用CreatePipe创建的管道不支持它 有任何选项吗?在创建子进程时,将句柄保存到标准输出管道的写入端。然后,您可以向该线程写入一个字符,以解除对调用

我正在使用CreatePipe将stdin/out从进程重定向到我的进程

到目前为止效果还不错。问题是当我想要终止等待客户机进程写入内容的线程时

我可以使用CancelIoEx,但这只适用于Vista+,我还需要一个XP解决方案。如果没有CancelIoEx,另一个线程中的ReadFile将永远不会返回

我也不能使用重叠的ReadFile,因为使用CreatePipe创建的管道不支持它


有任何选项吗?

在创建子进程时,将句柄保存到标准输出管道的写入端。然后,您可以向该线程写入一个字符,以解除对调用ReadFile的线程的阻止,该线程正在从标准输出管道的读取端进行读取。为了不将其解释为数据,请创建一个Event CreateEvent,该事件在写入伪字符的线程中设置为SetEvent,并在ReadFile返回后进行检查。有点凌乱,但似乎有效

/* Init */

stdout_closed_event = CreateEvent(NULL, TRUE, FALSE, NULL);

/* Read thread */

read_result = ReadFile(stdout_read, data, buf_len, &bytes_read, NULL);            
if (!read_result)
    ret = -1;
else 
    ret = bytes_read;    
if ((bytes_read > 0) && (WAIT_OBJECT_0 == WaitForSingleObject(stdout_closed_event, 0))) {
    if (data[bytes_read-1] == eot) {
        if (bytes_read > 1) {                     
            /* Discard eot character, but return the rest of the read data that should be valid. */    
            ret--;
        } else { 
            /* No data. */
            ret = -1;
        } 
    }   
}

/* Cancel thread */

HMODULE mod = LoadLibrary (L"Kernel32.dll");
BOOL WINAPI (*cancel_io_ex) (HANDLE, LPOVERLAPPED) = NULL;
if (mod != NULL) {
    cancel_io_ex = (BOOL WINAPI (*) (HANDLE, LPOVERLAPPED)) GetProcAddress (mod, "CancelIoEx");        
}
if (cancel_io_ex != NULL) {
    cancel_io_ex(stdout_write_pipe, NULL);
} else {
    SetEvent(stdout_closed_event);            
    WriteFile(stdout_write_pipe, &eot, 1, &written, NULL);
}

只需关闭管道,ReadFile将失败。@Hanpassant如果不关闭,请关闭句柄块。请改用CreateNamedPipe,然后可以使用重叠I/O。请参阅