def handle_com_error (err=None):
"""Convenience wrapper for displaying all manner of COM errors.
Raises a :exc:`x_wmi` exception with more useful information attached
:param err: The structure attached to a `pywintypes.com_error`
"""
if err is None:
_, err, _ = sys.exc_info ()
hresult_code, hresult_name, additional_info, parameter_in_error = err.args
hresult_code = signed_to_unsigned (hresult_code)
exception_string = ["%s - %s" % (hex (hresult_code), hresult_name)]
scode = None
if additional_info:
wcode, source_of_error, error_description, whlp_file, whlp_context, scode = additional_info
scode = signed_to_unsigned (scode)
exception_string.append (" Error in: %s" % source_of_error)
exception_string.append (" %s - %s" % (hex (scode), (error_description or "").strip ()))
for error_code, klass in WMI_EXCEPTIONS.items ():
if error_code in (hresult_code, scode):
break
else:
klass = x_wmi
raise klass (com_error=err)
python类com_error()的实例源码
def set (self, **kwargs):
"""Set several properties of the underlying object
at one go. This is particularly useful in combination
with the new () method below. However, an instance
which has been spawned in this way won't have enough
information to write pack, so only try if the
instance has a path.
"""
if kwargs:
try:
for attribute, value in kwargs.items ():
if attribute in self.properties:
self._cached_properties (attribute).set (value)
else:
raise AttributeError (attribute)
#
# Only try to write the attributes
# back if the object exists.
#
if self.ole_object.Path_.Path:
self.ole_object.Put_ ()
except pywintypes.com_error:
handle_com_error ()
def _cached_associated_classes (self):
if self._associated_classes is None:
if isinstance (self, _wmi_class):
params = {'bSchemaOnly' : True}
else:
params = {'bClassesOnly' : True}
try:
associated_classes = dict (
(assoc.Path_.Class, _wmi_class (self._namespace, assoc)) for
assoc in self.ole_object.Associators_ (**params)
)
_set (self, "_associated_classes", associated_classes)
except pywintypes.com_error:
handle_com_error ()
return self._associated_classes
def __call__ (self, timeout_ms=-1):
"""When called, return the instance which caused the event. Supports
timeout in milliseconds (defaulting to infinite). If the watcher
times out, :exc:`x_wmi_timed_out` is raised. This makes it easy to support
watching for multiple objects.
"""
try:
event = self.wmi_event.NextEvent (timeout_ms)
if self.is_extrinsic:
return _wmi_event (event, None, self.fields)
else:
return _wmi_event (
event.Properties_ ("TargetInstance").Value,
_wmi_object (event, property_map=self._event_property_map),
self.fields
)
except pywintypes.com_error:
handle_com_error ()
def check_is_admin():
global _is_admin
if _is_admin is None:
from win32com.shell.shell import IsUserAnAdmin
import pythoncom
try:
_is_admin = IsUserAnAdmin()
except pythoncom.com_error, exc:
if exc.hresult != winerror.E_NOTIMPL:
raise
# not impl on this platform - must be old - assume is admin
_is_admin = True
return _is_admin
# If this exception is raised by a test, the test is reported as a 'skip'
def GetModuleForProgID(progid):
"""Get a Python module for a Program ID
Given a Program ID, return a Python module which contains the
class which wraps the COM object.
Returns the Python module, or None if no module is available.
Params
progid -- A COM ProgramID or IID (eg, "Word.Application")
"""
try:
iid = pywintypes.IID(progid)
except pywintypes.com_error:
return None
return GetModuleForCLSID(iid)
def MakeModuleForTypelib(typelibCLSID, lcid, major, minor, progressInstance = None, bGUIProgress = None, bForDemand = bForDemandDefault, bBuildHidden = 1):
"""Generate support for a type library.
Given the IID, LCID and version information for a type library, generate
and import the necessary support files.
Returns the Python module. No exceptions are caught.
Params
typelibCLSID -- IID of the type library.
major -- Integer major version.
minor -- Integer minor version.
lcid -- Integer LCID for the library.
progressInstance -- Instance to use as progress indicator, or None to
use the GUI progress bar.
"""
if bGUIProgress is not None:
print "The 'bGuiProgress' param to 'MakeModuleForTypelib' is obsolete."
import makepy
try:
makepy.GenerateFromTypeLibSpec( (typelibCLSID, lcid, major, minor), progressInstance=progressInstance, bForDemand = bForDemand, bBuildHidden = bBuildHidden)
except pywintypes.com_error:
return None
return GetModuleForTypelib(typelibCLSID, lcid, major, minor)
def MakeModuleForTypelibInterface(typelib_ob, progressInstance = None, bForDemand = bForDemandDefault, bBuildHidden = 1):
"""Generate support for a type library.
Given a PyITypeLib interface generate and import the necessary support files. This is useful
for getting makepy support for a typelibrary that is not registered - the caller can locate
and load the type library itself, rather than relying on COM to find it.
Returns the Python module.
Params
typelib_ob -- The type library itself
progressInstance -- Instance to use as progress indicator, or None to
use the GUI progress bar.
"""
import makepy
try:
makepy.GenerateFromTypeLibSpec( typelib_ob, progressInstance=progressInstance, bForDemand = bForDemandDefault, bBuildHidden = bBuildHidden)
except pywintypes.com_error:
return None
tla = typelib_ob.GetLibAttr()
guid = tla[0]
lcid = tla[1]
major = tla[3]
minor = tla[4]
return GetModuleForTypelib(guid, lcid, major, minor)
def EnsureDispatch(prog_id, bForDemand = 1): # New fn, so we default the new demand feature to on!
"""Given a COM prog_id, return an object that is using makepy support, building if necessary"""
disp = win32com.client.Dispatch(prog_id)
if not disp.__dict__.get("CLSID"): # Eeek - no makepy support - try and build it.
try:
ti = disp._oleobj_.GetTypeInfo()
disp_clsid = ti.GetTypeAttr()[0]
tlb, index = ti.GetContainingTypeLib()
tla = tlb.GetLibAttr()
mod = EnsureModule(tla[0], tla[1], tla[3], tla[4], bForDemand=bForDemand)
GetModuleForCLSID(disp_clsid)
# Get the class from the module.
import CLSIDToClass
disp_class = CLSIDToClass.GetClass(str(disp_clsid))
disp = disp_class(disp._oleobj_)
except pythoncom.com_error:
raise TypeError("This COM object can not automate the makepy process - please run makepy manually for this object")
return disp
def GetModuleForProgID(progid):
"""Get a Python module for a Program ID
Given a Program ID, return a Python module which contains the
class which wraps the COM object.
Returns the Python module, or None if no module is available.
Params
progid -- A COM ProgramID or IID (eg, "Word.Application")
"""
try:
iid = pywintypes.IID(progid)
except pywintypes.com_error:
return None
return GetModuleForCLSID(iid)
def MakeModuleForTypelib(typelibCLSID, lcid, major, minor, progressInstance = None, bGUIProgress = None, bForDemand = bForDemandDefault, bBuildHidden = 1):
"""Generate support for a type library.
Given the IID, LCID and version information for a type library, generate
and import the necessary support files.
Returns the Python module. No exceptions are caught.
Params
typelibCLSID -- IID of the type library.
major -- Integer major version.
minor -- Integer minor version.
lcid -- Integer LCID for the library.
progressInstance -- Instance to use as progress indicator, or None to
use the GUI progress bar.
"""
if bGUIProgress is not None:
print "The 'bGuiProgress' param to 'MakeModuleForTypelib' is obsolete."
import makepy
try:
makepy.GenerateFromTypeLibSpec( (typelibCLSID, lcid, major, minor), progressInstance=progressInstance, bForDemand = bForDemand, bBuildHidden = bBuildHidden)
except pywintypes.com_error:
return None
return GetModuleForTypelib(typelibCLSID, lcid, major, minor)
def MakeModuleForTypelibInterface(typelib_ob, progressInstance = None, bForDemand = bForDemandDefault, bBuildHidden = 1):
"""Generate support for a type library.
Given a PyITypeLib interface generate and import the necessary support files. This is useful
for getting makepy support for a typelibrary that is not registered - the caller can locate
and load the type library itself, rather than relying on COM to find it.
Returns the Python module.
Params
typelib_ob -- The type library itself
progressInstance -- Instance to use as progress indicator, or None to
use the GUI progress bar.
"""
import makepy
try:
makepy.GenerateFromTypeLibSpec( typelib_ob, progressInstance=progressInstance, bForDemand = bForDemandDefault, bBuildHidden = bBuildHidden)
except pywintypes.com_error:
return None
tla = typelib_ob.GetLibAttr()
guid = tla[0]
lcid = tla[1]
major = tla[3]
minor = tla[4]
return GetModuleForTypelib(guid, lcid, major, minor)
def EnsureDispatch(prog_id, bForDemand = 1): # New fn, so we default the new demand feature to on!
"""Given a COM prog_id, return an object that is using makepy support, building if necessary"""
disp = win32com.client.Dispatch(prog_id)
if not disp.__dict__.get("CLSID"): # Eeek - no makepy support - try and build it.
try:
ti = disp._oleobj_.GetTypeInfo()
disp_clsid = ti.GetTypeAttr()[0]
tlb, index = ti.GetContainingTypeLib()
tla = tlb.GetLibAttr()
mod = EnsureModule(tla[0], tla[1], tla[3], tla[4], bForDemand=bForDemand)
GetModuleForCLSID(disp_clsid)
# Get the class from the module.
import CLSIDToClass
disp_class = CLSIDToClass.GetClass(str(disp_clsid))
disp = disp_class(disp._oleobj_)
except pythoncom.com_error:
raise TypeError("This COM object can not automate the makepy process - please run makepy manually for this object")
return disp
def check_is_admin():
global _is_admin
if _is_admin is None:
from win32com.shell.shell import IsUserAnAdmin
import pythoncom
try:
_is_admin = IsUserAnAdmin()
except pythoncom.com_error, exc:
if exc.hresult != winerror.E_NOTIMPL:
raise
# not impl on this platform - must be old - assume is admin
_is_admin = True
return _is_admin
# If this exception is raised by a test, the test is reported as a 'skip'
def GetModuleForProgID(progid):
"""Get a Python module for a Program ID
Given a Program ID, return a Python module which contains the
class which wraps the COM object.
Returns the Python module, or None if no module is available.
Params
progid -- A COM ProgramID or IID (eg, "Word.Application")
"""
try:
iid = pywintypes.IID(progid)
except pywintypes.com_error:
return None
return GetModuleForCLSID(iid)
def MakeModuleForTypelib(typelibCLSID, lcid, major, minor, progressInstance = None, bGUIProgress = None, bForDemand = bForDemandDefault, bBuildHidden = 1):
"""Generate support for a type library.
Given the IID, LCID and version information for a type library, generate
and import the necessary support files.
Returns the Python module. No exceptions are caught.
Params
typelibCLSID -- IID of the type library.
major -- Integer major version.
minor -- Integer minor version.
lcid -- Integer LCID for the library.
progressInstance -- Instance to use as progress indicator, or None to
use the GUI progress bar.
"""
if bGUIProgress is not None:
print "The 'bGuiProgress' param to 'MakeModuleForTypelib' is obsolete."
import makepy
try:
makepy.GenerateFromTypeLibSpec( (typelibCLSID, lcid, major, minor), progressInstance=progressInstance, bForDemand = bForDemand, bBuildHidden = bBuildHidden)
except pywintypes.com_error:
return None
return GetModuleForTypelib(typelibCLSID, lcid, major, minor)
def MakeModuleForTypelibInterface(typelib_ob, progressInstance = None, bForDemand = bForDemandDefault, bBuildHidden = 1):
"""Generate support for a type library.
Given a PyITypeLib interface generate and import the necessary support files. This is useful
for getting makepy support for a typelibrary that is not registered - the caller can locate
and load the type library itself, rather than relying on COM to find it.
Returns the Python module.
Params
typelib_ob -- The type library itself
progressInstance -- Instance to use as progress indicator, or None to
use the GUI progress bar.
"""
import makepy
try:
makepy.GenerateFromTypeLibSpec( typelib_ob, progressInstance=progressInstance, bForDemand = bForDemandDefault, bBuildHidden = bBuildHidden)
except pywintypes.com_error:
return None
tla = typelib_ob.GetLibAttr()
guid = tla[0]
lcid = tla[1]
major = tla[3]
minor = tla[4]
return GetModuleForTypelib(guid, lcid, major, minor)
def EnsureDispatch(prog_id, bForDemand = 1): # New fn, so we default the new demand feature to on!
"""Given a COM prog_id, return an object that is using makepy support, building if necessary"""
disp = win32com.client.Dispatch(prog_id)
if not disp.__dict__.get("CLSID"): # Eeek - no makepy support - try and build it.
try:
ti = disp._oleobj_.GetTypeInfo()
disp_clsid = ti.GetTypeAttr()[0]
tlb, index = ti.GetContainingTypeLib()
tla = tlb.GetLibAttr()
mod = EnsureModule(tla[0], tla[1], tla[3], tla[4], bForDemand=bForDemand)
GetModuleForCLSID(disp_clsid)
# Get the class from the module.
import CLSIDToClass
disp_class = CLSIDToClass.GetClass(str(disp_clsid))
disp = disp_class(disp._oleobj_)
except pythoncom.com_error:
raise TypeError("This COM object can not automate the makepy process - please run makepy manually for this object")
return disp
def check_is_admin():
global _is_admin
if _is_admin is None:
from win32com.shell.shell import IsUserAnAdmin
import pythoncom
try:
_is_admin = IsUserAnAdmin()
except pythoncom.com_error as exc:
if exc.hresult != winerror.E_NOTIMPL:
raise
# not impl on this platform - must be old - assume is admin
_is_admin = True
return _is_admin
# If this exception is raised by a test, the test is reported as a 'skip'
def GetModuleForProgID(progid):
"""Get a Python module for a Program ID
Given a Program ID, return a Python module which contains the
class which wraps the COM object.
Returns the Python module, or None if no module is available.
Params
progid -- A COM ProgramID or IID (eg, "Word.Application")
"""
try:
iid = pywintypes.IID(progid)
except pywintypes.com_error:
return None
return GetModuleForCLSID(iid)
def MakeModuleForTypelib(typelibCLSID, lcid, major, minor, progressInstance = None, bGUIProgress = None, bForDemand = bForDemandDefault, bBuildHidden = 1):
"""Generate support for a type library.
Given the IID, LCID and version information for a type library, generate
and import the necessary support files.
Returns the Python module. No exceptions are caught.
Params
typelibCLSID -- IID of the type library.
major -- Integer major version.
minor -- Integer minor version.
lcid -- Integer LCID for the library.
progressInstance -- Instance to use as progress indicator, or None to
use the GUI progress bar.
"""
if bGUIProgress is not None:
print("The 'bGuiProgress' param to 'MakeModuleForTypelib' is obsolete.")
from . import makepy
try:
makepy.GenerateFromTypeLibSpec( (typelibCLSID, lcid, major, minor), progressInstance=progressInstance, bForDemand = bForDemand, bBuildHidden = bBuildHidden)
except pywintypes.com_error:
return None
return GetModuleForTypelib(typelibCLSID, lcid, major, minor)
def MakeModuleForTypelibInterface(typelib_ob, progressInstance = None, bForDemand = bForDemandDefault, bBuildHidden = 1):
"""Generate support for a type library.
Given a PyITypeLib interface generate and import the necessary support files. This is useful
for getting makepy support for a typelibrary that is not registered - the caller can locate
and load the type library itself, rather than relying on COM to find it.
Returns the Python module.
Params
typelib_ob -- The type library itself
progressInstance -- Instance to use as progress indicator, or None to
use the GUI progress bar.
"""
from . import makepy
try:
makepy.GenerateFromTypeLibSpec( typelib_ob, progressInstance=progressInstance, bForDemand = bForDemandDefault, bBuildHidden = bBuildHidden)
except pywintypes.com_error:
return None
tla = typelib_ob.GetLibAttr()
guid = tla[0]
lcid = tla[1]
major = tla[3]
minor = tla[4]
return GetModuleForTypelib(guid, lcid, major, minor)
def EnsureDispatch(prog_id, bForDemand = 1): # New fn, so we default the new demand feature to on!
"""Given a COM prog_id, return an object that is using makepy support, building if necessary"""
disp = win32com.client.Dispatch(prog_id)
if not disp.__dict__.get("CLSID"): # Eeek - no makepy support - try and build it.
try:
ti = disp._oleobj_.GetTypeInfo()
disp_clsid = ti.GetTypeAttr()[0]
tlb, index = ti.GetContainingTypeLib()
tla = tlb.GetLibAttr()
mod = EnsureModule(tla[0], tla[1], tla[3], tla[4], bForDemand=bForDemand)
GetModuleForCLSID(disp_clsid)
# Get the class from the module.
from . import CLSIDToClass
disp_class = CLSIDToClass.GetClass(str(disp_clsid))
disp = disp_class(disp._oleobj_)
except pythoncom.com_error:
raise TypeError("This COM object can not automate the makepy process - please run makepy manually for this object")
return disp
def link_bug(qcc, testinstance, bug):
"""
link a Bug to a TsTestInstance
returns True if successful, False if not
"""
bug_filter = qcc.BugFactory.Filter
bug_filter.Clear()
bug_filter['BG_BUG_ID'] = bug
bug_list = bug_filter.NewList()
if len(bug_list) == 0:
LOG.error('no bugs found')
return False
bug = bug_list(1)
link_factory = testinstance.BugLinkFactory
try:
link = link_factory.AddItem(bug)
link.LinkType = 'Related'
link.Post()
except pywintypes.com_error as ex:
LOG.exception(ex)
return True
def __init__ (self, info="", com_error=None):
self.info = info
self.com_error = com_error
def __str__ (self):
return "<x_wmi: %s %s>" % (
self.info or "Unexpected COM Error",
self.com_error or "(no underlying exception)"
)
def __init__ (self, ole_object, method_name):
"""
:param ole_object: The WMI class/instance whose method is to be called
:param method_name: The name of the method to be called
"""
try:
self.ole_object = Dispatch (ole_object)
self.method = ole_object.Methods_ (method_name)
self.qualifiers = {}
for q in self.method.Qualifiers_:
self.qualifiers[q.Name] = q.Value
self.provenance = "\n".join (self.qualifiers.get ("MappingStrings", []))
self.in_parameters = self.method.InParameters
self.out_parameters = self.method.OutParameters
if self.in_parameters is None:
self.in_parameter_names = []
else:
self.in_parameter_names = [(i.Name, i.IsArray) for i in self.in_parameters.Properties_]
if self.out_parameters is None:
self.out_parameter_names = []
else:
self.out_parameter_names = [(i.Name, i.IsArray) for i in self.out_parameters.Properties_]
doc = "%s (%s) => (%s)" % (
method_name,
", ".join ([name + ("", "[]")[is_array] for (name, is_array) in self.in_parameter_names]),
", ".join ([name + ("", "[]")[is_array] for (name, is_array) in self.out_parameter_names])
)
privileges = self.qualifiers.get ("Privileges", [])
if privileges:
doc += " | Needs: " + ", ".join (privileges)
self.__doc__ = doc
except pywintypes.com_error:
handle_com_error ()
def __str__ (self):
"""For a call to print [object] return the OLE description
of the properties / values of the object
"""
try:
return self.ole_object.GetObjectText_ ()
except pywintypes.com_error:
handle_com_error ()
def __repr__ (self):
"""
Indicate both the fact that this is a wrapped WMI object
and the WMI object's own identifying class.
"""
try:
return "<%s: %s>" % (self.__class__.__name__, self.Path_.Path.encode ("ascii", "backslashreplace"))
except pywintypes.com_error:
handle_com_error ()
def __getattr__ (self, attribute):
"""
Attempt to pass attribute calls to the proxied COM object.
If the attribute is recognised as a property, return its value;
if it is recognised as a method, return a method wrapper which
can then be called with parameters; otherwise pass the lookup
on to the underlying object.
"""
try:
if attribute in self.properties:
property = self._cached_properties (attribute)
factory = self.property_map.get (attribute, self.property_map.get (property.type, lambda x: x))
value = factory (property.value)
#
# If this is an association, certain of its properties
# are actually the paths to the aspects of the association,
# so translate them automatically into WMI objects.
#
if property.type.startswith ("ref:"):
return WMI (moniker=value)
else:
return value
elif attribute in self.methods:
return self._cached_methods (attribute)
else:
return getattr (self.ole_object, attribute)
except pywintypes.com_error:
handle_com_error ()