You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.7 KiB
106 lines
3.7 KiB
import sys
|
|
from ctypes import *
|
|
from comtypes import IUnknown, HRESULT, COMMETHOD, GUID, BSTR
|
|
from comtypes.hresult import *
|
|
|
|
LPCOLESTR = c_wchar_p
|
|
DWORD = c_ulong
|
|
|
|
class ICreateErrorInfo(IUnknown):
|
|
_iid_ = GUID("{22F03340-547D-101B-8E65-08002B2BD119}")
|
|
_methods_ = [
|
|
COMMETHOD([], HRESULT, 'SetGUID',
|
|
(['in'], POINTER(GUID), "rguid")),
|
|
COMMETHOD([], HRESULT, 'SetSource',
|
|
(['in'], LPCOLESTR, "szSource")),
|
|
COMMETHOD([], HRESULT, 'SetDescription',
|
|
(['in'], LPCOLESTR, "szDescription")),
|
|
COMMETHOD([], HRESULT, 'SetHelpFile',
|
|
(['in'], LPCOLESTR, "szHelpFile")),
|
|
COMMETHOD([], HRESULT, 'SetHelpContext',
|
|
(['in'], DWORD, "dwHelpContext"))
|
|
]
|
|
|
|
class IErrorInfo(IUnknown):
|
|
_iid_ = GUID("{1CF2B120-547D-101B-8E65-08002B2BD119}")
|
|
_methods_ = [
|
|
COMMETHOD([], HRESULT, 'GetGUID',
|
|
(['out'], POINTER(GUID), "pGUID")),
|
|
COMMETHOD([], HRESULT, 'GetSource',
|
|
(['out'], POINTER(BSTR), "pBstrSource")),
|
|
COMMETHOD([], HRESULT, 'GetDescription',
|
|
(['out'], POINTER(BSTR), "pBstrDescription")),
|
|
COMMETHOD([], HRESULT, 'GetHelpFile',
|
|
(['out'], POINTER(BSTR), "pBstrHelpFile")),
|
|
COMMETHOD([], HRESULT, 'GetHelpContext',
|
|
(['out'], POINTER(DWORD), "pdwHelpContext")),
|
|
]
|
|
|
|
class ISupportErrorInfo(IUnknown):
|
|
_iid_ = GUID("{DF0B3D60-548F-101B-8E65-08002B2BD119}")
|
|
_methods_ = [
|
|
COMMETHOD([], HRESULT, 'InterfaceSupportsErrorInfo',
|
|
(['in'], POINTER(GUID), 'riid'))
|
|
]
|
|
|
|
################################################################
|
|
_oleaut32 = oledll.oleaut32
|
|
|
|
def CreateErrorInfo():
|
|
cei = POINTER(ICreateErrorInfo)()
|
|
_oleaut32.CreateErrorInfo(byref(cei))
|
|
return cei
|
|
|
|
def GetErrorInfo():
|
|
"""Get the error information for the current thread."""
|
|
errinfo = POINTER(IErrorInfo)()
|
|
if S_OK == _oleaut32.GetErrorInfo(0, byref(errinfo)):
|
|
return errinfo
|
|
return None
|
|
|
|
def SetErrorInfo(errinfo):
|
|
"""Set error information for the current thread."""
|
|
return _oleaut32.SetErrorInfo(0, errinfo)
|
|
|
|
def ReportError(text, iid,
|
|
clsid=None, helpfile=None, helpcontext=0, hresult=DISP_E_EXCEPTION):
|
|
"""Report a COM error. Returns the passed in hresult value."""
|
|
ei = CreateErrorInfo()
|
|
ei.SetDescription(text)
|
|
ei.SetGUID(iid)
|
|
if helpfile is not None:
|
|
ei.SetHelpFile(helpfile)
|
|
if helpcontext is not None:
|
|
ei.SetHelpContext(helpcontext)
|
|
if clsid is not None:
|
|
if isinstance(clsid, str):
|
|
clsid = GUID(clsid)
|
|
try:
|
|
progid = clsid.as_progid()
|
|
except WindowsError:
|
|
pass
|
|
else:
|
|
ei.SetSource(progid) # progid for the class or application that created the error
|
|
_oleaut32.SetErrorInfo(0, ei)
|
|
return hresult
|
|
|
|
def ReportException(hresult, iid, clsid=None, helpfile=None, helpcontext=None,
|
|
stacklevel=None):
|
|
"""Report a COM exception. Returns the passed in hresult value."""
|
|
typ, value, tb = sys.exc_info()
|
|
if stacklevel is not None:
|
|
for _ in range(stacklevel):
|
|
tb = tb.tb_next
|
|
line = tb.tb_frame.f_lineno
|
|
name = tb.tb_frame.f_globals["__name__"]
|
|
text = "%s: %s (%s, line %d)" % (typ, value, name, line)
|
|
else:
|
|
text = "%s: %s" % (typ, value)
|
|
return ReportError(text, iid,
|
|
clsid=clsid, helpfile=helpfile, helpcontext=helpcontext,
|
|
hresult=hresult)
|
|
|
|
__all__ = ["ICreateErrorInfo", "IErrorInfo", "ISupportErrorInfo",
|
|
"ReportError", "ReportException",
|
|
"SetErrorInfo", "GetErrorInfo", "CreateErrorInfo"]
|