如何从ctypes使用IFileOperation [英] How to use IFileOperation from ctypes
问题描述
我想使用 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
?
推荐答案
这个问题使我步入正轨,因为它表明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屋!