Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows上出现奇怪的Python错误,可在调试器下工作_Python_Windows_Ctypes - Fatal编程技术网

Windows上出现奇怪的Python错误,可在调试器下工作

Windows上出现奇怪的Python错误,可在调试器下工作,python,windows,ctypes,Python,Windows,Ctypes,以下代码意外引发异常:pywintypes.error:(6,“GetFileInformationByHandle”,“句柄无效”),即GetFileInformationByHandle不起作用 奇怪的是,在调试器下,一切都正常工作。更奇怪的是,当我删除某个参数或GetFileInformationByHandle时,错误就消失了。这告诉我可能是内存错误,但我在这里真的不知所措 有些代码可能看起来是不必要的,但我无法在不引起异常的情况下进一步缩减代码 我已经在Windows7、pywin32

以下代码意外引发异常:
pywintypes.error:(6,“GetFileInformationByHandle”,“句柄无效”)
,即
GetFileInformationByHandle
不起作用

奇怪的是,在调试器下,一切都正常工作。更奇怪的是,当我删除
某个参数
GetFileInformationByHandle
时,错误就消失了。这告诉我可能是内存错误,但我在这里真的不知所措

有些代码可能看起来是不必要的,但我无法在不引起异常的情况下进一步缩减代码

我已经在Windows7、pywin32 218.5和219上的Python3.4.1 x64上对此进行了测试

import os
import win32file
import pywintypes
from ctypes import *
from ctypes.wintypes import *


class BY_HANDLE_FILE_INFORMATION(Structure):
    _fields_ = [
        ('dwFileAttributes', DWORD),
        ('ftCreationTime', FILETIME),
        ('ftLastAccessTime', FILETIME),
        ('ftLastWriteTime', FILETIME),
        ('dwVolumeSerialNumber', DWORD),
        ('nFileSizeHigh', DWORD),
        ('nFileSizeLow', DWORD),
        ('nNumberOfLinks', DWORD),
        ('nFileIndexHigh', DWORD),
        ('nFileIndexLow', DWORD),
    ]


def GetFileInformationByHandle2(handle):
    GetFileInformationByHandle(handle)


def GetFileInformationByHandle(handle):
    bhfi = BY_HANDLE_FILE_INFORMATION()
    res = windll.kernelbase.GetFileInformationByHandle(handle.handle, byref(bhfi))
    if res == 0:
        errno = GetLastError()
        raise pywintypes.error(errno, 'GetFileInformationByHandle', FormatError(errno))


def open_file(path, param_1=False):
    return win32file.CreateFile(path, win32file.GENERIC_READ, 0, None, win32file.OPEN_EXISTING, 0, None)


def main():
    path = 'test.bin'
    open(path, 'wb').close()
    h_file = open_file(path)
    GetFileInformationByHandle(h_file)
    win32file.CloseHandle(h_file)
    h_file = open_file(path)
    GetFileInformationByHandle2(h_file)
    win32file.CloseHandle(h_file)
    os.remove(path)


if __name__ == '__main__':
    main()

在windbg的帮助下,我花了很多时间才找到原因

问题是
windell.kernelbase.GetFileInformationByHandle
的第一个句柄参数被作为
DWORD
而不是
QWORD
传递。奇怪的错误可能是由额外的代码修改了
rcx
的前4个字节引起的,这是x64调用约定中的第一个参数


我把这个答案留在这里供我自己参考,以防其他人认为这很有用。

您没有指出异常发生的位置(没有堆栈跟踪)。此外,这是再现问题所需的最低代码量吗?如果只对一个文件进行操作,并消除(似乎毫无意义的)
GetFileInformationByHandle2
wrapper函数,这种情况还会发生吗?是的,如果没有
GetFileInformationByHandle2
代码,这种情况就会发生。代码出现在
raise pywintypes.error
。无论是谁投了关闭和关闭的一票,这都是一个最小的例子。这段代码实际上并不长。其中大约1/3是导入和一个字典,您可以跳过它,直到需要理解它为止,不过有趣的是,这个示例包括
GetFileInformationByHandle2
,它只调用
GetFileInformationByHandle
。英雄联盟