[python-win32] Making a COM server that accepts COM objects

Boylan, Ross Ross.Boylan at ucsf.edu
Tue Jan 8 16:46:29 EST 2019


I have a Python 3.7, 32 bit, COM server and am calling it from 32 bit Office 2010 in VBA.  I am attempting to pass some COM objects from VBA to Python.  The trace collector full output appears below, but I think the key clues are several messages like

in <BSTImport.BSTImport object at 0x009F62F0>._QueryInterface_ with unsupported IID {00000003-0000-0000-C000-000000000046} ({00000003-0000-0000-C000-000000000046})

and, later,
    rst = fedb.OpenRecordset("foo")
AttributeError: 'PyIDispatch' object has no attribute 'OpenRecordset'

I think this means that the objects passed in have unrecognized types, and therefore type-specific methods don't work on them (though it seems odd they aren't dynamically dispatched).

What can I do to fix or debug this?

Based on this theory, I used the makepy tool from the GUI to import the DAO 3.6 library, which I believe defines both types.  But this didn't seem to help.  I found some documentation saying to use win32com.client.Dispatch to get the right interface--it also mentioned that the IDispatch object would only repond to the 2 methods it knows--but I don't know how.  All the examples I've seen with Dispatch use it to create a new object.  I can't find any documentation on it (as opposed to tutorials illustratin it use); I think com\win32com\client\__init__.py has the relevant definition in the source code, but it is not apparent to me whether handing it an IDispatch object rather "Company.Class" will cause the  appropriate object to be created.

Running on 64 bit Win 7, with quite a few installations of versions of Python floating around.  Using a LocalServer because of earlier problems with in process servers.  In particular, the invoking path in the registry for my class is 
C:\PROGRA~2\PYTHON~1\pythonw.exe "C:\Users\rdboylan\AppData\Roaming\Python\Python37\site-packages\win32com\server\localserver.py"
even though I just installed pywin32 and it said it was putting things under "c:\Program Files (x86)".  Both locations (with suitable additions to the Program Files path) have localserver.py
--------------------------------------------------- test code in VBA ----------------------------------------

Public Function medium()
    Dim srv As Object
    Set srv = CreateObject("Fahy.BST")
    medium = srv.Barney(DBEngine.Workspaces(0), CurrentDb())
End Function
---------------------------------------------------------------------

------------------------ python server code BSTImport.py ---------------------------
import atexit, csv, sys
import pythoncom, win32com.client
from win32com.server.exception import COMException
from win32com.client import constants
from win32com.server.register import UseCommandLine

TmpTable = "aatmpt_bst"  # table to import csv into
#pdb.set_trace()
# fields in csv file I use now are
# 'Sample Barcode', 'Participant ID', 'Initials', 'Visit ID',
# 'Collection Date', 'Sample Type', 'Site Comment',
# 'Shipment Comment', 'Shipment ID

# BST Import already name of form in VB
class BSTImport:
    # COM Support
    _public_methods_ = ['Fred', 'Barney']

    _reg_clsid_ = "{050321C2-9B99-4CD0-B5E9-B636DFD94C4D}"
    _reg_desc_ = "BST Test Com Server in Python 32 bit"
    _reg_progid_ = "Fahy.BST"
    # for unknown reasons the inprocess server isn't working
    _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER

    def Barney(self, ws, fedb):
        """ws is the workspace with which a transaction has already been  initiated
        fedb is  the database used by the frontend"""
        rst = fedb.OpenRecordset("foo")
        rst.AddNew()
        fld = rst("foolish")
        fld.Value = "python.Barney"
        rst.Update()
        rst.Close()
        rst = None
        return True
    # other methods omitted

if __name__ == "__main__":
    UseCommandLine(BSTImport)
-------------------------------------------------------------------------------------------

--------------------------------------- trace ---------------------------------------------

Object with win32trace dispatcher created (object=None)
in <BSTImport.BSTImport object at 0x009F62F0>._QueryInterface_ with unsupported IID {00000003-0000-0000-C000-000000000046} ({00000003-0000-0000-C000-000000000046})
in <BSTImport.BSTImport object at 0x009F62F0>._QueryInterface_ with unsupported IID {0000001B-0000-0000-C000-000000000046} ({0000001B-0000-0000-C000-000000000046})
in <BSTImport.BSTImport object at 0x009F62F0>._QueryInterface_ with unsupported IID {00000018-0000-0000-C000-000000000046} ({00000018-0000-0000-C000-000000000046})
in <BSTImport.BSTImport object at 0x009F62F0>._QueryInterface_ with unsupported IID b'IExternalConnection' ({00000019-0000-0000-C000-000000000046})
in <BSTImport.BSTImport object at 0x009F62F0>._QueryInterface_ with unsupported IID {4C1E39E1-E3E3-4296-AA86-EC938D896E92} ({4C1E39E1-E3E3-4296-AA86-EC938D896E92})
in <BSTImport.BSTImport object at 0x009F62F0>._QueryInterface_ with unsupported IID b'IPersistStreamInit' ({7FD52380-4E07-101B-AE2D-08002B2EC713})
in <BSTImport.BSTImport object at 0x009F62F0>._QueryInterface_ with unsupported IID b'IPersistPropertyBag' ({37D84F60-42CB-11CE-8135-00AA004BB851})
in <BSTImport.BSTImport object at 0x009F62F0>._QueryInterface_ with unsupported IID {1C733A30-2A1C-11CE-ADE5-00AA0044773D} ({1C733A30-2A1C-11CE-ADE5-00AA0044773D})
in _GetIDsOfNames_ with '('Barney',)' and '1033'

in _Invoke_ with 1001 1033 3 (<PyIDispatch at 0x00B81400 with obj at 0x00848994>, <PyIDispatch at 0x00B81418 with obj at 0x00848A24>)
Traceback (most recent call last):
  File "C:\Users\rdboylan\AppData\Roaming\Python\Python37\site-packages\win32com\server\dispatcher.py", line 47, in _Invoke_
    return self.policy._Invoke_(dispid, lcid, wFlags, args)
  File "C:\Users\rdboylan\AppData\Roaming\Python\Python37\site-packages\win32com\server\policy.py", line 278, in _Invoke_
    return self._invoke_(dispid, lcid, wFlags, args)
  File "C:\Users\rdboylan\AppData\Roaming\Python\Python37\site-packages\win32com\server\policy.py", line 283, in _invoke_
    return S_OK, -1, self._invokeex_(dispid, lcid, wFlags, args, None, None)
  File "C:\Users\rdboylan\AppData\Roaming\Python\Python37\site-packages\win32com\server\policy.py", line 586, in _invokeex_
    return func(*args)
  File "C:\Users\rdboylan\Documents\Wk devel\BSTImport.py", line 36, in Barney
    rst = fedb.OpenRecordset("foo")
AttributeError: 'PyIDispatch' object has no attribute 'OpenRecordset'
pythoncom error: Python error invoking COM method.

Traceback (most recent call last):
  File "C:\Users\rdboylan\AppData\Roaming\Python\Python37\site-packages\win32com\server\dispatcher.py", line 163, in _Invoke_
    return DispatcherBase._Invoke_(self, dispid, lcid, wFlags, args)
  File "C:\Users\rdboylan\AppData\Roaming\Python\Python37\site-packages\win32com\server\dispatcher.py", line 49, in _Invoke_
    return self._HandleException_()
  File "C:\Users\rdboylan\AppData\Roaming\Python\Python37\site-packages\win32com\server\dispatcher.py", line 47, in _Invoke_
    return self.policy._Invoke_(dispid, lcid, wFlags, args)
  File "C:\Users\rdboylan\AppData\Roaming\Python\Python37\site-packages\win32com\server\policy.py", line 278, in _Invoke_
    return self._invoke_(dispid, lcid, wFlags, args)
  File "C:\Users\rdboylan\AppData\Roaming\Python\Python37\site-packages\win32com\server\policy.py", line 283, in _invoke_
    return S_OK, -1, self._invokeex_(dispid, lcid, wFlags, args, None, None)
  File "C:\Users\rdboylan\AppData\Roaming\Python\Python37\site-packages\win32com\server\policy.py", line 586, in _invokeex_
    return func(*args)
  File "C:\Users\rdboylan\Documents\Wk devel\BSTImport.py", line 36, in Barney
    rst = fedb.OpenRecordset("foo")
AttributeError: 'PyIDispatch' object has no attribute 'OpenRecordset'
in <BSTImport.BSTImport object at 0x009F62F0>._QueryInterface_ with unsupported IID IProvideClassInfo ({B196B283-BAB4-101A-B69C-00AA00341D07})
in <BSTImport.BSTImport object at 0x009F62F0>._QueryInterface_ with unsupported IID {CACC1E85-622B-11D2-AA78-00C04F9901D2} ({CACC1E85-622B-11D2-AA78-00C04F9901D2})
in _GetTypeInfo_ with index=0, lcid=1033

in _GetTypeInfo_ with index=0, lcid=0
-------------------------------------------------------------------------------------------------


More information about the python-win32 mailing list