使用 CreatePseudoConsole 在 python 中创建 pty 管道时出现问题

Problem with using CreatePseudoConsole to create a pty pipe in python

我正在尝试制作一个 pty 管道。为此,我必须使用 Windows api 中的 CreatePseudoConsole 函数。我正在松散地复制 this which is this 但在 python.

我不知道它是否相关,但我正在使用 Python 3.7.9 和 Windows 10。

这是我的代码:

from ctypes.wintypes import DWORD, HANDLE, SHORT
from ctypes import POINTER, POINTER, HRESULT
import ctypes
import msvcrt
import os


# The COORD data type used for the size of the console
class COORD(ctypes.Structure):
    _fields_ = [("X", SHORT),
                ("Y", SHORT)]


# HPCON is the same as HANDLE
HPCON = HANDLE


CreatePseudoConsole = ctypes.windll.kernel32.CreatePseudoConsole
CreatePseudoConsole.argtypes = [COORD, HANDLE, HANDLE, DWORD, POINTER(HPCON)]
CreatePseudoConsole.restype = HRESULT


def create_console(width:int, height:int) -> HPCON:
    read_pty_fd, write_fd = os.pipe()
    read_pty_handle = msvcrt.get_osfhandle(read_pty_fd)

    read_fd, write_pty_fd = os.pipe()
    write_pty_handle = msvcrt.get_osfhandle(write_pty_fd)

    # Create the console
    size = COORD(width, height)
    console = HPCON()

    result = CreatePseudoConsole(size, read_pty_handle, write_pty_handle,
                                 DWORD(0), ctypes.byref(console))
    # Check if any errors occured
    if result != 0:
        raise ctypes.WinError(result)

    # Add references for the fds to the console
    console.read_fd = read_fd
    console.write_fd = write_fd

    # Return the console object
    return console


if __name__ == "__main__":
    consol = create_console(80, 80)
    print("Writing...")
    os.write(consol.write_fd, b"abc")
    print("Reading...")
    print(os.read(consol.read_fd, 1))
    print("Done")

问题是它无法从管道中读取。我希望它打印 "a" 但它只是卡在 os.read 上。请注意,这是我第一次使用 WinAPI,所以问题很可能就在那里。

代码没有错:你错的是你的期望。

你正在做的是写入管道以将“键盘”输入提供给程序,并从另一个管道读取return程序的“屏幕”输出。但是在任何一个管道的另一端都没有实际的程序,所以 read 调用什么也做不到 return.

CreatePseudoConsole API 编辑的 HPCON 句柄 return 应该通过 [=12] 在线程属性列表中传递给新生成的进程=].除此之外几乎没有什么可以用它做的。 (您甚至不能像在 Unix 上那样将自己连接到伪控制台。)以这种方式传递句柄后,您可以使用 read_fdwrite_fd 描述符与进程通信。

article on MSDN provides a full sample in C that creates a pseudoconsole and passes it to a new process; the exact same thing 是由您链接的来源完成的。