使用 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_fd
和 write_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 是由您链接的来源完成的。
我正在尝试制作一个 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_fd
和 write_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 是由您链接的来源完成的。