M
Mikko Ohtamaa
Hi,
I am quite new to Python, PythonCom and COM generally. As a former
Java programmer, I have found Python's flexible ability to access
native Win32, especially COM, very comfortable. However, there is
quite little on-line documentation and examples available about
PythonCOM. The only good sources I have found were the sample chapter
from Mark Hammond's book and some decades old PowerPoint show.
I have a following problem:
I am trying to do XML Schema validation using MSXML SAX parser through
PythonCOM API.
MSXML offers two different interfaces for SAX: One for VB and one for
C++. C++ one is named ISAXXMLReader and VB one is named
IVBSAXXMLReader. I haven't found what is the basic difference between
these interfaces though I have carefully read MSXML SDK documentation.
I assume IVBSAXXMLReader might have some IDispatch functionality which
is requirement for PythonCom(?).
The problem is that SAX Parser requires COM interface for callback.
You must assign a COM interface as a handler to the parser. When the
parsing begins, the handler calls this interface.
saxReader.errorHandler = myErrorHandler <-- COM Interface
I do not know how to turn Python class into COM interface on the fly.
I have managed to open the C++ version ISAXXMLReader of the interface.
I have NOT succeed to do this for VB versioon IVBSAXXMLReader, because
I do not know how it happens. I assume you have to use
CoCreateInstance, but it returns "Class not registered", see the
sample below.
After opening ISAXXMLReader I have not been able to pass COM error
handler for it. I have reasons not to go through full process
registering my own error handler as a COM server into Windows registry
and create it using win32com.client.Dispatch("Python.MyErrorHandler").
Is there a way to create COM server on the fly and get the COM handle
for it? I have been trying to read win32.client and win32.server
Python sources and even PythonCOM C sources, but unfortunately my
skillz are not 1337 enough to see the big picture.
How to assign a COM Interface for a Python object? It goes somehow
through policies and wrapping, right? Unfortunately every approach I
have tried end to an error saying my wrapper IPyDispatch cannot be
used as ISAXErrorHandler.
Mikko Ohtamaa
Student of Industrial Engineering & Management
Oulu, Finland
Sample code:
class MySaxErrorHandler:
# Some random stuff in stucked into this class
# hoping it would help policies & wrapping
_reg_progid_ = "Art2ComponentValidator.SaxErrorHandler"
_reg_clsid_ = "{a60511c4-ccf5-479e-98a3-dc8dc545b7d0}"
_reg_clsctx_ = "INPROC_SERVER"
_com_interfaces = [ "{a60511c4-ccf5-479e-98a3-dc8dc545b7d0}" ]
_query_interface_ = "{a60511c4-ccf5-479e-98a3-dc8dc545b7d0}"
_public_methods_ = [ "error", "fatalError", "ignorableWarning" ]
# A piece of VB sample:
#Private Sub IVBSAXErrorHandler_error(ByVal oLocator As
SXML2.IVBSAXLocator,
strErrorMessage As String, ByVal nErrorCode As Long)
# WriteErrorToResults "Error", strErrorMessage, _
# nErrorCode, oLocator.lineNumber, oLocator.columnNumber
#End Sub
def error(oLocator, strErrorMessage, nErrorCode):
print strErrorMessage
def fatalError(oLocator, strErrorMessage, nErrorCode):
print strErrorMessage
def ignorableWarning(oLocator, strErrorMessage, nErrorCode):
print strErrorMessage
def saxtest():
# SAXXmlReader MIDL: a4f96ed0-f829-476e-81c0-cdc7bd2a0802
# sax error handler: a60511c4-ccf5-479e-98a3-dc8dc545b7d0
# ivbsaxerrorhandler: d963d3fe-173c-4862-9095-b92f66995f52
# ivbsaxxmlreader: 8c033caa-6cd6-4f73-b728-4531af74945f
# test path switcher
useISAX = 0
if useISAX:
# Use c++ version ISAXXMLReader
saxReader = win32com.client.Dispatch("Msxml2.SAXXMLReader.4.0")
errorHandler = MySaxErrorHandler()
# ISAXErrorHandler: a60511c4-ccf5-479e-98a3-dc8dc545b7d0
iid = pywintypes.IID("{a60511c4-ccf5-479e-98a3-dc8dc545b7d0}")
# What I should do instead of this?
saxReader.errorHandler =
win32com.server.util.wrap(errorHandler, iid)
# Following error:
# File "C:\Python22\Lib\site-packages\win32com\server\util.py",
line 28, in wrap
# ob = ob.QueryInterface(iid) # Ask the PyIDispatch
if it supports it?
# pywintypes.com_error: (-2147467262, 'No such interface
supported', None, None)
else:
# Use VB version, IVBSAXXMLreader
clsid = pywintypes.IID("{8c033caa-6cd6-4f73-b728-4531af74945f}")
iid = clsid
create_as = win32com.client.pythoncom.CLSCTX_INPROC_SERVER
iface = win32com.client.pythoncom.CoCreateInstance(clsid,
None, create_as, iid)
# pywintypes.com_error: (-2147221164, 'Class not registered',
None, None)
I am quite new to Python, PythonCom and COM generally. As a former
Java programmer, I have found Python's flexible ability to access
native Win32, especially COM, very comfortable. However, there is
quite little on-line documentation and examples available about
PythonCOM. The only good sources I have found were the sample chapter
from Mark Hammond's book and some decades old PowerPoint show.
I have a following problem:
I am trying to do XML Schema validation using MSXML SAX parser through
PythonCOM API.
MSXML offers two different interfaces for SAX: One for VB and one for
C++. C++ one is named ISAXXMLReader and VB one is named
IVBSAXXMLReader. I haven't found what is the basic difference between
these interfaces though I have carefully read MSXML SDK documentation.
I assume IVBSAXXMLReader might have some IDispatch functionality which
is requirement for PythonCom(?).
The problem is that SAX Parser requires COM interface for callback.
You must assign a COM interface as a handler to the parser. When the
parsing begins, the handler calls this interface.
saxReader.errorHandler = myErrorHandler <-- COM Interface
I do not know how to turn Python class into COM interface on the fly.
I have managed to open the C++ version ISAXXMLReader of the interface.
I have NOT succeed to do this for VB versioon IVBSAXXMLReader, because
I do not know how it happens. I assume you have to use
CoCreateInstance, but it returns "Class not registered", see the
sample below.
After opening ISAXXMLReader I have not been able to pass COM error
handler for it. I have reasons not to go through full process
registering my own error handler as a COM server into Windows registry
and create it using win32com.client.Dispatch("Python.MyErrorHandler").
Is there a way to create COM server on the fly and get the COM handle
for it? I have been trying to read win32.client and win32.server
Python sources and even PythonCOM C sources, but unfortunately my
skillz are not 1337 enough to see the big picture.
How to assign a COM Interface for a Python object? It goes somehow
through policies and wrapping, right? Unfortunately every approach I
have tried end to an error saying my wrapper IPyDispatch cannot be
used as ISAXErrorHandler.
Mikko Ohtamaa
Student of Industrial Engineering & Management
Oulu, Finland
Sample code:
class MySaxErrorHandler:
# Some random stuff in stucked into this class
# hoping it would help policies & wrapping
_reg_progid_ = "Art2ComponentValidator.SaxErrorHandler"
_reg_clsid_ = "{a60511c4-ccf5-479e-98a3-dc8dc545b7d0}"
_reg_clsctx_ = "INPROC_SERVER"
_com_interfaces = [ "{a60511c4-ccf5-479e-98a3-dc8dc545b7d0}" ]
_query_interface_ = "{a60511c4-ccf5-479e-98a3-dc8dc545b7d0}"
_public_methods_ = [ "error", "fatalError", "ignorableWarning" ]
# A piece of VB sample:
#Private Sub IVBSAXErrorHandler_error(ByVal oLocator As
SXML2.IVBSAXLocator,
strErrorMessage As String, ByVal nErrorCode As Long)
# WriteErrorToResults "Error", strErrorMessage, _
# nErrorCode, oLocator.lineNumber, oLocator.columnNumber
#End Sub
def error(oLocator, strErrorMessage, nErrorCode):
print strErrorMessage
def fatalError(oLocator, strErrorMessage, nErrorCode):
print strErrorMessage
def ignorableWarning(oLocator, strErrorMessage, nErrorCode):
print strErrorMessage
def saxtest():
# SAXXmlReader MIDL: a4f96ed0-f829-476e-81c0-cdc7bd2a0802
# sax error handler: a60511c4-ccf5-479e-98a3-dc8dc545b7d0
# ivbsaxerrorhandler: d963d3fe-173c-4862-9095-b92f66995f52
# ivbsaxxmlreader: 8c033caa-6cd6-4f73-b728-4531af74945f
# test path switcher
useISAX = 0
if useISAX:
# Use c++ version ISAXXMLReader
saxReader = win32com.client.Dispatch("Msxml2.SAXXMLReader.4.0")
errorHandler = MySaxErrorHandler()
# ISAXErrorHandler: a60511c4-ccf5-479e-98a3-dc8dc545b7d0
iid = pywintypes.IID("{a60511c4-ccf5-479e-98a3-dc8dc545b7d0}")
# What I should do instead of this?
saxReader.errorHandler =
win32com.server.util.wrap(errorHandler, iid)
# Following error:
# File "C:\Python22\Lib\site-packages\win32com\server\util.py",
line 28, in wrap
# ob = ob.QueryInterface(iid) # Ask the PyIDispatch
if it supports it?
# pywintypes.com_error: (-2147467262, 'No such interface
supported', None, None)
else:
# Use VB version, IVBSAXXMLreader
clsid = pywintypes.IID("{8c033caa-6cd6-4f73-b728-4531af74945f}")
iid = clsid
create_as = win32com.client.pythoncom.CLSCTX_INPROC_SERVER
iface = win32com.client.pythoncom.CoCreateInstance(clsid,
None, create_as, iid)
# pywintypes.com_error: (-2147221164, 'Class not registered',
None, None)