如何从 ctypes 使用 IFileOperation [英] How to use IFileOperation from ctypes

查看:32
本文介绍了如何从 ctypes 使用 IFileOperation的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to use IFileOperation to copy files from python code -

  • 速度快(比 python 快)
  • 你会得到一个很好的对话
  • 不会阻塞 Python

在 Windows 10 上,Python 3.8 -

On Windows 10, Python 3.8 -

import ctypes

ctypes.windll.shell32.IFileOperation

似乎不存在.

如何使用 ctypes 访问 IFileOperation(不是已弃用的 SHFileOperation API)?

How can I reach IFileOperation (Not the deprecated SHFileOperation API) using ctypes?

推荐答案

This 问题让我走上了正轨,因为它表明 COM 加载 Windows 功能实际上可以从 ctypes 获得,尽管它需要更多的工作.

This question put me on track, as it shows that COM loading Windows functionality is in fact avialable from ctypes, albeit it requires a bit more work.

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

The question uses comtypes.GUID as the only (non standard) dependency.

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

Looking at comtypes itself, it's pure python and uses ctypes (for CoCreateInstance and all else), and the paths to the windows functions needed to load and handle the COM object can be found, specifically -

import ctypes
ctypes.oledll.ole32.CoCreateInstance()

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

The CLSIDs need to be put explicitly, as in the referred question -

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

总而言之,comtypes 是一个小型的纯 Python 库,对于这项任务似乎已经足够了,如果不想修改 ctypes,请粘贴 GUID,否则不介意依赖.

All and all, comtypes, which is a small pure python library, seems quite enough for this task, if one doesn't want to tinker with ctypes, paste in GUID or else doesn't mind the dependency.

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

However, this is fully implementable in ctypes, as proven by comtypes itself, with the caveat of possibly having to add in GUID manually -

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 使用 IFileOperation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆