如何在Windows STDOUT句柄上获取句柄(在python中)?

时间:2018-12-14 08:32:17

标签: python-3.x windows winapi stdout msvcrt

我正在尝试在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:

  • _get_osfhandle

      

    检索与指定文件描述符关联的操作系统文件句柄。

  • GetStdHandle

      

    检索指定标准设备(标准输入,标准输出或标准错误)的句柄。

相关问题:


附录: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 ++。

0 个答案:

没有答案
相关问题