当前位置: 首页 > 面试题库 >

如何从ctypes使用IFileOperation

淳于嘉树
2023-03-14
问题内容

我想使用IFileOperation从python代码复制文件-

  • 它比python更快
  • 您会看到一个不错的对话框
  • 不阻止Python

在Windows 10上,Python 3.8-

import ctypes

ctypes.windll.shell32.IFileOperation

似乎不存在。

如何使用来联系IFileOperation(不是不​​推荐使用的SHFileOperationAPI)ctypes


问题答案:

该问题使用comtypes.GUID作为唯一(非标准)依赖项。

看一下comtypes本身,它是纯python并使用ctypes(用于CoCreateInstance和所有其他类型),并且可以找到加载和处理COM对象所需的windows函数的路径,特别是-

import ctypes
ctypes.oledll.ole32.CoCreateInstance()

需要明确地放置CLSID,如所提到的问题-

IID_IFileOperation  = '{947AAB5F-0A5C-4C13-B4D6-4BF7836FC9F8}'
CLSID_FileOperation = '{3AD05575-8857-4850-9277-11B85BDB8E09}'

总而言之,comtypes是一个小的纯python库,似乎足以完成此任务,如果您不想修改ctypes,粘贴GUID或不介意依赖项。

但是,正如comtypes本身所证明的那样,这在ctypes中是完全可实现的,但有可能需要手动添加GUID的警告-

from ctypes import *

BYTE, WORD, DWORD = c_byte, c_ushort, c_ulong

_StringFromCLSID = oledll.ole32.StringFromCLSID
_ProgIDFromCLSID = oledll.ole32.ProgIDFromCLSID
_CLSIDFromString = oledll.ole32.CLSIDFromString
_CLSIDFromProgID = oledll.ole32.CLSIDFromProgID
_CoCreateGuid    = oledll.ole32.CoCreateGuid

_CoTaskMemFree   = windll.ole32.CoTaskMemFree

class GUID(Structure):
    _fields_ = [("Data1", DWORD),
                ("Data2", WORD),
                ("Data3", WORD),
                ("Data4", BYTE * 8)]

    def __init__(self, name=None):
        if name is not None:
            _CLSIDFromString(unicode(name), byref(self))

    def __repr__(self):
        return u'GUID("%s")' % unicode(self)

    def __unicode__(self):
        p = c_wchar_p()
        _StringFromCLSID(byref(self), byref(p))
        result = p.value
        _CoTaskMemFree(p)
        return result
    __str__ = __unicode__

    def __cmp__(self, other):
        if isinstance(other, GUID):
            return cmp(bytes(self), bytes(other))
        return -1

    def __nonzero__(self):
        return self != GUID_null

    def __eq__(self, other):
        return isinstance(other, GUID) and \
               bytes(self) == bytes(other)

    def __hash__(self):
        # We make GUID instances hashable, although they are mutable.
        return hash(bytes(self))

    def copy(self):
        return GUID(unicode(self))

    def from_progid(cls, progid):
        """Get guid from progid, ...
        """
        if hasattr(progid, "_reg_clsid_"):
            progid = progid._reg_clsid_
        if isinstance(progid, cls):
            return progid
        elif isinstance(progid, basestring):
            if progid.startswith("{"):
                return cls(progid)
            inst = cls()
            _CLSIDFromProgID(unicode(progid), byref(inst))
            return inst
        else:
            raise TypeError("Cannot construct guid from %r" % progid)
    from_progid = classmethod(from_progid)

    def as_progid(self):
        "Convert a GUID into a progid"
        progid = c_wchar_p()
        _ProgIDFromCLSID(byref(self), byref(progid))
        result = progid.value
        _CoTaskMemFree(progid)
        return result

    def create_new(cls):
        "Create a brand new guid"
        guid = cls()
        _CoCreateGuid(byref(guid))
        return guid
    create_new = classmethod(create_new)


 类似资料:
  • 问题内容: 我正在使用ctypes在Python中加载DLL。这很好。 现在,我们希望能够在运行时重新加载该DLL。 直接的方法似乎是:1.卸载DLL 2.加载DLL 不幸的是,我不确定卸载DLL的正确方法是什么。 _ctypes.FreeLibrary可用,但私有。 还有其他卸载DLL的方法吗? 问题答案: 您应该能够通过放置对象来做到这一点 编辑: 霍普的评论是正确的,这取消了名称的绑定,但是

  • 问题内容: 我正在使用ctypes在Python中实现C 函数。C 函数应返回一个指向数组的指针。不幸的是,我还没有弄清楚如何在Python中访问数组。我尝试了numpy.frombuffer,但是没有成功。它只是返回一个任意数字的数组。显然我没有正确使用它。这是一个简单的示例,数组大小为10: function.cpp的内容: wrapper.py的内容: 要编译我正在使用的C ++文件: 您对

  • 问题内容: 我想在python ctypes中复制以下c代码: 我可以弄清楚如何以函数指针的形式调用此内存位置,而不仅仅是正常的取消引用: 由于存在段错误,指令指针指向该存储位置,因此它已成功调用它。但是我不能只读取内存位置: 问题答案: 。

  • 问题内容: 这可能是一个愚蠢的问题,但我在文档或任何地方都找不到好的答案。 如果我使用 struct 定义二进制结构,则该结构具有2种对称的序列化和反序列化方法(打包和解包),但是 ctypes 似乎没有直接的方法。这是我的解决方案,感觉不对: 问题答案: PythonInfo Wiki为此提供了解决方案。 常见问题解答:如何从ctypes.Structure复制字节到Python? 常见问题解答

  • 问题内容: 我有一个通过ctypes访问的结构: 到目前为止,我有类似以下的Python代码: 但是我不确定该用什么枚举。我应该将其映射到a还是? 问题答案: 至少对于GCC来说,只是一个简单的数字类型。它可以是8位,16位,32位,64位或其他任何值(我已经用64位值对其进行了测试)以及或。我猜它不能超过,但是实际上你应该检查你的范围并选择类似。 这是一个例子。C程序: 和Python之一:

  • 问题内容: 我想使用ctypes在库中映射一个声明为全局值的int值。 目前,我可以像这样加载库: 并成功映射了许多功能。但是,出于错误检查的目的,其中许多设置了变量,因此我也需要访问该变量。但是,如果我尝试访问它,则会得到: 当然,它不是函数指针,尝试调用它会导致段错误。 在主头文件和API头文件中声明为。 Objdump将符号显示为: 问题答案: ctypes文档中有一节关于访问dll中导出的