[python-win32] COM server AddIn
Johannes Brunen
jbrunen at datasolid.de
Wed Jul 6 11:43:35 CEST 2005
Hi Mark,
unfortunately I do not make any progress. The trace collector gives me the
following output.
Object with win32trace dispatcher created (object=None)
pythoncom error: Failed to call the universal dispatcher
Traceback (most recent call last):
File "C:\Programme\Python\Lib\site-packages\win32com\universal.py", line
173, in dispatch
retVal = ob._InvokeEx_(meth.dispid, 0, meth.invkind, args, None, None)
File "C:\Programme\Python\Lib\site-packages\win32com\server\policy.py",
line 330, in _InvokeEx_
return self._invokeex_(dispid, lcid, wFlags, args, kwargs,
serviceProvider)
File "C:\Programme\Python\Lib\site-packages\win32com\server\policy.py",
line 647, in _invokeex_
return DesignatedWrapPolicy.c( self, dispid, lcid, wFlags, args, kwArgs,
serviceProvider)
File "C:\Programme\Python\Lib\site-packages\win32com\server\policy.py",
line 593, in _invokeex_
raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND) # not found
win32com.server.exception.COMException: (-2147352573, 'Mitglied nicht
gefunden.', None, -1)
How can I see the values of the arguments passed to function ._InvokeEx_?
Below I added the 'AddIn1.py' server script and the script generated by
gencache. Additionally,
I have added a properly working Visual Basic file 'Addin4.cls', which I used
as a starting point
for my PythonCOM Addin1 test. Do you have any ideas what is going wrong
here?
Is there any way to get the debugger stop in one of the _InvokeEx_
functions?
Any help would be very much appreciated.
With kind regards
Johannes
My script now looks as follows:
##
## Addin1.py - A very simple CADdy++ AddIn server
##
from win32com import universal
from win32com.server.exception import COMException
from win32com.client import gencache
#from win32com.client import DispatchWithEvents
#import winerror
import pythoncom
#from win32com.client import constants, Dispatch
import sys
#
# Support for COM objects we use.
#
gencache.EnsureModule('{9C3BB401-114D-11D4-AC72-00105A4925FC}', 0, 1, 2,
bForDemand=True) # CADdy.tlb
#
# The TLB defining the interfaces we implement
#
universal.RegisterInterfaces('{9C3BB401-114D-11D4-AC72-00105A4925FC}', 0, 1,
2, ['ICADdyAddIn'])
class AddIn1:
_com_interfaces_ = ['ICADdyAddIn']
_public_methods_ = ['Exit','Init','CLSID','ProgId','Description']
_reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER
_reg_clsid_ = "{AB6C657A-2C26-4BD0-ABB8-D777BC91F199}"
_reg_progid_ = "CADdyAddIn.PythonTest1"
_reg_policy_spec_ = "win32com.server.policy.EventHandlerPolicy"
def __init__(self):
self.appHostApp = None
def Exit(self):
"""method Exit"""
self.appHostApp = None
def Init(self, theCADdy):
"""method Init"""
self.appHostApp = theCADdy
self.CLSID = _reg_clsid_
self.ProgId = _reg_progid_
self.Description = "CADdy++ CADdyAddIn.PythonTest1"
pUIManager = theCADdy.UIManager
pUIManager.Information("Init Python Test AddIn1...")
def CLSID(self):
return self.CLSID
def ProgId(self):
return self.ProgId
def Description(self):
return self.Description
def RegisterAddin(klass):
pass
def UnregisterAddin(klass):
pass
if __name__ == '__main__':
import win32com.server.register
win32com.server.register.UseCommandLine(AddIn1)
if "--unregister" in sys.argv:
UnregisterAddin(AddIn1)
else:
RegisterAddin(AddIn1)
And my gencache generated python script:
# Created by makepy.py version 0.4.93
# By python version 2.4.1 (#65, Mar 30 2005, 09:33:37) [MSC v.1310 32 bit
(Intel)]
# From type library '{9C3BB401-114D-11D4-AC72-00105A4925FC}'
# On Wed Jun 29 17:14:19 2005
"""CADdyCOM 1.2 (CADdy) Type Library"""
makepy_version = '0.4.93'
python_version = 0x20401f0
import win32com.client.CLSIDToClass, pythoncom
import win32com.client.util
from pywintypes import IID
from win32com.client import Dispatch
# The following 3 lines may need tweaking for the particular server
# Candidates are pythoncom.Missing and pythoncom.Empty
defaultNamedOptArg=pythoncom.Empty
defaultNamedNotOptArg=pythoncom.Empty
defaultUnnamedArg=pythoncom.Empty
CLSID = IID('{9C3BB401-114D-11D4-AC72-00105A4925FC}')
MajorVersion = 1
MinorVersion = 2
LibraryFlags = 8
LCID = 0x0
class constants:
ADDIN_E_ALREADYSTARTED =-2147220991 # from enum ADDINHRESULTS
ADDIN_E_CANTCREATESERVER =-2147220989 # from enum ADDINHRESULTS
ADDIN_E_ERRONEOUSADDIN =-2147220992 # from enum ADDINHRESULTS
ADDIN_E_INAPPROPRIATESERVER =-2147220990 # from enum ADDINHRESULTS
from win32com.client import DispatchBaseClass
class ICADdy(DispatchBaseClass):
"""ICADdy Interface"""
CLSID = IID('{D330F3E0-0F91-11D4-AC6E-00105A4925FC}')
coclass_clsid = IID('{D330F3E1-0F91-11D4-AC6E-00105A4925FC}')
# The method Manager is actually a property, but must be used as a method
to correctly pass the arguments
def Manager(self, _MIDL_0025_=defaultNamedNotOptArg):
"""property Manager"""
ret = self._oleobj_.InvokeTypes(4, LCID, 2, (9, 0), ((8, 1),),_MIDL_0025_
)
if ret is not None:
ret = Dispatch(ret, 'Manager', None, UnicodeToString=0)
return ret
_prop_map_get_ = {
"ExeDirectory": (5, 2, (8, 0), (), "ExeDirectory", None),
"FrameManager": (1, 2, (9, 0), (), "FrameManager", None),
"HomeDirectory": (6, 2, (8, 0), (), "HomeDirectory", None),
"ModelManager": (2, 2, (9, 0), (), "ModelManager", None),
"Name": (7, 2, (8, 0), (), "Name", None),
"ReleaseNo": (9, 2, (3, 0), (), "ReleaseNo", None),
"UIManager": (3, 2, (9, 0), (), "UIManager", None),
"VersionNo": (8, 2, (3, 0), (), "VersionNo", None),
}
_prop_map_put_ = {
}
class ICADdyAddIn(DispatchBaseClass):
"""ICADdyAddIn Interface"""
CLSID = IID('{14F65AE1-4671-11D4-8B1A-00105A49278B}')
coclass_clsid = None
def Exit(self):
"""method Exit"""
return self._oleobj_.InvokeTypes(2, LCID, 1, (24, 0), (),)
def Init(self, theCADdy=defaultNamedNotOptArg):
"""method Init"""
return self._oleobj_.InvokeTypes(1, LCID, 1, (24, 0), ((9, 1),),theCADdy
)
_prop_map_get_ = {
"CLSID": (3, 2, (8, 0), (), "CLSID", None),
"Description": (5, 2, (8, 0), (), "Description", None),
"ProgId": (4, 2, (8, 0), (), "ProgId", None),
}
_prop_map_put_ = {
}
class ICADdyAddIns(DispatchBaseClass):
"""ICADdyAddIns Interface"""
CLSID = IID('{14F65AE2-4671-11D4-8B1A-00105A49278B}')
coclass_clsid = IID('{3F5B2591-4768-11D4-8B1C-00105A49278B}')
# Result is of type ICADdyAddIn
# The method Item is actually a property, but must be used as a method to
correctly pass the arguments
def Item(self, _MIDL_0018_=defaultNamedNotOptArg):
"""Item"""
ret = self._oleobj_.InvokeTypes(0, LCID, 2, (9, 0), ((3, 1),),_MIDL_0018_
)
if ret is not None:
ret = Dispatch(ret, 'Item', '{14F65AE1-4671-11D4-8B1A-00105A49278B}',
UnicodeToString=0)
return ret
# Result is of type ICADdyAddIn
def Start(self, _MIDL_0022_=defaultNamedNotOptArg):
"""Start"""
ret = self._oleobj_.InvokeTypes(2, LCID, 1, (9, 0), ((8, 1),),_MIDL_0022_
)
if ret is not None:
ret = Dispatch(ret, 'Start', '{14F65AE1-4671-11D4-8B1A-00105A49278B}',
UnicodeToString=0)
return ret
def Stop(self, _MIDL_0024_=defaultNamedNotOptArg):
"""Stop"""
return self._oleobj_.InvokeTypes(3, LCID, 1, (24, 0), ((9,
1),),_MIDL_0024_
)
def StopAll(self):
"""StopAll"""
return self._oleobj_.InvokeTypes(4, LCID, 1, (24, 0), (),)
_prop_map_get_ = {
"Count": (1, 2, (3, 0), (), "Count", None),
}
_prop_map_put_ = {
}
# Default method for this class is 'Item'
def __call__(self, _MIDL_0018_=defaultNamedNotOptArg):
"""Item"""
ret = self._oleobj_.InvokeTypes(0, LCID, 2, (9, 0), ((3, 1),),_MIDL_0018_
)
if ret is not None:
ret = Dispatch(ret, '__call__', '{14F65AE1-4671-11D4-8B1A-00105A49278B}',
UnicodeToString=0)
return ret
# str(ob) and int(ob) will use __call__
def __unicode__(self, *args):
try:
return unicode(self.__call__(*args))
except pythoncom.com_error:
return repr(self)
def __str__(self, *args):
return str(self.__unicode__(*args))
def __int__(self, *args):
return int(self.__call__(*args))
def __iter__(self):
"Return a Python iterator for this object"
ob = self._oleobj_.InvokeTypes(-4,LCID,2,(13, 10),())
return win32com.client.util.Iterator(ob)
def _NewEnum(self):
"Create an enumerator from this object"
return
win32com.client.util.WrapEnum(self._oleobj_.InvokeTypes(-4,LCID,2,(13,
10),()),'{14F65AE1-4671-11D4-8B1A-00105A49278B}')
def __getitem__(self, index):
"Allow this class to be accessed as a collection"
if not self.__dict__.has_key('_enum_'):
self.__dict__['_enum_'] = self._NewEnum()
return self._enum_.__getitem__(index)
#This class has Count() property - allow len(ob) to provide this
def __len__(self):
return self._ApplyTypes_(*(1, 2, (3, 0), (), "Count", None))
#This class has a __len__ - this is needed so 'if object:' always returns
TRUE.
def __nonzero__(self):
return True
from win32com.client import CoClassBaseClass
# This CoClass is known by the name 'AddIns.CADdyAddIns.1'
class CADdyAddIns(CoClassBaseClass): # A CoClass
# CADdyAddIn Collection
CLSID = IID('{3F5B2591-4768-11D4-8B1C-00105A49278B}')
coclass_sources = [
]
coclass_interfaces = [
ICADdyAddIns,
]
default_interface = ICADdyAddIns
# This CoClass is known by the name 'CADdy.CADdy.1'
class CoCADdy(CoClassBaseClass): # A CoClass
# CADdy Class
CLSID = IID('{D330F3E1-0F91-11D4-AC6E-00105A4925FC}')
coclass_sources = [
]
coclass_interfaces = [
ICADdy,
]
default_interface = ICADdy
ICADdy_vtables_dispatch_ = 1
ICADdy_vtables_ = [
(( 'FrameManager' , 'ppICADdyFrameManager' , ), 1, (1, (), [ (16393, 10,
None, None) , ], 1 , 2 , 4 , 0 , 28 , (3, 0, None, None) , 0 , )),
(( 'ModelManager' , 'ppICADdyModelManager' , ), 2, (2, (), [ (16393, 10,
None, None) , ], 1 , 2 , 4 , 0 , 32 , (3, 0, None, None) , 0 , )),
(( 'UIManager' , 'ppICADdyUIManager' , ), 3, (3, (), [ (16393, 10, None,
None) , ], 1 , 2 , 4 , 0 , 36 , (3, 0, None, None) , 0 , )),
(( 'Manager' , '__MIDL_0025' , 'ppICADdyDimensionManager' , ), 4, (4, (),
[ (8, 1, None, None) ,
(16393, 10, None, None) , ], 1 , 2 , 4 , 0 , 40 , (3, 0, None, None) , 0
, )),
(( 'ExeDirectory' , 'pbstrDirectory' , ), 5, (5, (), [ (16392, 10, None,
None) , ], 1 , 2 , 4 , 0 , 44 , (3, 0, None, None) , 0 , )),
(( 'HomeDirectory' , 'pbstrDirectory' , ), 6, (6, (), [ (16392, 10, None,
None) , ], 1 , 2 , 4 , 0 , 48 , (3, 0, None, None) , 0 , )),
(( 'Name' , 'pbstrName' , ), 7, (7, (), [ (16392, 10, None, None) , ], 1 ,
2 , 4 , 0 , 52 , (3, 0, None, None) , 0 , )),
(( 'VersionNo' , 'lVersion' , ), 8, (8, (), [ (16387, 10, None, None) , ],
1 , 2 , 4 , 0 , 56 , (3, 0, None, None) , 0 , )),
(( 'ReleaseNo' , 'lRelease' , ), 9, (9, (), [ (16387, 10, None, None) , ],
1 , 2 , 4 , 0 , 60 , (3, 0, None, None) , 0 , )),
]
ICADdyAddIn_vtables_dispatch_ = 1
ICADdyAddIn_vtables_ = [
(( 'Init' , 'theCADdy' , ), 1, (1, (), [ (9, 1, None,
"IID('{D330F3E0-0F91-11D4-AC6E-00105A4925FC}')") , ], 1 , 1 , 4 , 0 , 28 ,
(3, 0, None, None) , 0 , )),
(( 'Exit' , ), 2, (2, (), [ ], 1 , 1 , 4 , 0 , 32 , (3, 0, None, None) , 0
, )),
(( 'CLSID' , 'pcCLSID' , ), 3, (3, (), [ (16392, 10, None, None) , ], 1 , 2
, 4 , 0 , 36 , (3, 0, None, None) , 0 , )),
(( 'ProgId' , 'pcProgId' , ), 4, (4, (), [ (16392, 10, None, None) , ], 1 ,
2 , 4 , 0 , 40 , (3, 0, None, None) , 0 , )),
(( 'Description' , 'pcDescription' , ), 5, (5, (), [ (16392, 10, None,
None) , ], 1 , 2 , 4 , 0 , 44 , (3, 0, None, None) , 0 , )),
]
ICADdyAddIns_vtables_dispatch_ = 1
ICADdyAddIns_vtables_ = [
(( 'Item' , '__MIDL_0018' , '__MIDL_0019' , ), 0, (0, (), [ (3, 1, None,
None) ,
(16393, 10, None, "IID('{14F65AE1-4671-11D4-8B1A-00105A49278B}')") , ], 1
, 2 , 4 , 0 , 28 , (3, 0, None, None) , 0 , )),
(( '_NewEnum' , '__MIDL_0020' , ), -4, (-4, (), [ (16397, 10, None, None)
, ], 1 , 2 , 4 , 0 , 32 , (3, 0, None, None) , 1 , )),
(( 'Count' , '__MIDL_0021' , ), 1, (1, (), [ (16387, 10, None, None) , ], 1
, 2 , 4 , 0 , 36 , (3, 0, None, None) , 0 , )),
(( 'Start' , '__MIDL_0022' , '__MIDL_0023' , ), 2, (2, (), [ (8, 1, None,
None) ,
(16393, 10, None, "IID('{14F65AE1-4671-11D4-8B1A-00105A49278B}')") , ], 1
, 1 , 4 , 0 , 40 , (3, 0, None, None) , 0 , )),
(( 'Stop' , '__MIDL_0024' , ), 3, (3, (), [ (9, 1, None,
"IID('{14F65AE1-4671-11D4-8B1A-00105A49278B}')") , ], 1 , 1 , 4 , 0 , 44 ,
(3, 0, None, None) , 0 , )),
(( 'StopAll' , ), 4, (4, (), [ ], 1 , 1 , 4 , 0 , 48 , (3, 0, None, None) ,
0 , )),
]
IEnumCADdyAddIn_vtables_dispatch_ = 0
IEnumCADdyAddIn_vtables_ = [
(( 'Next' , 'i4Count' , '__MIDL_0015' , 'pi4Fetched' , ), 1, (1, (), [
(19, 1, None, None) , (16393, 2, None,
"IID('{14F65AE1-4671-11D4-8B1A-00105A49278B}')") , (16403, 2, None, None)
, ], 1 , 1 , 4 , 0 , 12 , (3, 0, None, None) , 0 , )),
(( 'Skip' , '__MIDL_0016' , ), 2, (2, (), [ (19, 1, None, None) , ], 1 , 1
, 4 , 0 , 16 , (3, 0, None, None) , 0 , )),
(( 'Reset' , ), 3, (3, (), [ ], 1 , 1 , 4 , 0 , 20 , (3, 0, None, None) , 0
, )),
(( 'Clone' , '__MIDL_0017' , ), 4, (4, (), [ (16397, 2, None,
"IID('{14F65AE3-4671-11D4-8B1A-00105A49278B}')") , ], 1 , 1 , 4 , 0 , 24 ,
(3, 0, None, None) , 0 , )),
]
ISupportErrorInfo_vtables_dispatch_ = 0
ISupportErrorInfo_vtables_ = [
(( 'InterfaceSupportsErrorInfo' , 'riid' , ), 1610678272, (1610678272, (),
[ (36, 1, None, None) , ], 1 , 1 , 4 , 0 , 12 , (3, 0, None, None) , 0 , )),
]
RecordMap = {
}
CLSIDToClassMap = {
'{14F65AE1-4671-11D4-8B1A-00105A49278B}' : ICADdyAddIn,
'{D330F3E1-0F91-11D4-AC6E-00105A4925FC}' : CoCADdy,
'{D330F3E0-0F91-11D4-AC6E-00105A4925FC}' : ICADdy,
'{14F65AE2-4671-11D4-8B1A-00105A49278B}' : ICADdyAddIns,
'{3F5B2591-4768-11D4-8B1C-00105A49278B}' : CADdyAddIns,
}
CLSIDToPackageMap = {}
win32com.client.CLSIDToClass.RegisterCLSIDsFromDict( CLSIDToClassMap )
VTablesToPackageMap = {}
VTablesToClassMap = {
'{14F65AE2-4671-11D4-8B1A-00105A49278B}' : 'ICADdyAddIns',
'{14F65AE3-4671-11D4-8B1A-00105A49278B}' : 'IEnumCADdyAddIn',
'{D330F3E0-0F91-11D4-AC6E-00105A4925FC}' : 'ICADdy',
'{DF0B3D60-548F-101B-8E65-08002B2BD119}' : 'ISupportErrorInfo',
'{14F65AE1-4671-11D4-8B1A-00105A49278B}' : 'ICADdyAddIn',
}
NamesToIIDMap = {
'ICADdyAddIn' : '{14F65AE1-4671-11D4-8B1A-00105A49278B}',
'ICADdy' : '{D330F3E0-0F91-11D4-AC6E-00105A4925FC}',
'ISupportErrorInfo' : '{DF0B3D60-548F-101B-8E65-08002B2BD119}',
'IEnumCADdyAddIn' : '{14F65AE3-4671-11D4-8B1A-00105A49278B}',
'ICADdyAddIns' : '{14F65AE2-4671-11D4-8B1A-00105A49278B}',
}
win32com.client.constants.__dicts__.append(constants.__dict__)
The Visual Basic example:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "AddIn4"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
'
' Implementation of the addin4 COM component. To communicate with CADdy++
' the component implements the CADdy++ provided interface ICADdyAddIn.
' This contains mainly the implementation of such things you want to do
' on starting and exiting an addin.
'
Option Explicit
Implements ICADdyAddIn
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
' a commandpool for this addins's commands
Private pCmdPool As CmdPoolAddIn4
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As
Any, pSrc As Any, ByVal ByteLen As Long)
Private Declare Function CLSIDFromProgID Lib "ole32.dll" (ByVal lpszProgID
As Long, pCLSID As GUID) As Long
Private Declare Function StringFromCLSID Lib "ole32.dll" (pCLSID As GUID,
lpszProgID As Long) As Long
'
'
' init method
' This method is called on initialization of every CADdyAddIn.
' You can set your global vars and if required AddIn specific data.
'
'
Private Sub ICADdyAddIn_Init(ByVal theCADdy As CoCADdy)
MsgBox "Init AddIn4", vbOKOnly, "AddIn4"
Set pICADdy = theCADdy
Set pIFrameManager = pICADdy.FrameManager
Set pUIManager = pICADdy.UIManager
' attach commands in CADdy++
Set pCmdPool = New CmdPoolAddIn4
End Sub
'
'
' This method is called while exiting a CADdyAddIn. Here normaly globals are
' cleaned and commandpools removed.
'
'
Private Sub ICADdyAddIn_Exit()
MsgBox "Exit AddIn4", vbOKOnly, "AddIn4"
' detach commands from CADdy++
Set pCmdPool = Nothing
Set pICADdy = Nothing
Set pIFrameManager = Nothing
Set pUIManager = Nothing
oNonModalForm.UnloadAddIn4Form
Set oNonModalForm = Nothing
End Sub
'
'
' An utility method which returns the AddIn's ClassId
'
'
Private Property Get ICADdyAddIn_CLSID() As String
Dim hr As Long
Dim pCLSID As Long
Dim strCLSID As String * 255
Dim pGUID As GUID
Dim strProgID As String
strProgID = "CADdyAddIn.AddIn4"
hr = CLSIDFromProgID(StrPtr(strProgID), pGUID)
hr = StringFromCLSID(pGUID, pCLSID)
StringFromPointer pCLSID, strCLSID
ICADdyAddIn_CLSID = strCLSID
End Property
'
'
' An utility method which returns the AddIn's ProgID
'
'
Private Property Get ICADdyAddIn_ProgId() As String
ICADdyAddIn_ProgId = "CADdyAddIn.AddIn4"
End Property
'
'
' An utility method which returns the AddIn's Description
'
'
Private Property Get ICADdyAddIn_Description() As String
ICADdyAddIn_Description = "DLL(Visual Basic 6) AddIn4"
End Property
'
'
' An utility method which returns the String from the given Pointer
'
'
Private Sub StringFromPointer(pOLESTR As Long, strOut As String)
Dim ByteArray(255) As Byte
Dim intTemp As Integer
Dim intCount As Integer
Dim i As Integer
intTemp = 1
While intTemp <> 0
CopyMemory intTemp, ByVal pOLESTR + i, 2
ByteArray(intCount) = intTemp
intCount = intCount + 1
i = i + 2
Wend
CopyMemory ByVal strOut, ByteArray(0), intCount
End Sub
More information about the Python-win32
mailing list