我正在考虑在终端中使用 python 制作进度条。首先,我必须获取终端窗口的宽度(列)。在 python 2.7 中,没有标准库可以在 Windows 上执行此操作。我知道也许我必须手动调用 Windows 控制台 API。
根据 MSDN 和 Python 文档,我编写了以下代码:
import ctypes
import ctypes.wintypes
class CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
_fields_ = [
('dwSize', ctypes.wintypes._COORD),
('dwCursorPosition', ctypes.wintypes._COORD),
('wAttributes', ctypes.c_ushort),
('srWindow', ctypes.wintypes._SMALL_RECT),
('dwMaximumWindowSize', ctypes.wintypes._COORD)
]
hstd = ctypes.windll.kernel32.GetStdHandle(ctypes.c_ulong(-11)) # STD_OUTPUT_HANDLE = -11
print hstd
csbi = CONSOLE_SCREEN_BUFFER_INFO()
print ctypes.sizeof(csbi) # <---------------
ret = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(ctypes.c_ulong(hstd), csbi)
print ret
print csbi.dwSize.X
它工作正常。我开始删除一些print
代码。但是之后就不行了!GetLastError
返回 6(无效句柄)。经过多次尝试,我发现代码的指向位置一定有一些东西,例如print 'hello'
,import sys
或sys.stdout.flush()
。起初,我想可能需要时间做点什么。所以我试图把它放在time.sleep(2)
那个位置,但它仍然不起作用。
但是,如果我确实使用struct
而不是ctypes.Structure
,就没有这样的问题。
import ctypes
import struct
hstd = ctypes.windll.kernel32.GetStdHandle(-11) # STD_OUTPUT_HANDLE = -11
csbi = ctypes.create_string_buffer(22)
res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(hstd, csbi)
width, height, curx, cury, wattr, left, top, right, bottom, maxx, maxy = struct.unpack("hhhhHhhhhhh", csbi.raw)
print bufx
有没有人可以告诉我为什么不相关的代码会产生如此大的差异?