我正在尝试在Windows stdout 句柄上获取句柄。
我需要了解为什么STDOUT有不同的句柄(CONOUT$
?)
以及如何解释这些差异。我知道有不同
Windows API使用的输出缓冲区,但是(从许多MSDN文档中)无法理解何时以及如何使用它们。
使用ctypes
和python3,我可以通过下面的脚本获得其中的2个。但是,在(Cygwin) mintty/bash
, PowerShell
(6.1.1),CMD
甚至{{1 }},结果都略有不同。
在薄荷中,所有标准输出手柄都是相同的,而在PowerShell中,它们是相同的 不同。发生了什么事?
问题:
为什么ConEmu
和_get_osfhandle
获得的stdout句柄不同?
这是我的代码:
GetStdHandle
以下是输出:
#!/usr/bin/env python3
#-*- coding: utf-8 -*-
#----------------------------------------------------------------------------
import sys
import ctypes
from ctypes import cdll, c_ulong
def color(text, color_code):
return '\x1b[%sm%s\x1b[0m' % (color_code, text)
def byellow(text): return color(text, '1;49;33')
def printHex(mode):
return byellow("0x%04x (%s)" % (mode, mode)) # DWORD
kFile = 'C:\\Windows\\System32\\kernel32.dll'
mFile = 'C:\\Windows\\System32\\msvcrt.dll'
print("\n Getting Console STDOUT handles using 2 different methods:")
try:
k32 = cdll.LoadLibrary(kFile)
msvcrt = cdll.LoadLibrary(mFile)
except OSError as e:
print("ERROR: %s" % e)
sys.exit(1)
try:
hmsvcrt_osf = msvcrt._get_osfhandle(sys.stdout.fileno()) # Get the parent (?) process Console Output buffer Handle
hk32_11 = k32.GetStdHandle(-11) # Get the current process Console Output buffer Handle
except Exception as e:
print("ERROR: %s" % e)
sys.exit(1)
print(" Got stdout handles using:\n")
print(" msvcrt._get_osfhandle : %s" % printHex(hmsvcrt_osf))
print(" k32.GetStdHandle(-11) : %s" % printHex(hk32_11))
根据MSDN:
检索与指定文件描述符关联的操作系统文件句柄。
检索指定标准设备(标准输入,标准输出或标准错误)的句柄。
相关问题:
附录:2018-12-14
在:# In PowerShell
# python3.6m.exe .\testHandles.py
Getting STDOUT handles using 2 different methods:
Got stdout handles using:
msvcrt._get_osfhandle : 0x001c (28)
k32.GetStdHandle(-11) : 0x014c (332)
# In Cygwin
# ./testHandles.py
Getting STDOUT handles using 2 different methods:
Got stdout handles using:
msvcrt._get_osfhandle : 0x0338 (824)
k32.GetStdHandle(-11) : 0x0338 (824)
# pwsh.exe -NoProfile -c "python3.6m.exe C:\test\testHandles.py"
Getting STDOUT handles using 2 different methods:
Got stdout handles using:
msvcrt._get_osfhandle : 0x0338 (824)
k32.GetStdHandle(-11) : 0x0144 (324)
:
/usr/lib/python3.6/ctypes/__init__.py
:此类的实例表示已加载的dll /共享 库,使用标准C调用导出函数 约定(在Windows上为“ cdecl”)。
导出的函数可以作为属性访问,也可以通过 使用函数名称进行索引。例子:
class CDLL(object)
->可调用对象
<obj>.qsort
->可调用对象调用函数会在调用期间释放Python GIL,然后 之后重新获取。
<obj>['qsort']
:此类代表Python库本身。它允许 访问Python API函数。 GIL未发布,并且 正确处理了Python异常。
然后class PyDLL(CDLL)
:
if _os.name == "nt"
:此类表示使用dll导出功能 Windows stdcall调用约定。
class WinDLL(CDLL)
:
stdcall [4]调用约定是Pascal调用的变体 约定,被叫方负责清理 堆栈,但参数从右到左被压入堆栈 顺序,如
stdcall
调用约定中所述。注册EAX,ECX和 EDX被指定在功能内使用。返回值是 存储在EAX寄存器中。
_cdecl
是Microsoft Win32的标准调用约定 API和Open Watcom C ++。