Re: [comtypes-users] Getting AddressOfMember working?
Am 17.05.2014 21:20, schrieb Will Dormann: Hi folks, I'm interested in using comtypes to get the actual addresses of method/property names in a COM object. In typeinfo.py, I've commented out the following line: #raise Check Me Using test_typeinfo.py as a starting point, I've got a script that attempts to use AddressOfMember in the following way: address = ti.AddressOfMember(fd.memid, fd.invkind) This results in the following error: Traceback (most recent call last): File C:\ax.py, line 31, in module address = ti.AddressOfMember(fd.memid, fd.invkind) File C:\Python27\lib\site-packages\comtypes-1.0.0-py2.7.egg\comtypes\typeinfo.py, line 316, in AddressOfMember self.__com_AddressOfMember(memid, invkind, byref(p)) _ctypes.COMError: (-2147317571, 'Wrong module kind for the operation.', (None, None, None, 0, None)) The best info I could find online is this: http://forums.codeguru.com/showthread.php?497293-Why-Exception-occured-getting-address-of-COM-function but there's no answer. MSDN says in http://msdn.microsoft.com/en-us/library/windows/desktop/ms221544%28v=vs.85%29.aspx: Retrieves the addresses of static functions or variables, such as those defined in a DLL. This seems to suggest that ITypeInfo::GetAddressOfMember works only for static functions or static variables, but not for methods of COM object. Thomas -- Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE Instantly run your Selenium tests across 300+ browser/OS combos. Get unparalleled scalability from the best Selenium testing platform available Simple to use. Nothing to install. Get started now for free. http://p.sf.net/sfu/SauceLabs ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Getting AddressOfMember working?
Am 19.05.2014 16:31, schrieb Will Dormann: On 5/19/14, 10:29 AM, Thomas Heller wrote: Am 19.05.2014 14:13, schrieb Will Dormann: P.S.Do you have any idea on how I might be able to get the address of a method or property of a COM object?Or is that outside the scope of comtypes? Why do you need the address? What do you want to do with it? This info is quite valuable for reverse engineering. e.g. if a COM object exposes a function foo(), then where in the module is the actual code to handle foo()? comtypes doesn't expose the address of the methods directly. However, with some advanced ctypes-wizardry you should be able to find out. Nevertheless I cannot help you with this. Thomas -- Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE Instantly run your Selenium tests across 300+ browser/OS combos. Get unparalleled scalability from the best Selenium testing platform available Simple to use. Nothing to install. Get started now for free. http://p.sf.net/sfu/SauceLabs ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] comtypes and the GIL
Am 27.08.2013 21:39, schrieb Uri Cohen: I use comtypes.automation to access an IDispatch object in an out-of-process server and it seems to me as if the GIL is not unlocked during the call. Thus when trying to invoke multiple calls on IDispatch objects the calls are synchronized by the GIL and all calls block if one of the server's methods blocks. I tried to figure myself how the GIL is handled by comtypes, but this seems to hidden somewhere down the layers in the ctypes implementation. Does my problem make sense and it is a known issue with the GIL? Or should I look harder for some other cause for my calls being synchronized? I think there should be another source of your problem. comtypes/ctypes always releases the GIL when calling or executing C-code. Thomas -- Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more! Discover the easy way to master current and previous Microsoft technologies and advance your career. Get an incredible 1,500+ hours of step-by-step tutorial videos with LearnDevNow. Subscribe today and save! http://pubads.g.doubleclick.net/gampad/clk?id=58040911iu=/4140/ostg.clktrk ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] REGCLS_MULTIPLEUSE not working for local servers on Windows 8?
Am 19.03.2013 00:12, schrieb Alicia Chen: I tried a similar setup with a sample C++ server/client and it works fine. I haven't yet managed to determine what the differences are. Can anyone shed some light on this? Alicia, I have not yet used comtypes on Windows 8. Currently downloading win8 from my MSDN subscription... Thomas On Fri, Mar 15, 2013 at 3:49 PM, Alicia Chen owlishn...@gmail.com mailto:owlishn...@gmail.com wrote: We pass REGCLS_MULTIPLEUSE as the flag for an out-of-proc server. This worked fine on Windows 7, but Windows 8 seems to ignore this flag and attempts to launch a new instance for any call other than the first. I tested this with the sample code given here http://starship.python.net/crew/theller/comtypes/server.html with only a slight modification, changing the server so that it stays running and continually processes calls, to emulate what our program does. while True: comtypes.server.localserver.run([MyObjectImpl]) On Win7, if you launch the server, you can run the client multiple times and the calls will always go to the running instance of the server. On Win8, the first client call behaves as expected, but all subsequent calls cause a new instance of the server to be launched, and CreateObject eventually fails with the following error: Creating MyObject object now! Traceback (most recent call last): File tools\sample_com_obj\sample_client.py, line 13, in module x = CreateObject(MyTypelib.MyObject) File \comtypes\client\__init__.py, line 235, in CreateObject obj = comtypes.CoCreateInstance(clsid, clsctx=clsctx, interface=interface) File \comtypes\__init__.py, line 1145, in CoCreateInstance _ole32.CoCreateInstance(byref(clsid), punkouter, clsctx, byref(iid), byref(p)) File _ctypes/callproc.c, line 936, in GetResult WindowsError: [Error -2146959355 tel:2146959355] Server execution failed (That error number is 0x80080005 for marginally more readability) Both server and client files attached for your reference. Is anyone else experiencing this? Am I doing something horribly wrong? --Alicia -- Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_mar ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users -- Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_mar ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Supporting Component Categories (Patch provided)
Jan, and others, my apologies. I don't have time to support comtypes any longer (apart that I may, from time to time, answer some easy or even interesting questions on this mailing list). I don't even have a machine setup so that I can connect to the sourceforge SVN server, so I cannot commit patches any more. (If someone wants to take over the project, that would be great). Thomas Am 17.04.2012 10:31, schrieb Jan Wedel: Hi, Ive patched comtypes to support COM categories. In my case, an OPC client requires categories. It checks the registry for supported categories and if not one category is found, it will not support interaction with the server even if the server has implemented and published all required interfaces. An object can publish its supported categories which are represented by an registry entry. Ive changed the comtypes\server\register.py and added a few lines (see diff below). I'm not sure if I used the registry functions correctly, but it works for me. Using the following code, you can add a new attribute _reg_catids_ to your python COM class which should be a list of GUID strings: class MyComServer(CoClass): (...) _reg_catids_ = [ '{ FIRST CATID }', '{ SECOND CATID }', ] (..) This is probably not the most flexible way to do it (it may support e.g. interface objects instead of strings), but for me it works perfectly. It would be nice if this could be added to comtypes trunk. This is the diff: --- C:/Python26/Lib/site-packages/comtypes/server/register.py.old Mi Aug 19 22:17:08 2009 +++ C:/Python26/Lib/site-packages/comtypes/server/register.py Di Apr 17 10:17:47 2012 @@ -296,6 +296,12 @@ append(HKCR, CLSID\\%s\\LocalServer32 % reg_clsid, , %s %s % (exe, script)) else: append(HKCR, CLSID\\%s\\LocalServer32 % reg_clsid, , %s % exe) + +reg_catids = getattr(cls, _reg_catids_, None) +if reg_catids is not None: +append(HKCR, CLSID\\%s\\Implemented Categories % reg_clsid, , ) +for cat_id in reg_catids: +append(HKCR, CLSID\\%s\\Implemented Categories\\%s % (reg_clsid, cat_id), , ) # Register InprocServer32 only when run from script or from # py2exe dll server, not from py2exe exe server. -- Better than sec? Nothing is better than sec when it comes to monitoring Big Data applications. Try Boundary one-second resolution app monitoring today. Free. http://p.sf.net/sfu/Boundary-dev2dev -- For Developers, A Lot Can Happen In A Second. Boundary is the first to Know...and Tell You. Monitor Your Applications in Ultra-Fine Resolution. Try it FREE! http://p.sf.net/sfu/Boundary-d2dvs2 ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Using a COMObject from a client more than once
James Teh schrieb: Hi. In our project, we communicate with Microsoft SAPI 4 speech synthesisers using COM. When we want to speak data, we must provide an object which can receive events. (The IConnectionPoint* interfaces are not used.) Following is a rough, very simplified outline of the code: class SynthDriverBufSink(COMObject): _com_interfaces_ = [ITTSBufNotifySink] ... class SynthDriver(object): def __init__(self): self._ttsCentral = ... self._bufSink=SynthDriverBufSink() ... def performSpeak(self, text): ... self._ttsCentral.TextData(..., text, self._bufSink, ITTSBufNotifySink._iid_) _ttsCentral.TextData accepts a pointer to IUnknown (this is defined in its interface), as well as the iid of the ITTSBufNotifySink interface. The issue is that self._bufSink is created at instantiation, but is used in many calls to performSpeak. In comtypes 0.6.1, this was fine. However, in 0.6.2, when the ref count of a COMObject hits 0, the _com_pointers_ dict gets cleared to avoid a memory leak (svn r544). This means that the first call to performSpeak is fine. However, after this call completes, the ref count on self._bufSink will drop to 0, _com_pointers_ will be cleared and subsequent calls will fail to get the appropriate pointer. James, I agree with you that this is a problem. I'm looking into it but it seems to take langer than expected. We've fixed this by never holding the underlying COMObject. In the constructor, we do: self._bufSink=SynthDriverBufSink().QueryInterface(ITTSBufNotifySink) This way, the pointer will AddRef and keep the underlying COMObject alive and will Release it when the pointer gets garbage collected. Despite the solution, this raises the question: Are we supposed to never maintain a long-lasting reference to an underlying COMObject? That is, was it always intended that a COMObject should never be held directly? No, it was not intended to be this way. In C++, one usually has the ref count start at 1, rather than 0. I understand this would present challenges in Python, as you don't know when to clean up the object. However, it'd be good to have some policy documentation on this scenario. A possible solution would be to change the COMObject.IUnknown_QueryInterface() and COMObject.QueryInterface() methods so that they call __prepare_comobject() again when they find an empty _com_pointers_ dictionary. In this way the object can be used again even after the refcount has dropped to zero. Jamie -- Thanks, Thomas -- SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW http://p.sf.net/sfu/solaris-dev2dev ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Problem calling method
Here is a patch for comtypes that will pass byref(...) or pointer(...) arguments as VT_BYREF variants. It should workfor Pablos and Michaels use cases - also it demonstrates how to access the original object of a byref(..) call: Index: comtypes/automation.py === --- comtypes/automation.py (revision 564) +++ comtypes/automation.py (working copy) @@ -1,5 +1,6 @@ # comtypes.automation module from ctypes import * +from ctypes import _Pointer from _ctypes import CopyComPointer from comtypes import IUnknown, GUID, IID, STDMETHOD, BSTR, COMMETHOD, COMError from comtypes.hresult import * @@ -48,6 +49,7 @@ # helpers IID_NULL = GUID() riid_null = byref(IID_NULL) +_byref_type = type(byref(c_int())) # 30. December 1899, midnight. For VT_DATE. _com_null_date = datetime.datetime(1899, 12, 30, 0, 0, 0) @@ -296,6 +298,16 @@ elif isinstance(value, c_float): self.vt = VT_R4 self._.VT_R4 = value +elif isinstance(value, _byref_type): +ref = value._obj +self._.c_void_p = addressof(ref) +self.__keepref = value +self.vt = _ctype_to_vartype[type(ref)] | VT_BYREF +elif isinstance(value, _Pointer): +ref = value.contents +self._.c_void_p = addressof(ref) +self.__keepref = value +self.vt = _ctype_to_vartype[type(ref)] | VT_BYREF else: raise TypeError(Cannot put %r in VARIANT % value) # buffer - SAFEARRAY of VT_UI1 ? -- Thanks, Thomas -- SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW http://p.sf.net/sfu/solaris-dev2dev ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Problem calling method
Am 11.02.2010 02:32, schrieb Pablo Bianucci: [...] From the documentation of this control, I get this prototype (I don't know if that's the right name): --- Function GetControlMode(lChanID As Long, plMode As Long) As Long Parameters lChanID - the channel identifier plMode - returns the control loop feedback status --- I found this other funcion, that seems similar and has a code example: --- Function GetMaxTravel(lChanID As Long, plMaxTravel As Long) As Long Parameters lChanID - the channel identifier plMaxTravel - returns the maximum travel (in microns) Example: Private Sub cmdGetTravel_Click() Dim sngMaxTravel As Single MG17Piezo1.GetMaxTravel CHAN1_ID, sngMaxTravel ' inform user of piezo max travel MsgBox Maximum travel of piezo = sngMaxTravel --- Does this help? Well, what you could try out are these code snippets in Python: snip chanid = 42 # or whatever this needs to be... print ptr.GetControlMode(chanid) # try to leave out the plMode parameter print ptr.GetControlMode(chanid, 0) # pass a number for plMode... print ptr.GetMaxTravle(chanid) print ptr.GetMaxTravel(chanid, 0) /snip If nonthing of the above works, I guess you would have to pass the second parameter by reference. The basic code would have to look something like this; it is basically what I assume that VB does: snip # create a variable containing the 'control loop feedback status', # initialized to some value mode = c_int(0) # Call the function, passing the VALUE of chanid, # and a REFERENCE to the 'mode' variable. print ptr.GetControlMode(chanid, pass_by_reference(mode)) # The result of the function call should now have been printed, # and the 'mode' variable should contain an updated value: print mode.value /snip Ok, but what is this pass_by_reference() function? It should take the argument (a ctypes c_int instance, for example), and convert to something that will eventually, in the Invoke call, used as BYREF VARIANT argument. I'll try to come up with some ideas for that if the first code snippet above really fails. However, it could be that comtypes is not able to call this method... I hope not! (crossing fingers... :-)) We'll see. -- Thanks, Thomas -- SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW http://p.sf.net/sfu/solaris-dev2dev ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Problem calling method
Am 12.02.2010 20:24, schrieb Pablo Bianucci: Hi Thomas! On Fri, 12 Feb 2010, Pablo Bianucci wrote: Exception: Cannot put cparam 'P' (012D7468) in VARIANT The problem seems to be that the initialization of VARIANT does not know what to do with a pointer type. I think that VARIANT could be extended to handle those: Get the value of the pointer (no the contents but the actual address), store that as the content of the VARIANT instance and then set the VT_BYREF flag. Do you think that would work? Exactly. I cannot provide a patch, but here's a code snippet that creates such a beast: from comtypes.automation import * mode = c_int(42) # our variable v = VARIANT() v._.c_void_p = cast(pointer(mode), c_void_p) v.vt = VT_BYREF | VT_I4 print v # prints 'VARIANT(vt=0x4003, byref(42))' You could use this stuff and pass it to Invoke. I assume that is will be changed after the call. Pretty straightforward to retrieve the result; VARIANT contains code for that. Since the VARIANT is a kind of pointer, I have chosen the indexing to acces the contained value: print v # prints 'VARIANT(vt=0x4003, byref(42))' print v[0] # prints '42' What I don't see how to do is how to get the address pointed to as a plain number. cast does that for you, without worring about the actual address. -- Thanks, Thomas -- SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW http://p.sf.net/sfu/solaris-dev2dev ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Problem calling method
Am 30.01.2010 06:23, schrieb Pablo Bianucci: Hi! I am trying to use an ActiveX control (.OCX, from a piezo electric stage controller)) from a Python program. I have managed to get the control to work, but I am having problems calling a method. This is the method in question (from the autogenerated typelib): === DISPMETHOD([dispid(20)], c_int, 'GetControlMode', ( [], c_int, 'lChanID' ), ( [], POINTER(c_int), 'plMode' )), === This is what I am doing trying to use the method (it should give me an integer): === mode = 0 mode_ptr = cast(mode, POINTER(c_int)) What you are doing here is that you create a NULL pointer - which is probably not what you want. But see below. try: piezo1.GetControlMode(APTPiezoLib.CHAN1_ID, mode_ptr) except Exception, e: print Exception:, e === And I get: === Exception: Cannot put comtypes._safearray.LP_c_long object at 0x012D9440 in VARIANT ===i I have no previous experience with comtypes or ctypes (or Win32 programming, for that matter ;-)), so I might be doing something stupidly wrong. I've tried all the permutations I could think of already, so I need expert help. Ok, the interface that you have is a pure dispinterface, which means that all methods of the COM object are eventually called as IDispatch.Invoke() calls. The Invoke() method packs all parameters into a DISPPARAM structure which basically is an array of VARIANT instances. This explains the error that you get - comtypes is trying to pack the POINTER parameter that you have created into a VARIANT. This only works for 'automation-compatible' data types and your pointer is not one of those. I would guess that the 'mode_ptr' argument is an argument that must be passed by reference (this is visual basic speak). Do you have sample VB code that shows how this method is used? However, it could be that comtypes is not able to call this method... Thomas -- SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW http://p.sf.net/sfu/solaris-dev2dev ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] SafeArray of pointers to variant
serge.weinst...@barclayscapital.com schrieb: Hi Thomas, Looking at the MSDN documentation for SafeArrayCreate (http://msdn.microsoft.com/en-us/library/ms893380.aspx), I've found that: Neither VT_ARRAY nor the VT_BYREF flag can be set whatever the referenced type. Yes, but the docs for SafeArrayCreateEx or SafeArrayCreateVectorEx do NOT have such a notice. Whatever that means. After discussion, I've found that it's a mistake in the IDL, it should have been SAFEARRAY(VARIANT) and not SAFEARRAY(VARIANT*). Unfortunatly, I can't change the existing code. In fact, I don't need to use this particular object but I need to use other objects defined in the same type library. The problem is that when I try to import the type library with comtypes.client.GetModule, an exception is thrown when processing this particular method. Is there a way to get around it? Maybe by interpreting SAFEARRAY(VARIANT*) as SAFEARRAY(VARIANT)? An easy fix is to insert this line POINTER(VARIANT): VT_BYREF|VT_VARIANT, into the definition of the _ctype_to_vartype dictionary, at the end of the comtypes\automation.py module. This will let you import the typelib, but you will get an error if you want to call a method that uses such an argument type. Thomas -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] SafeArray of pointers to variant
Thomas Heller schrieb: serge.weinst...@barclayscapital.com schrieb: Hi, I'm trying to import a COM type library with the statement comtypes.client.GetModule(({09022755-93B0-4BA8-9593-AC74E4C6EABB}, 1, 0)) The module is correctly generated but when imported, I got an exception on: class NamedCommandSession(comtypes.gen._00020430___C000_0046_0 _2_0.IUnknown): _case_insensitive_ = True u'Named command session interface.' _iid_ = GUID('{44D908E9-7600-4C9D-ADE7-917D59EEA175}') _idlflags_ = ['oleautomation'] NamedCommandSession._methods_ = [ COMMETHOD([], HRESULT, 'Execute', ( ['in'], BSTR, 'commandName' ), ( ['in'], _midlSAFEARRAY(BSTR), 'paramNames' ), ( ['in'], _midlSAFEARRAY(POINTER(VARIANT)), 'paramValues' ), ( ['retval', 'out'], POINTER(BSTR), 'ppResult' )), ] The method midlSAFEARRAY doesn't handle the safearray with elements of type POINTER(VARIANT). Is there a quick fix for that? I hacked around a little, but failed to create such a safearray. I assume the typecode is VT_BYREF|VT_VARIANT, but calling SafeArrayCreateVectorEx(VT_BYREF|VT_VARIANT, 0, 42, NULL) returns zero (= failure). Do you have some C-example code? Do you want to use this very method in your call? If you only want to call OTHER methods then there are quick hacks around this problem... -- Thanks, Thomas -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] SafeArray of pointers to variant
serge.weinst...@barclayscapital.com schrieb: Hi, I'm trying to import a COM type library with the statement comtypes.client.GetModule(({09022755-93B0-4BA8-9593-AC74E4C6EABB}, 1, 0)) The module is correctly generated but when imported, I got an exception on: class NamedCommandSession(comtypes.gen._00020430___C000_0046_0 _2_0.IUnknown): _case_insensitive_ = True u'Named command session interface.' _iid_ = GUID('{44D908E9-7600-4C9D-ADE7-917D59EEA175}') _idlflags_ = ['oleautomation'] NamedCommandSession._methods_ = [ COMMETHOD([], HRESULT, 'Execute', ( ['in'], BSTR, 'commandName' ), ( ['in'], _midlSAFEARRAY(BSTR), 'paramNames' ), ( ['in'], _midlSAFEARRAY(POINTER(VARIANT)), 'paramValues' ), ( ['retval', 'out'], POINTER(BSTR), 'ppResult' )), ] The method midlSAFEARRAY doesn't handle the safearray with elements of type POINTER(VARIANT). Is there a quick fix for that? I hacked around a little, but failed to create such a safearray. I assume the typecode is VT_BYREF|VT_VARIANT, but calling SafeArrayCreateVectorEx(VT_BYREF|VT_VARIANT, 0, 42, NULL) returns zero (= failure). Do you have some C-example code? -- Thanks, Thomas -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Methods with ['in,'out'] and ['retval','out']
px schrieb: Hi All, We are trying to make a call to a method which has the following COMMETHOD definition: COMMETHOD([dispid(13), helpstring(u'method PopMessage')], HRESULT, 'PopMessage', ( ['in', 'out'], POINTER(AACDMAMessageEnum), 'MessageType' ), ( ['in', 'out'], POINTER(AAProtocolEnum), 'Protocol' ), ( ['in', 'out'], POINTER(c_int), 'PN' ), ( ['in', 'out'], POINTER(c_int), 'CDMAChannel' ), ( ['in', 'out'], POINTER(AACodeChannelEnum), 'CodeChannel' ), ( ['in', 'out'], POINTER(BSTR), 'TimeStamp' ), ( ['in', 'out'], POINTER(BSTR), 'Description' ), ( ['retval', 'out'], POINTER(POINTER(ICDMAMessage)), 'Message' )), What we are finding is that the return result is a tuple, however the POINTER(POINTER(ICDMAMessage)) parameter is missing from the returned tuple. All other elements are there. Now if I modify the definition and change the ['retval', 'out'] to a ['in', 'out'] then it works nicely and all items are returned in the tuple. Yes, this is a complicated bug in ctypes. ctypes provides the machinery for calling the COM methods that comtypes uses. The bug is difficult to understand and to fix. Hopefully I find the time for a bugfix or (another) workaround. I'll post here when I have one. Is this a bug with comtypes? The call we are doing is simply PopMessage(). I guess there is some ambiguity here, would passing pointers for each IN attribute make comtypes return Message alone? Passing pointers for the IN parameters does not change the behaviour of the OUT parameter. Your hack - changing the paremeter flags of the generated code is the easiest and best you can do at the moment. The behaviour with win32com is that Message is returned as the 1st item of the tuple, and the rest follow. Hm, I didn't know that win32com returns the results in that order (it makes some sense if I think of it). comtypes returns the results in the same order as they appear in the method definition, and does not reorder depending on the 'retval' attribute. It is too late to change that. -- Thanks for the heads-up, Thomas -- Come build with us! The BlackBerryreg; Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9#45;12, 2009. Register now#33; http://p.sf.net/sfu/devconf ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] SAPI5 and ShowEvents
Peter Parente schrieb: Hi, I'm trying to use the SAPI5 SPVoice interface through comtypes, but I don't seem to be getting any events. I instantiate the interface like so and call ShowEvents import comtypes.client tts = comtypes.client.CreateObject('SAPI.SPVoice') advise = comtypes.client.ShowEvents(tts) The ShowEvents call gives me the following list: # event found: _ISpeechVoiceEvents_StartStream # event found: _ISpeechVoiceEvents_EndStream # event found: _ISpeechVoiceEvents_VoiceChange # event found: _ISpeechVoiceEvents_Bookmark # event found: _ISpeechVoiceEvents_Word # event found: _ISpeechVoiceEvents_Sentence # event found: _ISpeechVoiceEvents_Phoneme # event found: _ISpeechVoiceEvents_Viseme # event found: _ISpeechVoiceEvents_AudioLevel # event found: _ISpeechVoiceEvents_EnginePrivate When I invoke the speak() method on the tts object, I believe I should see some of these events (word, sentence, etc.) once I enter a message loop. However, I see nothing printed: tts.speak('The quick brown fox jumps over the lazy dog.') comtypes.client.PumpEvents(10) I also tried passing my own class with callback methods named _ISpeechVoiceEvents_StartStream and so forth to GetEvents, but still, none of the callbacks get invoked. Has this worked in other versions of comtypes, or did you try for the first time? -- Thanks, Thomas -- Come build with us! The BlackBerryreg; Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9#45;12, 2009. Register now#33; http://p.sf.net/sfu/devconf ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] __del__ called more than once on a comtypes COM POINTER object
James Teh schrieb: Hi Thomas, In NVDA, we sometimes see access violation and vtable errors in __del__ on comtypes COM POINTER objects and intermittant crashes. I eventually figured that this might relate to Release() being called too many times. I then discovered that __del__ on these objects is sometimes called more than once. (We never call __del__ ourselves, so this is happening elsewhere.) As I understand it, Python should only ever call it once. Well, __del__ could revive the object, but comtypes doesn't do this afaik. I discovered this using the following rather nasty monkey patch before any COM objects are used: from comtypes import _compointer_base _cpbDel = _compointer_base.__del__ def newCpbDel(self): assert not hasattr(self, _deleted), compointer already deleted _cpbDel(self) self._deleted = True newCpbDel.__name__ = __del__ _compointer_base.__del__ = newCpbDel del _compointer_base This assertion does get raised. While I have come up with an exact set of steps to reproduce with NVDA and Firefox, I haven't yet managed to narrow it down to a programmatic test case due to the sheer number of interactions and code paths. I can tell you that we use QueryInterface quite a bit if that helps in any way. Can you think of any reason this might be happening? Is there any code in the ctypes POINTER type that calls __del__? No, and no. It would be great if you can provide some code that has this problem. -- Thanks, Thomas -- Come build with us! The BlackBerryreg; Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9#45;12, 2009. Register now#33; http://p.sf.net/sfu/devconf ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] comtypes and safearray of structs as out parameter
So it seems the easiest way to pass this parameter to 'create(...)' is this simple patch: (...) I've tried your approach and it works. You're right, your solution is better, I did not see that the extra variable was bound in the _make_safearray_type closure. Ok, I'll commit it into the repository and add some unittests for it. PS: Thinking about the code I'm wondering why I didn't use the outer definition of 'extra' in the create(...) method directly instead of passing it as a parameter... That could be another solution, to remove the 'extra' parameter from create (though I don't know whether someone may already be using it and this could break that code). Another one could be renaming the 'extra' parameter in create, and assign the bound 'extra' variable if None is provided as an argument (or filled in by the default value). I'll leave this as it is to not break existing code. -- Thanks, Thomas -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] comtypes and safearray of structs as out parameter
Eduardo Arias schrieb: I've come into a problem when trying to implement an interface that has a single out parameter which happens to be a safearray of structs/VT_RECORD. I've been able to find a workaround to what looks like a limitation, which I'm submitting for your review. The interface I need to implement in Python receives a safearray of a Pair structs (defined below) and has a single out parameter which also provides a safearray of Pair structs. [ uuid(41A8A003-C9FE-4ad8-866E-71CC5BAD0EA5) ] struct Pair { BSTR Key; BSTR Value; }; [ object, uuid(8232CB78-EEB8-4965-A275-2399F2EE497D), dual, nonextensible, helpstring(ITest Interface), pointer_default(unique) ] interface ITest : IDispatch{ [id(1), helpstring(method Test)] HRESULT Test([in] SAFEARRAY(struct Pair) in, [out] SAFEARRAY(struct Pair)* out); }; comtypes.client.GetModule generates the following code for the structure, that includes a _recordinfo_ member: [...] The generated code for the interface is: [...] The COM object that implements the interface tries to return a list of Pair objects: class Test(comtypes.COMObject): _com_interfaces_ = [test_tlb.ITest] # [id(1), helpstring(method Test)] HRESULT Test([in] SAFEARRAY(struct Pair) in, [out] SAFEARRAY(struct Pair)* out); def ITest_Test(self, in, out): l = [] l.append(test_tlb.Pair(u'1', u'2')) l.append(test_tlb.Pair(u'2', u'3')) return l This triggers the following error: Traceback (most recent call last): [...] TypeError: Cannot create SAFEARRAY type VT_RECORD without IRecordInfo. When _comobject.py tries to assign the method's return value to the single out argument: args[args_out_idx[0]][0] = result it ends up calling '__setitem__' which needs to create a saferray that contains the elements in the return value through the 'create' method: pa = self._type_.create(value) Then, because this is a safearray of structs, SafeArrayCreateVectorEx needs to receive an IRecordInfo interface to be able to allocate enough memory for the array elements: pa = _safearray.SafeArrayCreateVectorEx(cls._vartype_, 0, len(value), extra) However, as shown in the call to create, no 'extra' parameter is specified and thus the call to SafeArrayCreateVectorEx fails. I've been able to workaround the issue by trying to obtain IRecordInfo inside the 'create' method, when no extra parameter is provided. Because the function will receive an array or container of the structs to be copied into the safearray, if there is at least one element in value, we can check whether it has a '_recordinfo_' member and, if that's available, use comtypes.typeinfo.GetRecordInfoFromGuids to obtain the missing IRecordInfo for SafeArrayCreateVectorEx. The change in comtypes/safearray.py is shown below (just before the call to SafeArrayCreateVectorEx). # (...) # try to obtain IRecordInfo if it's a SAFEARRAY struct of VT_RECORD and IRecordInfo # has not been provided through 'extra'. check whether an element in value contains # _recordinfo_ and if that's the case, use comtypes.typeinfo.GetRecordInfoFromGuids # to obtain IRecordInfo if cls._vartype_ == VT_RECORD and extra is None and len(value) 0 and hasattr(value[0], '_recordinfo_'): import comtypes.typeinfo extra = comtypes.typeinfo.GetRecordInfoFromGuids(*value[0]._recordinfo_) # For VT_UNKNOWN or VT_DISPATCH, extra must be a pointer to # the GUID of the interface. # # For VT_RECORD, extra must be a pointer to an IRecordInfo # describing the record. pa = _safearray.SafeArrayCreateVectorEx(cls._vartype_, 0, len(value), extra) # (...) I'd like to know whether you think this approach is ok, or if there's any other way I'd have been able to have an out parameter provide a safearray of structs/VT_RECORD which doesn't require this change. Eduardo, thanks for the detailed analysis and the clear explanation. I've been looking at the code and probably have another, even better, approach. The missing 'extra' parameter in the create(cls, value, extra=None) implementaition in comtypes\safearray.py, line 62, that you retrieve from the 'value' parameter is defined in an outer scope of
Re: [comtypes-users] Change typelib dynamically?
px schrieb: Hi there, Is there a way I can change a generated typelib dynamically without having to modify the generated .py file itself? (ie. the files generated in C:\Python25\Lib\site-packages\comtypes\gen). No, not really. The _methods_ list is processed when the class is created, later changes to _methods_ have no effect. The processing occurrs in _cominterface_meta._make_methods_, in comtypes\__init__.py line 608. In principle, you could extract code from that function and change the generated COM method, but I wouldn't recommend that. Can't you modify the generated file and be done? Must it be regenerated more than once? In particular I just want to change the signature of one of the methods. I tried this: import comtypes.gen.MyLib as MyLib MyLib.Channel._methods_[3] = comtypes.COMMETHOD([], HRESULT, 'ReadPacket', ( ['in'], POINTER(c_ubyte), 'data' ), ( ['in'], c_int, 'length' ), ( ['out'], POINTER(c_int), 'actual' )) But it seems like comtypes doesn't see or register this change. Although if I print MyLib.Channel._methods_[3] I see it is changed accordingly. Of course if I make this change in the typelib file directly it works. Another approach would be that you write a new implementation of the ReadPacket function, and assign that to the class before you are using it, like so: import comtypes.gen.MyLib as MyLib def MyReadPacket(self, ...): MyLib.Channel.ReadPacket = MyReadPacket Would that work? -- Thanks, Thomas -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Installer error message - does it matter ?
comty...@richardshea.fastmail.fm schrieb: Hi - I've just used comtypes-0.6.1.win32.exe to install comtypes to Python 2.6 on Windows Vista 32 bit. The installer displays an error message on the last panel that reads : Traceback (most recent call last): File string, line 2, in module File C:\bin\installed\Python2.6\Lib\ctypes\__init__.py, line 10, in module from _ctypes import Union, Structure, Array ImportError: DLL load failed: The specified module could not be found. I'm not sure if this is a problem or not. comtypes is working to some extent I was just able to do this ... from comtypes.client import CreateObject xl = CreateObject(Excel.Application) xl.Visible = True print xl ... but I'd appreciate someone letting me know if I should be concerned abou this. I guess this error occurs when the installer is trying to run the postinstall script. This script asks whether any previous comtypes generated files in the comtypes\gen folder should be removed. It is recommended (but not required) to remove these files. So - you should not worry about this problem. (Well, I probably should but I cannot reproduce it). -- Thanks, Thomas -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] comtypes 0.6.1 released
Thomas Heller schrieb: Finally, I found the time to make the long overdue release: http://sourceforge.net/projects/comtypes/ comtypes 0.6.1 released. The source distribution comtypes-0.6.1.zip was missing some files (reason is that distutils creates a MANIFEST file by default but doesn't update it when modules are added). I have replaced it with a new comtypes-0.6.1-1.zip archive that should be complete. Thomas -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
[comtypes-users] comtypes 0.6.1 released
Finally, I found the time to make the long overdue release: http://sourceforge.net/projects/comtypes/ comtypes 0.6.1 released. Summary of important changes: - SAFEARRAYs can now be created from array.array objects, and from multidimensional numpy arrays. - Completely new implementation of the comtypes.server.automation.VARIANTEnumerator class. - Added comtypes.client.GetClassObject() function which returns a factory able to create COM objects. - Much improved IClassObject::CreateInstance() method. - SAFEARRAYs now support the typecodes VT_I8 and VT_UI8. - Added comtypes.IServiceProvider interface (unfortunately there is no ChangleLog entry for this one). -- Detailed changelog since version 0.6.0: 2009-08-19 Thomas Heller thel...@python.net * Bumped version number to 0.6.1. 2009-08-07 Thomas Heller thel...@python.net * When an interface was specified in the call to IClassObject.CreateInstance, return that instead of calling GetBestInterface. Patch from James Teh. 2009-08-04 Thomas Heller thel...@python.net * Added comtypes.CoGetClassObject() low-level function, comtypes.client.GetClassObject() high-level function, and implemented a pythonic interface to IClassFactory's CreateInstance method: def CreateInstance(self, punkouter=None, interface=None, dynamic=False) * Added the 'dynamic=False' parameter to the comtypes.client.CoGetObject and comtypes.client.GetActiveObject functions. Suggested by James Teh. 2009-06-17 Thomas Heller thel...@python.net * comtypes.automation: Support VT_I8 and VT_UI8 SAFEARRAYs. * comtypes._comobject: Restore compatibility with Python 2.3. * Add the comtypes.IServiceProvider interface. Based on a patch from Michael Curran. 2009-04-30 Thomas Heller thel...@python.net * Change version number in repository to 0.6.0.2dev. * Replace the VARIANTEnumerator implementation class in comtypes.server.automation with a new one which should actually be usable. * A completely new way how localserver and inproc server instances are managed: A comtypes.LocalServer or comtypes.InprocServer instance is attached to the comtypes.COMObject class at runtime. These changes keep localserver running as long as COMObject instances are alive. 2009-04-29 Thomas Heller thel...@python.net * comtypes.errorinfo.ReportException now takes an additional 'stacklevel' named argument. * Add E_OUTOFMEMORY hresult code. * Register the InprocServer32 only when running as script or py2exe dll, not when running as py2exe exe server. 2009-04-25 Thomas Heller thel...@python.net * SAFEARRAYs can now also be created from multi-dimensional numpy arrays. 2009-04-23 Thomas Heller thel...@python.net * Change version number in repository to 0.6.0.1dev. * SAFEARRAYs can now also be created from array.array objects, and from (one-dimensional) numpy arrays. This is a lot faster than creating them from Python lists or tuples, at least for large arrays. * ctypes instances like c_int, c_ubyte, and so on can now be assigned to VARIANT().value. This allows to force creation of VARIANTs with the corresponding typecodes V_I4, VT_UI1 and alike. * Accept typelibs that contain SAFEARRAY(char). 2009-03-17 Thomas Heller thel...@python.net * Fixed the return type of ITypeLib::ReleaseTLibAttr, which is documented wrongly in MSDN. The return type is void, not HRESULT. Reported to cause crashes on Windows 7. 2009-01-29 Thomas Heller thel...@python.net * Restore compatibility with Python 2.3. * comtypes\client\_code_cache.py: Add missing 'import types' in comtypes\client\_code_cache.py. -- Enjoy, Thomas -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] New release?
James Teh schrieb: Hi Thomas, Any chance of a release some time soon? We're going to make a release of our software (NVDA) within the next few months, which uses comtypes heavily, and it'd be great to have some of the cool stuff in trunk (IServiceProvider, GetActiveObject with dynamic parameter, CoCreateInstance, etc.) in our new release. If there are other changes pending before you're willing to make a release, I understand, but thought I'd ask anyway. Jamie I promise to make a new release within the next 7 days. -- Thanks, Thomas -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] comtypes.server.IClassFactory.CreateInstance
James Teh schrieb: On 5/08/2009 5:55 AM, Thomas Heller wrote: So, I have now in svn implemented the following: - Fixed the IClassFactory::CreateInstance method - Implemented a Pythonic interface for it, also including the nice 'dynamic=False' parameter. This is (almost) what I was looking for. Thanks! However, there is one issue. Currently, CreateInstance always tries to return the best interface, even if the interface was explicitly specified. In my case, I want a specific interface, but due to the fact that the typelib is not registered on the system, comtypes ends up returning a dispatch, which is not what I want. I've attached a patch against svn trunk to fix this. Sure. The patch has been applied; thanks. -- Thanks, Thomas -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] comtypes.server.IClassFactory.CreateInstance
James Teh schrieb: Hi all, I've had cause to instantiate a COM class which is not registered on the system. To do this, one uses DllGetClassObject on the dll and then calls CreateInstance on the resulting IClassFactory. IClassFactory::CreateInstance is defined as: HRESULT CreateInstance( [in] IUnknown *pUnkOuter, [in] REFIID riid, [out] void **ppvObject ); However, in comtypes.server.IClassFactory, CreateInstance is defined as follows: _methods_ = [ comtypes.STDMETHOD(comtypes.HRESULT, CreateInstance, [ctypes.c_int, ctypes.POINTER(comtypes.GUID), ctypes.POINTER(ctypes.c_ulong)]), ... The final parameter being declared as c_ulong makes life a little painful. In order to use it, you have to do something like: instance = ctypes.c_ulong() factory.CreateInstance(0, interface._iid_, ctypes.byref(instance)) instance = ctypes.POINTER(interface)(instance.value) First of all, is there a reason that last parameter is c_ulong instead of c_void_p or the like? I do not remember the details, but it looks strange. And the first parameter type is also wrong, it should be a pointer. Second, is there any chance we could make this more Pythonic like the recent IServiceProvider.QueryInterface? Something like: instance = factory.CreateInstance(interface=interface) I'm curious as to how frequently this is already used, as such a change would break existing usage. I don't think anyone was using the IClassFactory::CreateInstance method, otherwise I think I've heard this complaint earlier. So, I have now in svn implemented the following: - Fixed the IClassFactory::CreateInstance method - Implemented a Pythonic interface for it, also including the nice 'dynamic=False' parameter. - Implemented a low-level comtypes.CoGetClassObject() function, and a high level comtypes.client.GetClassObject() Please have a look at it and report your observations. -- Thanks, Thomas -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] How to implement COM interface properly
px schrieb: Thanks Thomas! This was very helpful indeed. Working great now :) Came across another problem trying to read back an unsigned byte buffer.. I'm pretty stumped #COMMETHOD([], HRESULT, 'Read', # ( ['out'], POINTER(c_ubyte), 'data' ), # ( ['in'], c_int, 'len' ), # ( ['out'], POINTER(c_int), 'actual' )), When I call Read(2048), I always just get 13 back for the data field (first element in returned tuple) but I actually expect more bytes. I took a shot at doing a ctypes style call, but when I try to make the call x.Read(byref(data), len, byref(actual)) I get TypeError: call takes exactly 2 arguments (4 given) It seems that comtypes only wants the in 'len' parameter. From the IDL: HRESULT Read( [out, size_is(length), length_is(*actual)] BYTE* data, [in] long length, [out] long* actual); comtypes isn't able to handle the 'length_is(...)' attribute. Besides, the info from this attribute isn't present in the TLB at all. So, you should override the generated 'Read' method in this way, which passes the pointer as 'in' argument, and later unpacks it: COMMETHOD([], HRESULT, 'Read', ( ['in'], POINTER(c_ubyte), 'data' ), ( ['in'], c_int, 'len' ), ( ['out'], POINTER(c_int), 'actual' )), ...] def Read(self, len): data = POINTER(c_ubyte)() actual = self._Read(byref(data), len) result = data[:actual] # I guess you need to free the memory here? # windll.ole32.CoTaskMemFree(data) return result Thomas -- Crystal Reports - New Free Runtime and 30 Day Trial Check out the new simplified licensing option that enables unlimited royalty-free distribution of the report engine for externally facing server and web deployment. http://p.sf.net/sfu/businessobjects ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] COM Server failure on x64 vista
Michael Eddington schrieb: Hello, I'm running python v2.6 amd64 on Vista x64. I've compiled the latest ctypes and comtypes (0.6) using Visual Studio 2008. Does your code work on 32-bit Vista? I'm afraid comtypes (and ctypes) isn't tested very good on 64-bit Windows... -- Thanks, Thomas -- Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT is a gathering of tech-side developers brand creativity professionals. Meet the minds behind Google Creative Lab, Visual Complexity, Processing, iPhoneDevCamp as they present alongside digital heavyweights like Barbarian Group, R/GA, Big Spaceship. http://p.sf.net/sfu/creativitycat-com ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] comtypes CreateObject problem
Reinhammar Maria schrieb: Great! Now the app starts. The interface to the app appears somewhat different from when we use win32all though. We have to investigate that to see what it means so no complaints so far! Thanks!//Maria This change is now in the repository, so the next release will contain it. -Ursprungligt meddelande- Från: Thomas Heller [mailto:thel...@ctypes.org] Skickat: den 3 april 2009 14:37 Till: comtypes-users@lists.sourceforge.net Ämne: Re: [comtypes-users] comtypes CreateObject problem Reinhammar Maria schrieb: We get the following, less favourable response :o( Any advice is greatly appreciated!! Setting is python 2.5.2, windows xp professional SP3, SolidEdge V20 SP10, comtypes 0.6 We have great success with comtypes interfacing other software like SmarTeam (PDM/PLM software) and of course Excel and alike. :o) Thnx IDLE 1.2.2 import comtypes.client foo = comtypes.client.CreateObject(SolidEdge.Application) # Generating comtypes.gen._8A7EFA3A_F000_11D1_BDFC_080036B4D502_0_1_0 # Generating comtypes.gen._00020430___C000_0046_0_2_0 # Generating comtypes.gen.stdole [...] sa_type = _make_safearray_type(itemtype) File C:\Python25\lib\site-packages\comtypes\safearray.py, line 52, in _make_safearray_type raise TypeError(itemtype) TypeError: class 'ctypes.c_char' Please try this patch: Index: comtypes/automation.py === --- comtypes/automation.py(revision 493) +++ comtypes/automation.py(working copy) @@ -747,6 +747,7 @@ _vartype_to_ctype[v] = c _vartype_to_ctype[VT_INT] = _vartype_to_ctype[VT_I4] _vartype_to_ctype[VT_UINT] = _vartype_to_ctype[VT_UI4] +_ctype_to_vartype[c_char] = VT_UI1 try: Maria Reinhammar -- Thanks, Thomas -- -- Thanks, Thomas -- Stay on top of everything new and different, both inside and around Java (TM) technology - register by April 22, and save $200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco. 300 plus technical and hands-on sessions. Register today. Use priority code J9JMT32. http://p.sf.net/sfu/p ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] comtypes CreateObject problem
Reinhammar Maria schrieb: We get the following, less favourable response :o( Any advice is greatly appreciated!! Setting is python 2.5.2, windows xp professional SP3, SolidEdge V20 SP10, comtypes 0.6 We have great success with comtypes interfacing other software like SmarTeam (PDM/PLM software) and of course Excel and alike. :o) Thnx IDLE 1.2.2 import comtypes.client foo = comtypes.client.CreateObject(SolidEdge.Application) # Generating comtypes.gen._8A7EFA3A_F000_11D1_BDFC_080036B4D502_0_1_0 # Generating comtypes.gen._00020430___C000_0046_0_2_0 # Generating comtypes.gen.stdole Traceback (most recent call last): File pyshell#2, line 1, in module foo = comtypes.client.CreateObject(SolidEdge.Application) File C:\Python25\lib\site-packages\comtypes\client\__init__.py, line 204, in CreateObject return _manage(obj, clsid, interface=interface) File C:\Python25\lib\site-packages\comtypes\client\__init__.py, line 165, in _manage obj = GetBestInterface(obj) File C:\Python25\lib\site-packages\comtypes\client\__init__.py, line 102, in GetBestInterface mod = GetModule(tlib) File C:\Python25\lib\site-packages\comtypes\client\_generate.py, line 112, in GetModule mod = _CreateWrapper(tlib, pathname) File C:\Python25\lib\site-packages\comtypes\client\_generate.py, line 188, in _CreateWrapper mod = _my_import(fullname) File C:\Python25\lib\site-packages\comtypes\client\_generate.py, line 26, in _my_import return __import__(fullname, globals(), locals(), ['DUMMY']) File C:\Python25\lib\site-packages\comtypes\gen \_8A7EFA3A_F000_11D1_BDFC_080036B4D502_0_1_0.py, line 3393, in module ( ['in'], POINTER(_midlSAFEARRAY(c_char)), 'Accelerators' )), File C:\Python25\lib\site-packages\comtypes\safearray.py, line 18, in _midlSAFEARRAY sa_type = _make_safearray_type(itemtype) File C:\Python25\lib\site-packages\comtypes\safearray.py, line 52, in _make_safearray_type raise TypeError(itemtype) TypeError: class 'ctypes.c_char' Please try this patch: Index: comtypes/automation.py === --- comtypes/automation.py (revision 493) +++ comtypes/automation.py (working copy) @@ -747,6 +747,7 @@ _vartype_to_ctype[v] = c _vartype_to_ctype[VT_INT] = _vartype_to_ctype[VT_I4] _vartype_to_ctype[VT_UINT] = _vartype_to_ctype[VT_UI4] +_ctype_to_vartype[c_char] = VT_UI1 try: Maria Reinhammar -- Thanks, Thomas -- ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] ITypeLib::ReleaseTLibAttr definition wrong in comtypes
Michael Curran schrieb: Perhaps you can use None, I'm not sure. However, I used c_voidp, not c_void_p. c_voidp as far as I am aware means void parameter, not void pointer. c_voidp can be used in ctypes function declarations for the return type when it is void. c_void_p is void pointer. c_voidp and c_void_p is actually the very same type; which means a void pointer. If a function or method returns nothing, 'void func(...)' in C, than 'None' should be used for the .restype attribute. So the correct comtypes definition is: COMMETHOD([], None, 'ReleaseTLibAttr', (['in'], POINTER(TLIBATTR))) ] Thanks for finding it. I will correct it in svn asap. Thomas -- Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are powering Web 2.0 with engaging, cross-platform capabilities. Quickly and easily build your RIAs with Flex Builder, the Eclipse(TM)based development software that enables intelligent coding and step-through debugging. Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] pypy and the comtypes module
[I added comtypes-users to the list of recipients, in case any existing comtypes users is interested in this] Amaury Forgeot d'Arc schrieb: Hello Thomas, hello to all pypy-ers, I'm sure you will be interested to know that the ctypes implementation of pypy has matured enough to be able to run the comtypes module, at least some of the examples I found on the web site: http://starship.python.net/crew/theller/comtypes/ See the copy of a pypy session below. Really cool to hear this. I must say that I sometimes look over the commit messages in the pypy.cvs mailing list (via gmane) and I'm fascinated by the work with ctypes that is done there! What I fear is that the day is not far where you know much more than myself about ctypes ;-) Not everything works, though. For example, the COMError exception does not give any message, some errors are caused by the alternate garbage collector of pypy (opposed to the determinism of reference counting), and I'm sure that I missed many important details... At least it is now possible to run the comtypes test suite: some tests even pass ;-) Hey, I did not know that ctypes and comtypes where so intricate: ctypes obviously has features designed for comtypes only (OUT parameters...) and ctypes/__init__.py even tries to import comtypes.server.inprocserver! But this was all fun, and I learned a lot about ffi and COM from reading the code. Thanks for these wonderful modules! Python 2.5.2 (61966, Feb 17 2009, 13:39:17) [PyPy 1.0.0] on win32 Type help, copyright, credits or license for more information. And now for something completely different: ``who am I and if yes, how many?'' from comtypes.client import CreateObject xl = CreateObject(Excel.Application) # Generating comtypes.gen._00020813___C000_0046_0_1_3 # Generating comtypes.gen._00020430___C000_0046_0_2_0 # Generating comtypes.gen.stdole # Generating comtypes.gen._2DF8D04C_5BFA_101B_BDE5_00AA0044DE52_0_2_1 # Generating comtypes.gen.Office # Generating comtypes.gen._0002E157___C000_0046_0_5_3 # Generating comtypes.gen.VBIDE # Generating comtypes.gen.Excel xl.Workbooks.Add() POINTER(_Workbook) ptr=0x16af6c at 35 xl.Range(E1).Formula = =SUM(A1:D1) print xl.Range(E1).Value 0.0 xl.Range(A1, D1).Value = (Data, 10, 20, 30) print xl.Range(E1).Value 60.0 xl.Visible = True Cheers, Fantastic! I wish I had time to use pypy or even participate, but there is no chance, unfortunately. -- Thanks, Thomas -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Comtypes dynamic Dispatch and MSHTML interfaces
Michael Curran schrieb: Hi, Here is a python script that shows the problem in action. By default the script raises an error when trying to retreave the offsetTop property. However, if you uncomment the commented line just before that, then it works. Also, if using win32com.client.Dispatch instead of comtypes.client.CreateObject(...,dynamic=True) the script also works. --Script-- import comtypes.client print starting IE... , appObj=comtypes.client.CreateObject('internetExplorer.Application',dynamic=True) print appObj appObj.Visible=True print Opening URL... , appObj.Navigate('about:blank') print done print fetching text range for body... , range=appObj.Document.body.createTextRange() #range=comtypes.client.dynamic._Dispatch(range._comobj) print range print OffsetTop property: , offsetTop=range.offsetTop print %s%offsetTop --end of script -- Thanks, I'll look into it. Thomas -- This SF.net email is sponsored by: SourcForge Community SourceForge wants to tell your story. http://p.sf.net/sfu/sf-spreadtheword ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Comtypes dynamic Dispatch and MSHTML interfaces
Michael Curran schrieb: Hi, I have been using comtypes 0.6 dynamic dispatch support with the MSHTML interfaces in Internet Explorer and Outlook Express. I have noticed that for some reason, comtypes is unable to find some properties, yet win32com can. Specifically, using a text range object retreaved by IHTMLElement::createTextRange(), I can not access any properties that exist on the IHTMLTextRangeMetrics interface. The text range object supports IHTMLTxtRange and IHTMLTextRangeMetrics, I'm not sure about any other interfaces. I can access any property on the IHTMLTxtRange interface, but not IHTMLTextRangeMetrics. Michael, can you please post some example code that does not work in comtypes but does work in pywin32? I have found a temporary solution to the problem, and that is: * In clude a comtypes.client.dynamic._Dispatch instance on the comtypes.client.lazybind.Dispatch instance, called something like '_dispatch'. *inlazybind.Dispatch.__bind: catch NameError as well as comtypes.COMError when calling iTypeComp.bind. *in lazybind.Dispatch.__getattr__: if a property can not be found with __bind (descr is None), then return getattr(self._dispatch,name). This will allow the name to be fetched using GetIDsOfNames etc. This solution fixes the problem for me, and I can now access some more of the properties. I have no idea why ITypeComp.bind cannot find the properties. Interested if anyone has any idea why this might occure, or whether this solution is appropriate. -- Thanks, Thomas -- This SF.net email is sponsored by: SourcForge Community SourceForge wants to tell your story. http://p.sf.net/sfu/sf-spreadtheword ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Problem with AutoCAD
Kelie schrieb: Thomas Heller thel...@... writes: Anyway, you should NOT use 'cast' with COM object pointers. Last, but not least, 'cast' doesn't handle the COM reference count correctly. Please use 'QueryInterface' with them, like so: block = obj.QueryInterface(ACAD.IAcadBlockReference) Thanks Thomas. I'm getting an error using QueryInterface. C:\Python25\pythonw.exe C:\Python25\codes\autocad\temp\cast_test.py Traceback (most recent call last): File C:\Python25\codes\autocad\temp\cast_test.py, line 9, in module block = obj.QueryInterface(ACAD.IAcadBlockReference) File C:\Python25\Lib\site-packages\comtypes\__init__.py, line 1069, in QueryInterface self.__com_QueryInterface(byref(iid), byref(p)) _ctypes.COMError: (-2147467262, 'No such interface supported', (None, None, None, 0, None)) I guess this means, well, that the interface is not supported. BTW: Sometimes, interfaces ARE supported by COM objects but cannot be marshalled across process boundaries. You also get the above error in this case. -- Thanks, Thomas -- Check out the new SourceForge.net Marketplace. It is the best place to buy or sell services for just about anything Open Source. http://p.sf.net/sfu/Xq1LFB ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Problem with AutoCAD
Kelie schrieb: Ronan, There is a cast function. But the syntax isn't much shorter. import comtypes import comtypes.gen.AutoCAD as ACAD app = comtypes.client.GetActiveObject(AutoCAD.Application) obj = app.ActiveDocument.ModelSpace(1) #Assume this obj is a block block = comtypes.cast(obj, comtypes.POINTER(ACAD.IAcadBlockReference)) # I hope this would work # block = comtypes.cast(obj, ACAD.IAcadBlockReference) print Layer name: %s % block.Layer print Color: %d % block.Color print block.InsertionPoint print block.XScaleFactor But I'm getting error when trying to access various block properties. See output below. Apparently it was OK to access the Layer and Color properties. Don't know why. Waiting for Thomas... I haven't followed this thread so I do not really know what all this is about. Anyway, you should NOT use 'cast' with COM object pointers. Last, but not least, 'cast' doesn't handle the COM reference count correctly. Please use 'QueryInterface' with them, like so: block = obj.QueryInterface(ACAD.IAcadBlockReference) Thomas -- Check out the new SourceForge.net Marketplace. It is the best place to buy or sell services for just about anything Open Source. http://p.sf.net/sfu/Xq1LFB ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Problem with AutoCAD
Ronan Paixão schrieb: Also, I'm had some problems with type coercion. In the VB examples, the variable types are declared before using, which coerce return types. The comtypes documentation is terrible and I didn't find anything to do similar. The problem is that ms.Item(number), where ms is the ModelSpace, returns an IAcadEntity object, but sometimes I need methods from the main class (or pointer), like IACadBlockReference. Since I didn't find how to do it, I dug deep and found a way to do it like this: item=comtypes.POINTER(comtypes.gen.AutoCAD.IAcadBlockReference).from_param(ms.Item(number)) That seems a bit long, just to use the Explode() function, which is available for IACadBlockReference objects but not IACadEntity ones. Is there a more direct way to do it? See my other post in this thread: Use a QueryInterface() call. By the way, I wonder why we must enter array.array('d', coords) when a function requires an array of doubles, but when something should output an array of doubles, comtypes gives a tuple. IIRC, this is because autocad's type library isn't precise in what acad accepts. I have no idea how VB does it. Thomas -- Check out the new SourceForge.net Marketplace. It is the best place to buy or sell services for just about anything Open Source. http://p.sf.net/sfu/Xq1LFB ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
[comtypes-users] comtypes 0.6.0 released
I've just released comtypes-0.6.0! Summary of important changes: - Added a 'dynamic' keyword parameter to comtypes.client.CreateObject() and other creation functions. If 'dynamic=True' is passed then no wrapper module is generated if the COM object supports dynamic dispatch. This can save quite some time or disk space since the wrapper modules can be huge. - Bugfixes Detailed changes since version 0.5.3: 2008-12-19 Thomas Heller thel...@python.net * Bumped version number to 0.6.0. * comtypes.client.lazybind.Dipatch: If __getitem__ fails the get the indexed default value, try NewENUM. Implement __eq__ for Python 3 compatibility. * Fix a problem with SAFEARRAYs where the contained data was released too early. * Fix property get handling for FUNC_PUREVIRTUAL functions in lazybind.py 2008-12-18 Thomas Heller thel...@python.net * Fix memoryleak in IEnumVARIANT. 2008-12-12 Thomas Heller thel...@python.net * Merged changes from the dyndispatch branch: * Add a comtypes.client.Constants class that provides a way to access constants in the type library for an object, even when no wrapper has been created for the type library. The contants can be accessed as attributes like this, assuming 'obj' is a COM object that exposes type information at runtime via the dispatch interface: Constants(obj).MyConstant * New comtypes.client.lazybind module. * Implement NamedProperty.__call__(). Extend NamedProperty.__getitem__() and NamedProperty.__setitem__() so that they accept a tuple, which make lazy bound objects more compatible with early bound objects. * Finished (for now) the comtypes.client.lazybind module. IEnumVARIANT instances get a _dynamic attribute which defaults to False. The values returned from next() calls are retrived by calling ._set_value(self._dynamic) on the VARIANT result. * comtypes.client.dynamic: * Started changes based on ideas from Michael Curran: better dynamic dispatch support, and a way to disable the time-consuming wrapper code generation on demand. * comtypes\client: Add a new 'dynamic=False' parameter to the CreateObject function. This parameter allows to create a dynamic dispatch object, bypassing the code generation. * comtypes\automation.py: Add a new parameter to the VARIANT._get_value(dynamic=False) method. This allows to retrieve the current value as a _Dispatch() instance if the typecode is VT_DISPATCH, bypassing the code generation on the result. The IDispatch.Invoke implementation now uses this to ensure that dynamic objects are returned when possible. * comtypes\client\dynamic.py: Implement _Dispatch.__eq__ so that we can compare instances for equality. -- Thanks, Thomas -- ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Trouble getting events ...
Sandy Walsh schrieb: Hey all (again), congrats on 0.5.3! Thanks! I can't seem to get apps by using GetEvents(), but ShowEvents() works fine. My app is running in wxpython app and, hopefully, gets its event pump from the wx.MainLoop() I have a simple window that holds my ActiveX control: app = wx.App(False) frame = wx.Frame(None) activeX = MyActiveXControlWindow(frame) control = activeX.ctrl frame.Show() app.MainLoop() Somewhere during the running of the app, this gets called: class MySink(object): def _IFooEvents_RecordingStops(self): print _IFooEvents_RecordingStops ... sink = MySink() connection = GetEvents(control, sink = MySink()) ... But I never get any calls on MySink of any kind. However, if I replace the GetEvents() with a ShowEvents() not only do the possible Events list but I get my notifications that a given event is generated (like MouseOver). If an exception happens in your event handler (before something is printed), or an exception happens calling your event handler (for example if it is called with more or less arguments than it expects), then comtypes catches the exception and logs an error via Pythons logging module. So, to see the exceptions if there are any, you must configure logging to not swallow the exceptions silently. Adding these lines at the top of your script should work, for example: import logging; logging.basicConfig(level=logging.ERROR) I have attached another script that shows this behaviour. Looking at the _events.py code, I can't even see where the PumpEvents() is being done in ShowEvents(), but that's another question. Some events require a message loop so that they are delivered, others not. To be sure that events are delivered, an event loop is required (in single threaded apartments at least). -- Thanks, Thomas -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Unsupported Variant - NotImplementedError: typecode 20 = 0x14
Sandy Walsh schrieb: Little update on this I added to automation.py ... _get_value(self): ... elif vt == VT_I8: return self._.VT_I8 tagVARIANT _fields_ = [ ... (VT_I8, c_longlong), And it works fine. Thanks for the heads up. I have extended your patch so that also VT_UI8 is fully supported in VARIANT, and extended the VARIANT._set_value(). Just in time for the 0.5.3 release... Thanks, Thomas -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
[comtypes-users] comtypes 0.5.3 released
I just released comtypes-0.5.3. comtypes is a lightweight Python COM package, based on the ctypes FFI library, in less than 1 lines of code (not counting the tests). comtypes allows to define, call, and implement custom and dispatch-based COM interfaces in pure Python. It works on Windows, 64-bit Windows, and Windows CE. Download location: http://sourceforge.net/project/showfiles.php?group_id=115265 Homepage: http://starship.python.net/crew/theller/comtypes/ This is a maintainance release of the current repository state, before I merged the dynamic-dispatch branch (which will be released as comtypes-0.6.0 within the next few days). Summary of important changes: - Compatible with Python 3.0 - Added comtypes.shelllink module; this allows to manage shortcuts - Various smaller improvements Detailed changes since version 0.5.2: 2008-12-12 Thomas Heller thel...@python.net * Bumped version number to 0.5.3. * Added VARIANT support for VT_I8 and VT_UI8 typecodes. 2008-12-11 Thomas Heller thel...@python.net * Workaround for Python bug: Python 3 cannot handle a distutils installscript in the setup script * Merged the py3-branch: Various changes for py3 compatibility. The setup script now uses distutils.command.build_py.build_py_2to3 when run with Python 3.x, and converts the sources into py3 syntax on the fly (in the build directory). 2008-11-26 Thomas Heller thel...@python.net * Added untested code to comtypes.server: RegisterActiveObject() and RevokeActiveObject(), plus some flags. * Applied a patch from Torbjørn Tyridal. This allows to high-level implement methods in COM servers, and event handler methods that have [in] and [out] arguments in mixed order. 2008-11-05 Thomas Heller thel...@python.net * Add the IPersistFile interface to the comtypes.persist module. Add comtypes.shelllink module which contains IShellLinkA and IShellLinkW interfaces, plus the ShellLink coclass. 2008-10-29 Thomas Heller thel...@python.net * Handle coclass pointers as arguments in com interface methods correctly. Method calls will now accept pointers to the default interface of this coclass. * The Fire_Event() method in comtypes.server.connectionpoints now returns a list of results. 2008-10-10 Thomas Heller thel...@python.net * Import cStringIO, which should always be available on Windows, instead of first trying cStringIO and then StringIO. * Python 2.6 compatibility: use 'types.MethodType' instead of 'new.instancemethod' to fix a -3 warning. Use 'raise Exception(details)' instead of 'raise Exception, details'. Don't use tuple unpacking in exception handlers: 'except COMError, err: (hresult, text, details) = err' instead of 'except COMError, (hresult, text, details)' * Python 2.4 compatibility: os.stat() raises OSError instead of WindowsError when a file is not found. -- Thanks, Thomas -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] dyndispatch branch
Michael Curran schrieb: Hi Thomas, Support for getEvents/showEvents would be great with dynDispatch. However I must admit, that I didn't realize that it was possible to support events purely with IDispatch. My project doesn't technically rely on support for COM events in the places where we use IDispatch, though that is not to say it won't in the future. But, I think that releasing a comtypes with dynDispatch so far is a great step forward, even with out events. Of course, then at a later stage if events were added that would also be great. Michael, I have now (after the 0.5.3 release) merged the dyndispatch branch into the trunk, so the next release will be 0.6.0 with the 'dynamic=True' support you have been waiting for so long. I have to look into the remaining unittest failures, but I promise to make the 0.6.0 release next week. Thomas -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] comtypes.BSTR in stucture return NoneType
Wong, Shin Guey schrieb: I had a com dll return a structure and the structure definition is like below: class DeviceInfo(Structure): _recordinfo_ = ('{70577167-ED71-4977-B719-2C40C6DD8E1D}', 1, 2, 0L, '{6C7A25CB-7938-4BE0-A285-12C616717FDD}') DeviceInfo._fields_ = [ ('Special', VARIANT), ('Name', BSTR), ('Value', c_int), ('Flags', c_ulong), ('Type', c_ulong), ('ID', c_ulong), ('LocId', c_ulong), ('SerialNumber', BSTR), ('Description', BSTR), ('ftHandle', c_ulong), ] I can access the Value, Flags, ID, Type. But the SerialNumber, Name and Description all return None. Is the comtypes.BSTR working? I am sure my com dll is working because it can works under vb, c# and c++. I think it *should* work. Are you sure the fields contain non-empty strings? 'None' is expected to be returned for empty (NULL-pointer) BSTR fields. Anyway; is this com dll available publicely, so that I can test it myself? -- Thanks, Thomas -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] PATCH accepting interleaved [out] and [in] arguments (on event handlers)
Torbjorn Tyridal schrieb: Oh well.. Here it is anyway.. The asumtion that [out] arguments are placed after [in] arguments proved false, here is a patch that accepts arguments in any order. I have now written a single unit test for this (which is probably not enough) and applied your patch to the repository. Many thanks again, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] dyndispatch branch
Michael Curran schrieb: Thanks. Interested to know what the timeframe is now in regards to getting dyndispatch merged in to trunk? I've been trying dyndispatch as a replacement to win32com IDispatch for my own project, and performance is just the same, if not a little better. Were there any other features that needed to be added? I'm certainly happy with how it is at the moment. What I have added a few days ago was a way to access constants in a type library from objects exposing IDispatch::GetTypeInfo() and ITypeComp (in the dyndisp branch). It works for early bound, late bound, and lazy bound objects (are these correct names to a native english speaker?). There is now a function (actually a class) named comtypes.client.Constants. It can be used in this way: from comtypes.client import CreateObject, Constants x = CreateObject(Excel.Application) c = Constants(x) c.xlSaveChanges 1 c.xlDoNotSaveChanges 2 A nice improvement would of course be to make events (ShowEvents, GetEvents) work without generating the typelib wrapper, but that is too much work at the moment. Don't you need it? I'd be happy to help with writing tests and or documentation if that is something that has to be done before merging --- Obviously I am quite keen to see this merged :) My original plan was to work on compatibility with Python 3, and release then, but if you're really waiting for it I can as well release now. Mick Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] dyndispatch branch
Michael Curran schrieb: Hi, Thanks for the explanation. If comtypes is already using the [] syntax for early bound interfaces, and if that is the most suitable way, then that sounds ok to me. I agree that it is important to keep dyn dispatch interfaces as compatible with early bound interfaces as possible. So, I also in that case do also think that __call__ should be implemented. In order so that named properties with optional or needed arguments can be called with () for getting, even though you could also use the [] syntax as well. In our projects, and I suspect others, comtypes early bound propgets with arguments are called with (), I never new about []. Hm, I didn't remember it but property access syntax IS even documented for quite some time here: http://starship.python.net/crew/theller/comtypes/#accessing-properties Besides that, I have now in the dyndispatch-branch added the call syntax to get properties, and extended the __getitem__ and __setitem__ calls so that [...] property access (both get and put) works with one or more arguments, in the same way as the early bound case. Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] interpreting idl files: [out] is actually an [in], is there something we can do?
That [out] has now become an __in because the caller allocates the buffer. If you are *implementing* this method - is there a problem at all? The caller HAS already allocated the buffer, you only have to fill it. Anyway, if you have special requirements that can not be fullfilled by the 'high level' method implementation then you should use the 'low level' implementation; I have posted several times about them. Yes, I'am implementing the event handler, and yes, as I tried to explain in the previous mail there is a problem as there is a mismatch between reality and the comtypes generated prototype. The argument is specified as [out] -as data is flowing from the implementation (callee) to the caller. That means for the (high-level) comtypes: the buffer never reaches my implementation of the event handler. As the buffer is preallocated by the caller that should really be interpreted as an [in] argument. I guess then, there is nothing else to do but to modify the generated file, or use the low-level stuff (but i really like high level... -That's why I used Python in the first place :) ) IMO the difference between low level and high level, when *implementing* a COM method, is not so large. In my own experience from working with a lot of com objects implemented in comtypes, sometimes the first is more convenient, sometimes the latter. Consider this implementation for a fairly normal method: IDL: HRESULT my_method([in] int a, [in] int b, [out, retval] int *presult) low level impl: def my_method(self, this, a, b, presult): if not presult: return E_POINTER # optional, check for NULL pointer presult[0] = a + b # store the result return S_OK # return success high level impl: def my_method(self, a, b): return a + b Surely the high level impl is a lot more Pythonic, but low level one should be easy to understand as well. When you want to check argument values, and return error codes depending on them (assuming the method should return the quotient of the two numbers), you would write code like this: low level impl: def my_method(self, this, a, b, presult): if not presult: return E_POINTER # optional, check for NULL pointer if b == 0: # check for valid values return E_INVALIDARG presult[0] = a / b # store the result return S_OK # return success high level impl: def my_method(self, a, b): if b == 0: raise ReturnHRESULT(E_INVALIDARG) return a / b In this case it is not so clear to me which way to prefer. But I should really write the docs for that... Anyway, I understand that you don't like to use the low level impl, but you can live with that? Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Creating Shell Links using comtypes
Martin (gzlist) schrieb: On 03/11/2008, Markus Gritsch [EMAIL PROTECTED] wrote: Hi, I would like to create shell links (.lnk) from my Python program. ... It would be very nice, if someone could give me any advice how to do this using comtypes. When I wanted to do this in a hurry and didn't have time to look up the right way to do it, I ended up with code something like: import comtypes from comtypes.client import CreateObject ws = CreateObject(WScript.Shell) from comtypes.gen import IWshRuntimeLibrary shortcut = comtypes.cast(ws.CreateShortcut(test_shortcut.lnk), comtypes.POINTER(IWshRuntimeLibrary.IWshShortcut)) shortcut.TargetPath = cmd.exe shortcut.Arguments = /K C:\Python24\python.exe shortcut.Save() This worked for me, but may be bad practice or generally bogus in some way or other. I think I got there by reading http://www.ironpython.info/index.php/Creating_a_Shortcut_File_with_WSH_Interop then looking at the comtypes generated code, then poking things until it stopped throwing exceptions. Cool! The only thing I would suggest to change is to use QueryInterface instead of cast: import comtypes from comtypes.client import CreateObject ws = CreateObject(WScript.Shell) from comtypes.gen import IWshRuntimeLibrary shortcut = ws.CreateShortcut(test_shortcut.lnk).QueryInterface(IWshRuntimeLibrary.IWshShortcut) shortcut.TargetPath = cmd.exe shortcut.Arguments = /K C:\Python24\python.exe shortcut.Save() -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Creating Shell Links using comtypes
Markus Gritsch schrieb: Hi, just to let you know: I gave up on creating .lnk files using comtypes and instead use .url files with a local address. For my application placing such a file in the Windows startup folder they works just fine, and have the huge advantage of being simple text files. Does the solution that Martin posted not work for you? -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Creating Shell Links using comtypes
Markus Gritsch schrieb: Hi, I would like to create shell links (.lnk) from my Python program. I found the following solution at [1] which uses win32com: import os, sys import pythoncom from win32com.shell import shell, shellcon shortcut = pythoncom.CoCreateInstance ( shell.CLSID_ShellLink, None, pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink ) shortcut.SetPath (sys.executable) shortcut.SetDescription (Python %s % sys.version) shortcut.SetIconLocation (sys.executable, 0) desktop_path = shell.SHGetFolderPath (0, shellcon.CSIDL_DESKTOP, 0, 0) persist_file = shortcut.QueryInterface (pythoncom.IID_IPersistFile) persist_file.Save (os.path.join (desktop_path, python.lnk), 0) I was trying to translate this to comtypes, but had absolutely no success. It would be very nice, if someone could give me any advice how to do this using comtypes. I have now bit the bullet and implemented the IPersistFile (in comtypes.persist), IShellLinkA, IShellLinkW interfaces plus the ShellLink coclass in comtypes SVN. A usage example is at the bottom of the comtypes.shelllink file: http://comtypes.svn.sourceforge.net/viewvc/comtypes/trunk/comtypes/shelllink.py?revision=457view=markup Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] interpreting idl files: [out] is actually an [in], is there something we can do?
Torbjorn Tyridal schrieb: Hi, I have another one for you: from the idl file (oleview) interface ISoftUSBEndpointEvents : IUnknown { ... [helpstring(Fired when an IN transaction is received from the host. Allows device simulator to directly return data to host controller for the transaction.), helpcontext(0x06bd)] HRESULT _stdcall OnReadTransfer( [in] unsigned char DataToggle, [out] unsigned char* pbDataBuffer, [in] unsigned long cbDataBuffer, [out] unsigned long* cbDataWritten, [out] unsigned char* pbStatus); Note the [out] unsigned char* pbDataBuffer, while we compare this to microsoft documentation for ISoftUSBEndpointEvents::OnReadTransfer, and especially the given example (http://msdn.microsoft.com/en-us/library/bb201520.aspx) STDMETHODIMP CSoftUSBEndpointEvent::OnReadTransfer(__in BYTE DataToggle, __in_bcount(cbDataBuffer) BYTE *pbDataBuffer, __in ULONG cbDataBuffer, __out ULONG *cbDataWritten, __out BYTE *pbStatus) That [out] has now become an __in because the caller allocates the buffer. As far as I understand this, '__in_bcount(cbDataBuffer) BYTE *pdDataBuffer' is MS' SAL (source code annotation language). It means that the caller has to supply a buffer of 'cdDataBuffer' length, the callee will fill it, and the contents will be returned (that is the 'out' value then). There is a somewhat similar notation in the IDL files for COM (size_is, length_is, and so on), but type libraries have no way to represent this information. The MIDL compiler, when it compiles an IDL file uses this info to generate marshalling C/C++ code that can be used to create proxy dlls for COM object. However, comtypes has no way to use this annotation simply because it is not in the typelib, as I said before. is there something (else than editing the generated file) I can do to solve this? Are you calling this method, or are you implementing it with comtypes? (Since it is an event interface, I assume the latter.) If *calling* this method, you should not call the obj.OnReadTransfer(...) method, instead you should call the low level obj.__com_OnReadTransfer(...) method which is also created at runtime by comtypes' metaclasses. See, as one example, the QueryInterface implementation in comtypes\__init__.py: class IUnknown(object): def QueryInterface(self, interface, iid=None): QueryInterface(interface) - instance p = POINTER(interface)() if iid is None: iid = interface._iid_ self.__com_QueryInterface(byref(iid), byref(p)) clsid = self.__dict__.get('__clsid') if clsid is not None: p.__dict__['__clsid'] = clsid return p If you are *implementing* this method - is there a problem at all? The caller HAS already allocated the buffer, you only have to fill it. Anyway, if you have special requirements that can not be fullfilled by the 'high level' method implementation then you should use the 'low level' implementation; I have posted several times about them. Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] PATCH accepting interleaved [out] and [in] arguments (on event handlers)
Torbjorn Tyridal schrieb: Oh well.. Here it is anyway.. Many thanks for the patch. I will create additional unittests for the new behaviour and eventually commit it. The asumtion that [out] arguments are placed after [in] arguments proved false, here is a patch that accepts arguments in any order. == --- comtypes-0.5.2\_comobject.py Fri Sep 19 21:49:50 2008 +++ comtypes\_comobject.pyWed Oct 29 22:04:20 2008 @@ -89,34 +89,44 @@ def hack(inst, mth, paramflags, interfac # An argument is an input arg either if flags are NOT set in the # idl file, or if the flags contain 'in'. In other words, the # direction flag is either exactly '0' or has the '1' bit set: -args_in = len([f for f in dirflags if (f == 0) or (f 1)]) -# number of output arguments: -args_out = len([f for f in dirflags if f 2]) +# Output arguments have flag '2' + +args_out_idx=[] +args_in_idx=[] +for i,a in enumerate(dirflags): +if a2: +args_out_idx.append(i) +if a1 or a==0: +args_in_idx.append(i) +args_out = len(args_out_idx) + ## XXX Remove this: ##if args_in != code.co_argcount - 1: ##return catch_errors(inst, mth, interface, mthname) -# This code assumes that input args are always first, and output -# args are always last. Have to check with the IDL docs if this -# is always correct. clsid = getattr(inst, _reg_clsid_, None) def call_without_this(this, *args): -outargs = args[len(args)-args_out:] # Method implementations could check for and return E_POINTER # themselves. Or an error will be raised when # 'outargs[i][0] = value' is executed. ##for a in outargs: ##if not a: ##return E_POINTER + +#make argument list for handler by index array built above +inargs=[] +for a in args_in_idx: +inargs.append(args[a]) + try: -result = mth(*args[:args_in]) +result = mth(*inargs) if args_out == 1: -outargs[0][0] = result +args[args_out_idx[0]][0] = result elif args_out != 0: if len(result) != args_out: raise ValueError(Method should have returned a %s-tuple % args_out) for i, value in enumerate(result): -outargs[i][0] = value +args[args_out_idx[i]][0] = value except ReturnHRESULT, (hresult, text): return ReportError(text, iid=interface._iid_, clsid=clsid, hresult=hresult) except COMError, (hr, text, details): -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] this parameter to COM event functions
James Teh schrieb: Hi all, I am a little confused about the this parameter to COM events. When one wants to receive COM events, one does something like the following: self._advise = comtypes.client.GetEvents(self._server, Sink()) where the Sink class has methods such as: def onEvent(self, this, arg1, arg2): ... However, it seems that there has recently been a change in the way this is handled. (I am not sure what version of comtypes this occurred in, but I suspect 0.5.1.) It seems that the name this is somehow special. If the exact parameter name this is not present as the first argument, the event seems to work fine without it. For example, the following works: def onEvent(self, arg1, arg2): However, this does not work: def onEvent(self, this, arg2): It would seem that the this parameter is now optional. Unfortunately, with another COM server, if this is present at all, the event function is not fired. Can anyone provide some clarification as to the status of the this parameter in comtypes 0.5.2? Is this now optional? Is the name this special? Just yesterday I answered mostly the same question, see the last post in the thread 'returning HResult value from event handlers'. In short: Yes, behaviour has changed between 0.4 and 0.5; yes the name 'this' is special; yes it is optional, but if you still use the 'this' parameter (with exactly that name) then the behaviour should be the same in 0.4 and 0.5 . -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Problem on access propput and propget functions
Wong, Shin Guey schrieb: Message: 4 Date: Mon, 27 Oct 2008 20:52:09 +0100 From: Thomas Heller [EMAIL PROTECTED] Subject: Re: [comtypes-users] Problem on access propput and propget functions To: comtypes-users@lists.sourceforge.net Sorry for this too late reply - I must somehow have overlooked this all the time. Well, it's fine. I am glad that you replied my email. In the mean time, we are using the win32com now. But I hope to be able to convert it to comtypes soon because most of the others com object we have are using comtypes. There is probably a problem with property accesses that use [in, out] parameters. Is the com object that you use publicely available somewhere? No, this is a com object use internally in our company. However, I have the source code and I can create some prototype for the com object for testing. I am busy with other stuff now and it is working with win32com now. I will retry again later. and update you if I have any problem. Fine. Maybe, you can explain why there are parameters marked [in, out] in propput methods? Here is the generated python script by comtypes: === COMMETHOD([dispid(1745027074), 'propput'], HRESULT, 'HeadCount', ( ['in', 'out'], POINTER(c_short), 'None' )), COMMETHOD([dispid(1745027074), 'propget'], HRESULT, 'HeadCount', ( ['retval', 'out'], POINTER(c_short), 'None' )), COMMETHOD([dispid(1745027073), 'propput'], HRESULT, 'CommPort', ( ['in', 'out'], POINTER(c_short), 'Head' ), ( ['in', 'out'], POINTER(c_short), 'None' )), Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] returning HResult value from event handlers
Torbjorn Tyridal schrieb: Another issue, Is it possible to control the hResult value returned from event sinks ? My COM object typically sends and event, assumes everything is fine and handled on S_OK and does some default handler if S_FAIL is returned. Well, I think that relying on the HRESULT of a event interface method call is not a good idea. FAILED HRESULT values are converted and raised as Python exceptions by comtypes. However, I would suggest that you use 'out' parameters in the event interface methods; this would allow the client code to pass some information to the server from an event. For example, Internet Explorer also uses this mechanism in the 'BeforeNavigate' event which allows the client to forbid navigation depending on the URL. I have committed some code to comtypes in SVN that collects the return values from event interface calls and returns a list of them from the Fire_Event(...) call. Does this help you? But maybe I completely misunderstand you and you want to return special HRESULT values from the event method implementations in your client ??? -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Passing object pointers to methods - prototypes generated with error?
Torbjorn Tyridal schrieb: On Tue, Oct 28, 2008 at 4:23 PM, Thomas Heller [EMAIL PROTECTED] wrote: I'm using comtypes (0.5.2) with the DSF (http://www.microsoft.com/whdc/devtools/DSF.mspx), and it seems to me that the generated prototypes for methods requiring object pointers are wrong. What is ISoftUSBString in the IDL (I assume a COM interface) and what is SoftUSRString in the IDL (I assume a coclass)? Good questions, it seems like microsoft is not distributing the idl, only tlb and dll files. Note: You can decompile the binary typeinformation in tlb, dll, and exe files with MS oleview program back into IDL. However I have the same problem with DSF.HotPlug not accepting DSFDevice objects. And for DSF the idl is available: interface IDSF : IDispatch { ... HRESULT _stdcall HotPlug ([in] DSFDevice *pDSFDevice, [in] BSTR bstrBus, [out, retval] IDSFBus **ppiDSFBus); ... }; interface IDSFDevice : IDispatch { ... }; coclass DSFDevice { [default] interface IDSFDevice; [default, source] interface IDSFDeviceEvents; }; again, import comtypes.client as cc dsf = cc.CreateObject(DSF.DSF) mydev = cc.CreateObject(DSF.DSFDevice) dsf.HotPlug(mydev, USB2.0) # throws TypeError comtypes generated code: IDSF._methods_ = [ ... COMMETHOD([dispid(1248), helpstring(u'Plugs the given DSFDevice into the bus which is defined eithe by its GUID or friendly name.')], HRESULT, 'HotPlug', ( ['in'], POINTER(DSFDevice), 'pDSFDevice' ), ( ['in'], BSTR, 'bstrBus' ), ( ['retval', 'out'], POINTER(POINTER(IDSFBus)), 'ppiDSFBus' )), ] changing that ( ['in'], POINTER(DSFDevice) to ( ['in'], POINTER(IDSFDevice) solves the problem I think that the code generation should not be changed; instead I would prefer to extend the CoClass class (which is the base class for DSFDevice in your case) so that it accepts interface pointers to the CoClass' default interface in method calls when the argument type is POINTER(CoClass-subclass). The following patch should do this, can you please try it out? Index: comtypes/_meta.py === --- comtypes/_meta.py (revision 428) +++ comtypes/_meta.py (working copy) @@ -14,6 +14,11 @@ result.__dict__[__clsid] = str(self._reg_clsid_) return result +def _coclass_from_param(cls, obj): +if isinstance(obj, (cls._com_interfaces_[0], cls)): +return obj +raise TypeError(obj) + # # The mro() of a POINTER(App) type, where class App is a subclass of CoClass: # @@ -42,8 +47,10 @@ clsid = namespace[_reg_clsid_] comtypes.com_coclass_registry[str(clsid)] = klass PTR = _coclass_pointer_meta(POINTER(%s) % klass.__name__, - (klass, c_void_p), - {__ctypes_from_outparam__: _wrap_coclass}) +(klass, c_void_p), +{__ctypes_from_outparam__: _wrap_coclass, + from_param: classmethod(_coclass_from_param), + }) from ctypes import _pointer_type_cache _pointer_type_cache[klass] = PTR -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Events from IUnknown interfaces
Erik Wilsher schrieb: After some further digging and testing with other COM-servers, I found out that I was creating new objects in my client code, rather than connecting to the active object. Ok, so I assume your events are working now. So the hurdle now is to register an instance of my COM-server (written using comtypes) as the active object in the ROT. This is quite challenging, and I've tried various combinations of RegisterActiveObject without any success. Any clues on how to register an instance would be most welcome. Here is some code that wraps the RegisterActiveObject and RevokeActiveObject functions: snip ACTIVEOBJECT_STRONG = 0x0 ACTIVEOBJECT_WEAK = 0x1 import comtypes, ctypes oleaut32 = ctypes.oledll.oleaut32 def RegisterActiveObject(comobj, weak=True): punk = comobj._com_pointers_[comtypes.IUnknown._iid_] clsid = comobj._reg_clsid_ if weak: flags = ACTIVEOBJECT_WEAK else: flags = ACTIVEOBJECT_STRONG handle = ctypes.c_ulong() oleaut32.RegisterActiveObject(punk, ctypes.byref(clsid), flags, ctypes.byref(handle)) return handle.value def RevokeActiveObject(handle): oleaut32.RevokeActiveObject(handle, None) snip/ RegisterActiveObject(...) can be called with an instance of a COM object implemented with comtypes (I tried it with the test code in comtypes\test\TestComServer.py). I guess this code should go into comtypes\server\__init__.py, but further integration into comtypes\server\localserver.py is probably needed (this I guess from reading the MSDN docs for RegisterActiveObject). -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Passing object pointers to methods - prototypes generated with error?
Torbjorn Tyridal schrieb: I'm using comtypes (0.5.2) with the DSF (http://www.microsoft.com/whdc/devtools/DSF.mspx), and it seems to me that the generated prototypes for methods requiring object pointers are wrong. It seems valid for all methods related to DSF, and example is ISoftUSBStrings.Add(...): ISoftUSBStrings.Add is generated to take parameter POINTER(SoftUSBString) however, I can not find a way to pass that object ? All I have is a ISoftUSBString reference. Changing the generated prototype to POINTER(ISoftUSBString) makes everything work. We have to look at the IDL definition of the interface. What is ISoftUSBString in the IDL (I assume a COM interface) and what is SoftUSRString in the IDL (I assume a coclass)? Am I overlooking a cast_to_object_implementing_interface function or is that a bug in the code generator? trigger code: import comtypes.client as cc usbdev = cc.CreateObject(SOFTUSB.SoftUSBDevice) usbstr = comc.CreateObject(SOFTUSB.SoftUSBString) usbstr.Value = my string #This will cast an typeError exception before changing the generated prototype usbdev.Strings.Add(usbstr,1) -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Events from IUnknown interfaces
Erik Wilsher schrieb: I have a problem with Fire_Event that I can't figure out, and some help would be appreciated. The problem is probably from my lack of understanding of COM. I have a server with three interfaces, one outbound event interface, and two inbound interfaces [...] The problem is that events fired from Itest2 methods (i.e using a Fire_Event within the register method) is never propagated and never reaches clients that are listening with ShowEvents, while events fired from Itest1 is. The server is running as a local server, STA. I have tried the following combinations on the server side: self.Fire_Event(0, 'RunState', 'test', 3) self.Fire_Event(...IServerEvents, 'RunState', 'test', 3) Watching the debug output, I can see that the .connectionpoints._call_sinks(...) is always executed when I call Fire_Event(), but the object addresses of the ConnectionPointImpl object are different depending on where the Fire_Event originates (from Itest1 or Itest2) Are you writing both the server and the client code in comtypes? Are you able to strip it down to a small selfcontained test case, and post the code? -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Events for device not working since version 0.3.2
Malte Skarupke schrieb: I'm trying to get the 3D Space Navigator (http://www.3dconnexion.com/) to work in Python. I quickly found a solution using comtypes on the 3DConnexion developer forum: http://www.3dconnexion.com/forum/viewtopic.php?t=984start=30 However that solution only works with comtypes version 0.2.1. Any newer version will result in the events not registering. I've looked up the thread in the forum. A user codenamed 'kitsu' wrote: Note that there is a error in the comtypes 0.3.2 GetEvents function which causes it to miss all events. I've reported it to the mailing list, but until it is fixed use comtypes 0.2.1. I have not found the 'report' he mentions on the mailing list. Dois the code snippet that he posted here http://www.3dconnexion.com/forum/viewtopic.php?t=984start=33 work with comtypes 0.2.1, and not with later comtypes? This is the output I get from the GetEvents() function when using version 0.2.1: Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32 Type help, copyright, credits or license for more information. import logging logging.basicConfig(level=logging.DEBUG) class EventHandler: ... def __getattr__(self, name): ... print name ... from comtypes.client import * DEBUG:comtypes:CoInitializeEx(None, 2) x = CreateObject(TDxInput.Device) DEBUG:comtypes.client:TDxInput.Device - {82C5AB54-C92C-4D52-AAC5-27E25E22604C} DEBUG:comtypes.client:CoCreateInstance({82C5AB54-C92C-4D52-AAC5-27E25E22604C}, clsctx=None, interface=None) INFO:comtypes.client:wrap(POINTER(IUnknown) object c108a0) INFO:comtypes.client:Does implement IProvideClassInfo INFO:comtypes.client:Implements default interface from typeinfo class 'comtypes.gen._7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0.ISimpleDevice' INFO:comtypes.client:Final result is POINTER(ISimpleDevice) object c2c080 x.Connect() 0 test = GetEvents(x.sensor, EventHandler) INFO:comtypes.client:wrap_outparam(POINTER(ISensor) object c108a0) DEBUG:comtypes.client:POINTER(ISensor) object c108a0 using sinkinterface class 'comtypes.gen._7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0._ISensorEvents' DEBUG:comtypes.client:Start advise class 'comtypes.gen._7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0._ISensorEvents' DEBUG:comtypes._comobject:comtypes.client.DispEventReceiver object at 0x00C12590.QueryInterface({E6929A4A-6F41-46C6-9252-A8CC53472CB1}) - S_OK DEBUG:comtypes._comobject:1 active COM objects: Added comtypes.client.DispEventReceiver object at 0x00C12590 DEBUG:comtypes._comobject:comtypes.client.DispEventReceiver object at 0x00C12590.AddRef() - 1 DEBUG:comtypes.client:End advise class 'comtypes.gen._7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0._ISensorEvents' DEBUG:comtypes._comobject:comtypes.client.DispEventReceiver object at 0x00C12590.Release() - 0 DEBUG:comtypes._comobject:0 active COM objects: Removed comtypes.client.DispEventReceiver object at 0x00C12590 And this is the output I get when I use version 0.5.1: Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32 Type help, copyright, credits or license for more information. import logging logging.basicConfig(level=logging.DEBUG) from comtypes.client import * DEBUG:comtypes:CoInitializeEx(None, 2) x = CreateObject(TDxInput.Device) DEBUG:comtypes.client:TDxInput.Device - {82C5AB54-C92C-4D52-AAC5-27E25E22604C} DEBUG:comtypes.client:CoCreateInstance({82C5AB54-C92C-4D52-AAC5-27E25E22604C}, clsctx=None, interface=None) DEBUG:comtypes.client:GetBestInterface(POINTER(IUnknown) ptr=0x9f3fc0 at c0e3f0) DEBUG:comtypes.client:Does implement IProvideClassInfo DEBUG:comtypes.client:Default interface is {CB3BF65E-0816-482A-BB11-64AF1E837812} DEBUG:comtypes:Release POINTER(IUnknown) ptr=0x9f3fc0 at c14080 DEBUG:comtypes.client._generate:GetModule(TLIBATTR(GUID={7858B9E0-5793-4BE4-9B53-661D922790D2}, Version=1.0, LCID=0, FLags=0x8)) DEBUG:comtypes.client:Implements default interface from typeinfo class 'comtypes.gen._7858B9E0_5793_4BE4_9B53_661D922790D2_0_1_0.ISimpleDevice' DEBUG:comtypes.client:Final result is POINTER(ISimpleDevice) ptr=0x9f3fc0 at c14d00 DEBUG:comtypes:Release POINTER(IProvideClassInfo) ptr=0x9f68a8 at c0ed00 DEBUG:comtypes:Release POINTER(ITypeInfo) ptr=0x24c5f4 at c0eda0 DEBUG:comtypes:Release POINTER(ITypeInfo) ptr=0x24c620 at c0ee90 DEBUG:comtypes:Release POINTER(ITypeLib) ptr=0x24bd88 at c0ef80 DEBUG:comtypes:Release POINTER(IUnknown) ptr=0x9f3fc0 at c0e3f0 x.Connect() 0 test = ShowEvents(x.sensor)
Re: [comtypes-users] Events for device not working since version 0.3.2
[Resending, the first answer seemed to get lost somewhere] Malte Skarupke schrieb: I'm trying to get the 3D Space Navigator (http://www.3dconnexion.com/) to work in Python. I quickly found a solution using comtypes on the 3DConnexion developer forum: http://www.3dconnexion.com/forum/viewtopic.php?t=984start=30 However that solution only works with comtypes version 0.2.1. Any newer version will result in the events not registering. I believe, that this is enough output, because I believe the line DEBUG:comtypes:Release POINTER(ISensor) ptr=0x9f2170 at c14d50 shows, where the bug originates. If you need any further testing, I would be glad to help. Does it work when you keep a reference to the sensor object? Something like this: import logging logging.basicConfig(level=logging.DEBUG) from comtypes.client import * x = CreateObject(TDxInput.Device) x.Connect() 0 s = x.sensor test = ShowEvents(s) -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
[Resending, the first answer seemed to get lost somewhere] Anthony Tuininga schrieb: On Thu, Sep 18, 2008 at 10:44 AM, Thomas Heller [EMAIL PROTECTED] wrote: Thomas Heller schrieb: Here's the next idea that I have for the version checking: Version check inside the generated modules, but using code outside: So, inside the generated module: ''' from comtypes import check_wrapper_version check_wrapper_version('42') ''' comtypes.check_wrapper_version() would compare against the code generator version, and in the simplest case raise an ImportError(version mismatch). In a more sophisticated implementation it could regenerate and reload the module. I have implemented this now; the code simply compares the actual and the required version and raises an ImportError if they are unequal. Looks good. Also I must admit that I have reintroduced the os.stat() calls on the typelib files and the generated module files, this is too damn convenient for me. The code is much simpler now, and if the generated module's timestamp is less than the typelib's timestamp an ImportError is also raised. If any of the os.stat() calls fail then the import succeeds. Hmm, you have added a coder generator version inside the generated module. Perhaps you could also add the type library timestamp inside the generated module as well and compare that with the os.stat() on the type library? The type library file should always exist, right? Its the module that may not exist or rather be buried inside a zip file. If you put the type library timestamp inside the generated module that would work in both the script and frozen situations. What do you think of that concept? To be honest, the current code does *exactly* what I want: def _check_version(actual): from comtypes.tools.codegenerator import version as required if actual != required: raise ImportError(Wrong version) if not hasattr(sys, frozen): g = sys._getframe(1).f_globals mod_path = g.get(__file__) tlb_path = g.get(typelib_path) try: mod_mtime = os.stat(mod_path).st_mtime tlib_mtime = os.stat(tlb_path).st_mtime except (WindowsError, TypeError): return if mod_mtime tlib_mtime: raise ImportError(Typelib newer than module) On the development machine, the code running as Python script, 'hasattr(sys, frozen)' is False, and the timestamps are checked. Regenerating a module because a typelib has been recompiled from idl - even if the version number has not changed - is what I want; this makes sure that the generated code is correct. On the end user machine my code runs from within py2exe, 'hasattr(sys, frozen)' is True, and I do not want to regenerate the code because I trust the typelib version number in this case. The generated modules bundled within the executable should be used in this case. There are probably other possible ways to distinguish a developer and an end-user machine, if they are preferred. I wonder if there should be a way in comtypes to enable/disable this timestamp check? Currently I've enabled this code only when a script is run, in other words only when hasattr(sys, frozen) is False. I was thinking of having a config variable in comtypes\__init__.py so that users (like you?) who would like to avoid the os.stat() calls, and who do not compile typelibaries themselves, would be able to skip this check completely by changing this variable. Maybe by editing a comtypes.cfg file somewhere, maybe programmatically. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
Thomas Heller schrieb: Here's the next idea that I have for the version checking: Version check inside the generated modules, but using code outside: So, inside the generated module: ''' from comtypes import check_wrapper_version check_wrapper_version('42') ''' comtypes.check_wrapper_version() would compare against the code generator version, and in the simplest case raise an ImportError(version mismatch). In a more sophisticated implementation it could regenerate and reload the module. I have implemented this now; the code simply compares the actual and the required version and raises an ImportError if they are unequal. Also I must admit that I have reintroduced the os.stat() calls on the typelib files and the generated module files, this is too damn convenient for me. The code is much simpler now, and if the generated module's timestamp is less than the typelib's timestamp an ImportError is also raised. If any of the os.stat() calls fail then the import succeeds. I wonder if there should be a way in comtypes to enable/disable this timestamp check? Currently I've enabled this code only when a script is run, in other words only when hasattr(sys, frozen) is False. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
I agree that version checking outside would be nicer. I tried to hack the comtypes.client._generate module and the codegenerator to implement this, but there is one place where an outside version check does not work. For example, the InternetExplorer typelib generated module contains this statement: import comtypes.gen._00020430___C000_0046_0_2_0 which imports the stdole2.tlb typelib wrapper code. So this import is not done with some code in the _generate module and cannot be checked from there. Good point. So adding the code to the generated module makes the most sense. So I guess you'll remove the code outside of the module, then. Here's the next idea that I have for the version checking: Version check inside the generated modules, but using code outside: So, inside the generated module: ''' from comtypes import check_wrapper_version check_wrapper_version('42') ''' comtypes.check_wrapper_version() would compare against the code generator version, and in the simplest case raise an ImportError(version mismatch). In a more sophisticated implementation it could regenerate and reload the module. But I have no time to implement this now. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
I have comitted an implementation as svn revision 407. I took a look. Much better. :-) Just one further question: is there any reason why you have the code inside the generated module to raise an error if the generated number does not match when you are already performing that check after you import the module successfully? I think you can quite safely remove that code. In other words, all you want in the generated code is __codegen_version__ = 42 Then in the importing code module = __import__() if module.__codegen_version__ != comtypes.tools.codegenerator.version: raise ImportError(version mismatch) I think that the version check inside the modules MUST be done. The only purpose of the version checks from outside, in comtypes.client._generate, is to catch cases where wrappers are already present in comtypes.gen, but from a previous version that has not inserted version checks into the modules. Since comtypes 0.5.1 will probably be the last release that does not generate version checks, this code can probably go. Ah, I see that you are intending to keep the code in the generated module and I was intending to keep the code outside the generated module. I think we both agree that only one check is needed. :-) The only reason I would keep the code outside the generated module is safety (that code is completely under your control) and clarity (the code that performs the check is in your face when you are looking at the code that does the import) -- but I have no difficulty with your plans either if you prefer. I agree that version checking outside would be nicer. I tried to hack the comtypes.client._generate module and the codegenerator to implement this, but there is one place where an outside version check does not work. For example, the InternetExplorer typelib generated module contains this statement: import comtypes.gen._00020430___C000_0046_0_2_0 which imports the stdole2.tlb typelib wrapper code. So this import is not done with some code in the _generate module and cannot be checked from there. BTW, the code that checks for the existence of the __codegen_version__ attribute will already confirm anything earlier than 0.5.1 anyway since that attribute is new, right? Yes (if I understand you correctly; I'm not a native english speaker) it would invalidate modules generated with earlier codegenerator versions. And this is the only place where an additional outside check makes sense when otherwise only inside checks were used. But this problem will go away after the next comtypes version anyway so maybe the check can be removed. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] generated modules
Anthony, I have, finally, come to the conclusion that you are absolutely right: it is fundamentally broken to make the generated modules dependent on timestamps. Whether a generated module is up to date or not should only depend on two things: - the version number of the type library (this is clear) - and the 'version number' of the comtypes codegenerator. The former is already taken care by the naming convention of the generated modules, the latter can probably be achived by generating a code snippet like this into the wrapper module itself: import comtypes.tools.codegenerator if comtypes.tools.codegenerator.version != 42: raise ImportError(wrong version) and then regenerating the wrapper code when the import fails. No longer fiddling with imp.find_module(), searching for type library files, fiddling with timestamps and so on. Ok? Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] COM issues with IE7 and python, possibly the GIL?
MR Michael Robellard (5314) schrieb: We have created a COM object that runs under IE to implement the IURLSearchHook2 interface. This allows you to intercept invalid URLs and run a search for them in the address bar of IE. Everything has been running great on my XP box with IE6 installed on it. We went to test it on an IE7 machine and we have instant issues with it. When you search in IE7 using the code it will randomly hang the search. The rest of IE continues to function. If you then execute a second search in the address bar, it will execute the second search and then the hung search will successfully execute. Attached is a standalone python module that successfully reproduces this issue. You will need to add the following GUID as the only string value in the key: {0BC6E3FA-78EF-4886-842C-5A1258C4455A} to this key in the registry HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\URLSearchHooks Thanks you for preparing this standalone test case. I have tried it out but as I said in posts before I cannot get it to work neither with a XP IE6 machine nor with a XP IE7 machine. I will try it out over the weekend when I find a different machine. So the questions are: Have we done something in our implementation that is causing this issue? Is there an issue with how _ctypes.pyd is handling the GIL for these calls? I noticed from the logging output, at least on my XP IE7 machine, that indeed the com object seems to hang somehow, although I see a different behaviour in IE with the first and the second search than you describe. When I close IE after trying out a search, the GUI closes but the process still keeps running - I have to kill it so that it closes. So it seems that maybe IE tries to make some COM calls to the search object but they are blocked... I will further check this out when I have more time, for now I changed the threading model that your sample code uses, and indeed when I reregister the object with threadingmodel 'None' then IE shuts down correctly (although the search still does not work). To test this yourself you should remove or comment out the line that reads _reg_threading_ = Both and reregister the object. As a workaround we have a C++ COM object that receives the calls on this interface and then forwards them to a localserver python com object that does the work. Not ideal but it seems to work. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
[comtypes-users] What's going on in SVN 8/2008
I have moved the comtypes subversion repository back to sourceforge, and also cleaned up the repository structure to a more standard layout. If you have a SVN checkout of comtypes, please get a fresh one from the new url: https://comtypes.svn.sourceforge.net/svnroot/comtypes/ ViewVC is available at https://comtypes.svn.sourceforge.net/comtypes/ -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
[comtypes-users] comtypes 0.5.1 released
I have released comtypes 0.5.1, so that it is no longer required to use SVN to get the current package. Here is the full ChangeLog: 2008-08-07 Thomas Heller [EMAIL PROTECTED] * Bump version number to 0.5.1 * comtypes\tools\codegenerator.py: Change the order of the interfaces in the _com_interfaces_ and _outgoing_interfaces_ list so that the default interface is the first one. This fixes the bug that GetEvents() and ShowEvents() sometimes did use the wrong event interface. 2008-08-06 Thomas Heller [EMAIL PROTECTED] * The repository was moved from python.org to sourceforge.net. The svn trunk URL is now: https://comtypes.svn.sourceforge.net/svnroot/comtypes/trunk The script that extracted the repository is in admin/extract_comtypes_repo. The repository structure and the revision numbers have changed; the last revision on python.org is rev 65336, this was imported as revision rev 355. 2008-07-18 Thomas Heller [EMAIL PROTECTED] * comtypes\test\find_memleak.py: Windows CE does not have GetProcessMemoryInfo; disable the find_memleak function because it cannot work. * comtypes\client\_generate.py, comtypes\typeinfo.py: Windows CE doesn't have QueryPathOfRegTypeLib - try to emulate it. Also it doesn't use tha PATH environment variable; use a hardcoded search path for type libraries. * comtypes\test\runtests.py: Define a main() function. 2008-05-29 Thomas Heller [EMAIL PROTECTED] * Improved the [in, out] parameter workaround. These parameters are now optional. Removed the special codegeneration for [in, out] parameters in IEnumXXX.Next methods. Added test. 2008-05-16 Thomas Heller [EMAIL PROTECTED] * Provide a workaround for a bug in ctypes. This allows methods using [in, out] parameters to correctly convert native Python values. * comtypes/tools/tlbparser.py: When GetRefTypeInfo(hreftype) fails, emit a warning and generate a fake type instead. 2008-05-07 Thomas Heller [EMAIL PROTECTED] * Fixed the definition of VARIANT.empty and VARIANT.null; the values were swapped. https://sourceforge.net/tracker/?func=detailatid=692940aid=1959722group_id=115265 2008-04-25 Thomas Heller [EMAIL PROTECTED] * Replace logger.info() calls with logger.debug() since it is more appropriate. In comtypes.server.connectionpoints, when a event notification fails with an error indicating that the event sink is no longer present, close the connection and log a warning. The __repr__ of VARIANT changed again to make it a little bit shorter. VARIANT instances of VT_BREF are NOT unpacked when the .value attribute as accessed. The value instead can be got or set by indexing, so the api is the same as for pointer instances: print byref_var[0] byref_var[0] = value 2008-04-17 Thomas Heller [EMAIL PROTECTED] * More changes merged from upstream svn 26400, add support for implementing (non-dual) dispinterfaces (work in progress). * Merge in a lot of changes from the private upstream repository 26394; mainly much better support for implementing comtypes servers. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] How to explain the speed difference?
Kelie schrieb: Thomas Heller [EMAIL PROTECTED] writes: It might be faster to use this code; you sabe one COM call in the loop: item = ms.Item for i in xrange(ms.Count): item(i).Color = 3 Thomas, Thanks for your advice. I tried your suggestion and it does not appear to make a difference in speed compared with the 1st testing method. Btw, I also tested with another scripting language called AutoIt and it is slightly faster than using the 1st testing method. Kelie, It just occurred to me that there is one additional 'feature' in comtypes that may slow down accessing COM properties or calling COM methods: the case insensitivity. Retriving COM properties or methods with the 'incorrect' casing will probably be slower than using the correct casing of the attribute: c = item(i).Color # this should be faster (if 'Color' is the correct spelling) c = item(i).color # this should be slower than the above The reason is that comtypes creates a Python property with the correct name in the instance which can be accessed directly and will be fast. Using the wrong casing will also work but first __getattr__(...) will be called, this will in turn map the property name to the correct spelling and then access the property. Setting the property will ALWAYS go through __setattr__() so will always be slow. All this is determined for each interface by the '_case_insensitive_ = True' code that the codegenerator by default inserts into the modules in comtypes\gen. You can manually replace all these lines with '_case_insensitive_ = False'. This will disable the case-insensitivity and access should be faster. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] thoughts and a patch for dynamic IDispatch
Michael Curran schrieb: In regards to use cases, I guess the reason why I want this functionality is for the main project I am working on, which is the NVDA screen reader, at http://www.nvda-project.org/ In that project we use comtypes very heavily, for MSAA, SAPI, RichEdit controls, etc. But for our support for MS Word and Excel etc, we currently use pywin32. Reason being that with comtypes the COM interfaces are just way too large and take way too long to generate. Pywin32 does a great job with dynamic dispatch, though its just annoying having to use two Python COM implementations in the same project. So this is why I would like to improve comtypes dynamic dispatch support. I have also updated the patch, again, now fixing a few little issues with the non-typeinfo dynamic dispatch support, and more importantly, I have added some more tests to test_dyndispatch.py which tests many of my code changes using MSAA objects. Michael, thanks for the patch and sorry for the late reply. I have now made up my mind and have a plan how I want to integrate this into comtypes. 1. I will add new named parameter to the object creation functions in comtypes.client, CreateObject, GetActiveObject, and CoGetObject. This parameter will be named 'dynamic' and will default to False. If one of these functions is called with 'dynamic = True', then a dynamic dispatch object will be returned (an instance of comtypes.client.dynamic._Dispatch). No wrapper code will be generated, and even if wrapper code is already there it will not be used. 2. It must be made sure that such an object will not trigger the code generation when an attribute is accessed or a method is called. Since all attribute and method access goes through the 'IDispatch.Invoke' implementation in comtypes.automation, the last line in this method (which now is ' return result.value') this is the place where it can be implemented. 'result' is a VARIANT instance, and I will add a new property - maybe result.dyn_value - that will return a dynamic dispatch object. 3. There are some good ideas in your patch for comtypes.client.dynamic - thanks for that. But it seems there are still also a few problems with it which need to be fixed. I will release the current code ASAP as comtypes-0.5.1 before starting with these changes, hopefully it is not too late for you. -- Thanks, Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] in,out parameters in comtypes 0.5 (trunk)
MR Michael Robellard (5314) schrieb: Thomas, Thanks for your help... Worked like a charm... I am not sure why your IE was calling translate from IURLSearchHook instead of TranslateWithSearchContext on IURLSearchHook2 on your machine, but we made the suggested changes to the generated file to a POINTER(c_wchar) and we started getting calls. We had to make a few changes to your suggestion for clearing the buffer and writing it back out because the slice operations weren't working right: def TranslateWithSearchContext(self, this, lpwszSearchURL, cchBufferSize, pSearchContext): # lpwszSearchURL is a POINTER(c_wchar) instance. rawdata = lpwszSearchURL[:cchBufferSize] # rawdata is now a unicode string of length cchBufferSize, filled with NUL characters # at the end. The [in] unicode string can probably be get by this: url = rawdata.split('\0')[0] # Maybe ctypes.wstring_at(lpwszSearchURL) would also work. # The [out] string must be written into the lpwszSearchURL buffer, maybe this works: for i in range(cchBufferSize): lpwszSearchURL[i] = '\0'# clear it urlout = searchgenerator.GenSearchUrl(url, {'f':'web', 'sbs':'1', 'from':'ie'}) for i in range(len(urlout)): if i = cchBufferSize: break lpwszSearchURL[i] = urlout[i] return S_OK Fine, it's great that you got it to work. Maybe sometime I find out why it doesn't work for me... Does codegenerator.py need to be changed to look for 'out' parameters for strings and change them to POINTER(c_wchar) and POINTER(c_char)? Maybe it would be a good idea to let the codegenerator generate POINTER(c_wchar) and POINTER(c_char) instead of STRING == c_char_p and WSTRING == c_wchar_p. You can even patch codegenerator yourself by changing the line 'ASSUME_STRINGS = True' to 'ASSUME_STRINGS = False' in your installation. The real problem is that ctypes (and even C) does not define what 'char *' really means. Sometimes it is a pointer to a single character, sometimes it is a pointer to a character array of a certain size, and sometimes it is a pointer to a NUL-terminated string. Sometimes the buffer is mutable, sometimes not ('char *' vs. 'const char *'). There is no way for the code generator to determine what is correct. The 'ASSUME_STRINGS = True' assumes NUL-terminated strings, which is most often true, but not always. Probably 'ASSUME_STRINGS = False' should be the default, leaving it up to the programmer to tale the correct action. I'll think about it. In the meantime we can keep the generated .py file in another place and use it explicity correct? Sure. That's what I would recommend anyway for interfaces when no type-library is provided. I use the code-generator only to create an initial module, then move this somewhere else, rename it and change it to my needs - most comtypes interface definitions have been created in this way. Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] problem after packaging with py2exe
Kelie schrieb: Hello, I wrote a simple script which uses comtypes. When I run it the first time, it takes some time to generate the module(s) (in the comtypes/gen directory), which is normal. comtypes creates the modules on the first time they are needed (which is usually when you call comtypes.client.CreateObject(MyProgId). If possible, they are written into the comtypes\gen directory. When I run the code again, the step of generating module(s) is skipped. Because they are now found in the comtypes\gen directory. But after I package the program into an executable with py2exe, it re-generates the module(s) every time I run the exe. Apparently the modules in comtypes\gen have not been included into the exe, so comtypes needs to generate them again. Now, since in the exe the comtypes library is inside the zipfile (library.zip or so), comtypes cannot write the generated code into the zipfile; the code is only kept in memory. and it has to be generated again each time your exe runs. Apparently it is not the case using PyWin32, or at least I cannot notice the delay. PyWin32 generates the code (if any) into a writeable directory somewhere else - I will change comtypes to also use another directory in a future version as well so that generated code can be cached in the filesystem even for a py2exe'd program. I'm not sure if this is related to its dynamic IDispatch feature that Michael mentioned in this post: http://article.gmane.org/gmane.comp.python.comtypes.user/192. Not really. Michael wants comtypes to work without generating code at all (for some objects, at least). Here's a walkthrough with a simple comtypes client program. This script creates a JScript interpreter and uses it to evaluate and print a JScript expression: script from comtypes.client import CreateObject if __name__ == __main__: p = CreateObject(uMSScriptControl.ScriptControl) p.Language = uJScript print repr(p.Eval(u'foobar' + 42.0)) script/ The first time you run it, the output is this: C:\py25 js.py # Generating comtypes.gen._0E59F1D2_1FBE_11D0_8FF2_00A0D10038BC_0_1_0 # Generating comtypes.gen._00020430___C000_0046_0_2_0 # Generating comtypes.gen.stdole # Generating comtypes.gen.MSScriptControl u'foobar42' C:\ Running it again, the only output is (since code generation is skipped now): C:\py25 js.py u'foobar42' C:\ Ok, write a trivial setup.py file for py2exe and let it create the exe. Run the exe several times; the code is generated each time: C:\py25 setup.py py2exe . C:\dist\js.exe # Generating comtypes.gen._0E59F1D2_1FBE_11D0_8FF2_00A0D10038BC_0_1_0 # Generating comtypes.gen._00020430___C000_0046_0_2_0 # Generating comtypes.gen.stdole # Generating comtypes.gen.MSScriptControl u'foobar42' C:\dist\js.exe # Generating comtypes.gen._0E59F1D2_1FBE_11D0_8FF2_00A0D10038BC_0_1_0 # Generating comtypes.gen._00020430___C000_0046_0_2_0 # Generating comtypes.gen.stdole # Generating comtypes.gen.MSScriptControl u'foobar42' C:\ Ok, let's advise py2exe to include the comtypes.gen.MSScriptControl module: script from comtypes.client import CreateObject import comtypes.gen.MSSciptControl # so that py2exe includes this module in the exe if __name__ == __main__: p = CreateObject(uMSScriptControl.ScriptControl) p.Language = uJScript print repr(p.Eval(u'foobar' + 42.0)) script/ Make a new exe and run it: C:\py25 setup.py py2exe . C:\dist\js.exe u'foobar42' C:\js.exe u'foobar42' C:\ Now, the final refinement (what I usually do) is to make sure that the comtypes.gen.MSScriptControl is recreated when I have cleaned up my comtypes.gen directory. Looking into comtypes.gen.MSScriptControl, then into comtypes.gen._0E59F1D2_1FBE_11D0_8FF2_00A0D10038BC_0_1_0 I find that the type library is 'c:\Windows\System32\msscript.ocx'. So I can use comtypes.client.GetModule(typelib_path) to generate the module even without or BEFORE actually creating the COM object. The final script is this: script import sys if not hasattr(sys, frozen): from comtypes.client import GetModule GetModule(umsscript.ocx) from comtypes.gen import MSScriptControl from comtypes.client import CreateObject if __name__ == __main__: p = CreateObject(uMSScriptControl.ScriptControl) p.Language = uJScript print repr(p.Eval(u'foobar' + 42.0)) script/ Explanation: The executables that py2exe creates have attached a 'frozen' attribute to the 'sys' module, which is not present in a normal Python interpreter. This is the easiest way to determine whether a script is running with Python or as exe. So, when running the script with Python, GetModule(msscript.ocx) is called which generates the comtypes.gen.MSScriptControl module unless it is already present. py2exe sees that comtypes.gen.MSScriptControl is imported and includes this module (plus that modules that this one references) into the exe. When the exe runs, the GetModule step is
Re: [comtypes-users] in,out parameters in comtypes 0.5 (trunk)
MR Michael Robellard (5314) schrieb: Hello, I am trying to implement the IURLSearchHook2 interface in comtypes and I am running into some issues. which generate the following in the comtypes.gen .py files: class IURLSearchHook2(IURLSearchHook): _case_insensitive_ = True _iid_ = GUID('{5EE44DA4-6D32-46E3-86BC-07540DEDD0E0}') _idlflags_ = [] IURLSearchHook2._methods_ = [ COMMETHOD([], HRESULT, 'TranslateWithSearchContext', ( ['in', 'out'], WSTRING, 'lpwszSearchURL' ), ( ['in'], c_ulong, 'cchBufferSize' ), ( ['in'], POINTER(ISearchContext), 'pSearchContext' )), ] I can get the data into the method and print it out fine. The problem is when I try and return a string out. It just plain hangs. If anyone has any thoughts. Is this even possible? I have tried both the high level and low level approach as discussed in Thomas' recent post Mike, here are my thoughts on your problem. The high level comtypes method implementation can only work for automation-compatible argument types, and WSTRING is not one of those. WSTRING is defined as c_wchar_p in the generated file. c_wchar_p is interpreted as a zero-terminated wide character string, but what COM really passes is a buffer with space for 'cchBufferSize' wide characters. Which contains a zero-terminated string that you are supposed to change. comtypes assumes c_wchar_p as 'const' strings which you cannot/should not change. I think you should change the 'TranslateWithSearchContext' method definition to something like this: IURLSearchHook2._methods_ = [ COMMETHOD([], HRESULT, 'TranslateWithSearchContext', ( ['in', 'out'], POINTER(c_wchar), 'lpwszSearchURL' ), ( ['in'], c_ulong, 'cchBufferSize' ), ( ['in'], POINTER(ISearchContext), 'pSearchContext' )), ] and write the (low-level) implementation like so: def TranslateWithSearchContext(self, this, lpwszSearchURL, cchBufferSize, pSearchContext): # lpwszSearchURL is a POINTER(c_wchar) instance. rawdata = lpwszSearchURL[:cchBufferSize] # rawdata is now a unicode string of length cchBufferSize, filled with NUL characters # at the end. The [in] unicode string can probably be get by this: url = rawdata.split('\0')[0] # Maybe ctypes.wstring_at(lpwszSearchURL) would also work. # The [out] string must be written into the lpwszSearchURL buffer, maybe this works: lpwszSearchURL[:cchBufferSize] = '\0' * cchBufferSize # clear it urlout = http://web.somewhere.whatdoIknow; lpwszSearchURL[:len(urlout)] = urlout return S_OK Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] thoughts and a patch for dynamic IDispatch
Michael Curran schrieb: Hi Tim, I wasn't aware Thomas was away, thanks for letting me know. He just suggested to me the other week that I should join and start a discussion on here about the patch. In regards to use cases, I guess the reason why I want this functionality is for the main project I am working on, which is the NVDA screen reader, at http://www.nvda-project.org/ In that project we use comtypes very heavily, for MSAA, SAPI, RichEdit controls, etc. But for our support for MS Word and Excel etc, we currently use pywin32. Reason being that with comtypes the COM interfaces are just way too large and take way too long to generate. Michael, I can understand that you feel like this, however let me play devils advocate. The code generation takes long, sure, but it is only done once. Also, you *could* generate when building the distribution and distribute them with your own code anyway. And what's the problem with the size? The NVDA zipfile is 11 MB, and the installer is 8.4 MB already, are a few MB more such a big deal? The problem with (parts of) your patch is that I fear there will be different behaviour in code using comtypes depending on what the 'disableCodeGeneration' current value is (and the *user* of our code is controlling the value of this variable), and additionally different behaviour depending on whether generated code is present or not even if the code generation is disabled. I can imagine several ways to fix that, possibly allowing the programmer to choose between dynamic dispatch and the custom part of dual interfaces: 1. It may be possible to explicitely specify that you want a dynamic object on COM object creation. Maybe introducing a comtypes.client.Dispatch() function in addition to comtypes.client.CreateObject(), similarly for the other creation function comtypes.client.GetActiveObject(). The returned *dynamic* dispatch objects/interfaces would probably have an attribute that prevented code generation for anything retrived from them. 2. Another approach would be to always use the automation interface if the object supports it. There may be other ways that escape me at the moment. Pywin32 does a great job with dynamic dispatch, though its just annoying having to use two Python COM implementations in the same project. So this is why I would like to improve comtypes dynamic dispatch support. I have also updated the patch, again, now fixing a few little issues with the non-typeinfo dynamic dispatch support, and more importantly, I have added some more tests to test_dyndispatch.py which tests many of my code changes using MSAA objects. Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] thoughts and a patch for dynamic IDispatch
Michael Curran schrieb: Hi Tim, I wasn't aware Thomas was away, thanks for letting me know. He just suggested to me the other week that I should join and start a discussion on here about the patch. I thought that other users (there aren't so many, yet) would have opinions on this. Thomas - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Problems reading properties
Björn Swift schrieb: I've been playing around with comtypes for the last few days and ran into some trouble reading COM Properties. The COM in question is Microsoft.Hpc.Scheduler.Scheduler and this is the Python code executed: from comtypes.client import CreateObject scheduler = CreateObject(Microsoft.Hpc.Scheduler.Scheduler) scheduler.Connect(corecluster00) job = scheduler.CreateJob() task = job.CreateTask() task.commandLine = rmpiexec -n 4 ping -n 15 bjorns-ws job.AddTask(task) scheduler.SubmitJob(job, None, None) Björn, can you say a few words about what this hpc stuff is? An add-on for Windows Server 2008? Now we want to take a look at the job object and figure out the Job ID. job POINTER(ISchedulerJob) ptr=0x767ffd0 at 3496770 job.id 124256112 job.id 124256080 job.id 124256048 Strange, an ever changing ID. Trying the _ISchedulerJob__com__get_id function: import ctypes i = ctypes.c_long() job._ISchedulerJob__com__get_id(ctypes.byref(i)) i c_long(124256016) job._ISchedulerJob__com__get_id(ctypes.byref(i)) i c_long(124255984) Basically the same result. Both the direct attribute access job.id and job._ISchedulerJob__com__get_id() use the same mechanism internally, only the calling convention is different so it is no wonder that they return the same result. But what happens if I use IDispatch'ers Invoke ? job.Invoke(1610743834, _invkind=2) 184 Bingo, the correct job ID ! The same goes for other properties, such as job.State: job.State -1164233603 job.Invoke(1610743851, _invkind=2) 128 The dispatch ids are correct in the autogenerated Python classes (as per job.GetIDsOfNames output). I tried to chase down what was causing the error, but as I'm not familiar with comtypes internals I got a bit lost. I attempted to get from accessing job.id to IDispatch's Invoke() without luck. from comtypes.gen._C45D10A1_54E8_420B_A052_719D47EC7C16_0_2_0 import ISchedulerJob ISchedulerJob.id ISchedulerJob.id.fget COM method offset 28: WinFunctionType at 0x03F964B8 Does job.id perhaps not use the Dispatch interface ? No, by default comtypes uses the custom interface when it is available. As there seems to be an issue with Microsoft.Hpc.Scheduler.dll (beta 2) causing my Python debugger to crash on breakpoints, tracing the steps from A to B therefore makes up for a fun manual labor step-through process ;) Perhaps you can identify the problem or point me in the right direction? Can you please post the IDL of this interface, and also the generated code for it? Maybe I'm able to spot something... -- Thanks, Thomas - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
[comtypes-users] What's going on in the SVN repository
I have made some larger changes in the SVN trunk; maybe a little bit early since I started it some weeks ago and it is not yet ready. The trunk version number has been changed to 0.5, but I have also created a comtypes-0.4 branch where I still make small fixes and also plan to make further maintainance releases. So, what's new it 0.5? -- I have committed a new way to implement COM objects with comtypes. Unfortunately there are some backwards incompatible changes that I will describe below. In 0.5, there are two ways to implement COM methods. The first way is high-level that should normally be used. You simply write a method just as you would do in a normal Python object. The method will receive [in] and [in, out] parameters as usual, marshalled as normal Python objects like (unicode) strings, integers, floats, lists or tuples. The method should do its processing, and it should return nothing (= None), a single Python value, or a tuple containing multiple Python values, depending on the [out] parameters that the COM method expects. Exceptions that occur in the code will automatically be converted to HRESULT values which are returned via COM to the caller; in addition exception information will be set that can also be retrieved by the caller. COM attributes are implemented by implementing normal Python attributes, either directly in the class or by implementing a Python property. The second possibility is to write a low-level COM method. This method will be called with all [in], [in, out] and [out] parameters. The [in] parameters will already be converted to Python objects (int, string, and so on), but [in, out] or [out] parameters will be passed as ctypes or comtypes pointer instances. The method implementation must return an integer HRESULT value (or None, which has the same meaning as S_OK), the [in, out] parameters must be retrieved from the pointer and the return values must be set into the pointer object to be returned to the caller. COM attributes are implemented by writing both a setter and a getter method, named get_name and set_name. Now comes the strange part ;-): comtypes inspects the method parameter names to determine whether a low-level or a high level method has been implemented. Low-level implementations MUST have a second parameter (self is the first) that has the name 'this', high-level methods MUST have no second parameter or it must have a different name. To give an example: Consider the ITypeLib::GetTypeInfo method. The IDL signature would be: HRESULT GetTypeInfo( [in] unsigned int index, [out] ITypeInfo FAR* FAR* ppTInfo ); The high-level comtypes implementation would be like this (assuming that 'some_typeinfo' is a sequence of ITypeInfo pointers): def GetTypeInfo(self, index): return some_typeinfo[index] and the low-level code would look like this: def GetTypeInfo(self, this, index, pptinfo): pptinfo[0] = some_typeinfo[index] return S_OK Events: The above description also applies to COM events. A COM event receiver is a COM interface implementation - the COM methods of the interface are the event handlers that you implement. Backwards (in)compatibility: These changes are *mostly* backwards compatible, assuming that your event handlers have a second parameter named 'this'. An incompatibility occurs with VARIANT BYREF parameters. Up to comtypes 0.4.x, VARIANT BYREF parameters have been fully dereferenced before they are passed to event handler implementations. Since the new way requires that pointer-like objects are passed to low level implementations, this cannot be done anymore. An example of this is the BeforeNavigate() event of InternetExplorer. The C signature of this method is: void BeforeNavigate( [in] IDispatch *pDisp, [in] VARIANT *url, [in] VARIANT *Flags, [in] VARIANT *TargetFrameName, [in] VARIANT *PostData, [in] VARIANT *Headers, [in, out] VARIANT_BOOL *Cancel ); Although only the last parameter is an [out] parameter (the others are not), all are passed as byref params. So, both the low-level and the high-level method will, in comtypes 0.5, be called with VARIANT instances containing BYREF values for the 2nd up to the 6th parameter. In comtypes 0.4, the 2nd up to the 7th parameters would have been passed as strings, integers, None, or bool. That's enough blurb for now; any comments, and does the above make sense? -- Thanks, Thomas - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] passing GUIDs by value works on 32-bit python but not 64-bit python (on Vista 64)
[EMAIL PROTECTED] schrieb: [passing GUIDs by value works on 32-bit python but not 64-bit python (on Vista 64)] Seems to stomp memory. I'm not a native english speaker and do not understand what you mean. Also, can you give a description or a code sample to illustrate the problem? Best would be if you can submit a test case. A work around is to declare the parameter as a POINTER(GUID) instead of GUID and pass a copy of the GUID instance byref [this should be what happens under the covers]. I'm not sure if this is a comtypes or ctypes issue; it likely applies to other large datatypes as well. I'm using python-2.5.2.amd64.msi, ctypes-1.0.2.win32-py2.5-AMD64.msi and comtypes-0.4.2.zip. Peter -- Thanks, Thomas - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] catching context menu event from html document
Robin Dunn schrieb: I've got a comtypes based activex container for wxPython[1], and I'm trying to find a way to prevent the default context menu in an IWebBrowser2 control. Cool. After some googling it seems from some VB sites[2] that there should be a OnContextMenu event coming from the document object, but I can't seem to be able to catch it using comtypes. When I try using GetEvents on the document property it just gives me an exception. cc.GetEvents(ie.ctrl.Document, t) Traceback (most recent call last): File input, line 1, in module File c:\tools\python25\lib\site-packages\comtypes-0.5.0a-py2.5.egg\comtypes\client\_events.py, line 132, in GetEvents interface = FindOutgoingInterface(source) File c:\tools\python25\lib\site-packages\comtypes-0.5.0a-py2.5.egg\comtypes\client\_events.py, line 52, in FindOutgoingInterface interface = comtypes.com_interface_registry[str(guid)] KeyError: '{----}' This looks like the Document object implements IProvideClassInfo2 interface, but IProvideClassInfo2::GetGUID() returns a NULL guid. comtypes should probably catch this, but the net effect is that one cannot determine the outgoing interface. Fortunately, with a little bit browsing through the comtypes.gen.MSHTML module (really the comtypes.gen._3050F1C5_98B5_11CF_BB82_00AA00BDCE0B_0_4_0 module) and guessing I found that both the HTMLDocumentEvents or HTMLDocumentEvents2 interface seems to work, you just have to pass that interface to GetEvents/ShowEvents. This script works for me: from comtypes.client import CreateObject, GetEvents, ShowEvents, PumpEvents ie = CreateObject(InternetExplorer.Application) ie.Visible = True ie.Navigate2(http://www.python.org;) PumpEvents(1) # give the page a chance to load doc = ie.Document from comtypes.gen import MSHTML print doc evt = ShowEvents(doc, interface=MSHTML.HTMLDocumentEvents2) PumpEvents(10) and here is some sample output: c:\svn\theller\comtypes-0.4py25 docevents.py POINTER(DispHTMLDocument) ptr=0x277764 at 180e7b0 # event found: HTMLDocumentEvents2_onstop # event found: HTMLDocumentEvents2_onbeforeeditfocus # event found: HTMLDocumentEvents2_onbeforeupdate # event found: HTMLDocumentEvents2_onafterupdate # event found: HTMLDocumentEvents2_onrowexit # event found: HTMLDocumentEvents2_onrowenter # event found: HTMLDocumentEvents2_onmouseover # event found: HTMLDocumentEvents2_onmouseout # event found: HTMLDocumentEvents2_onhelp # event found: HTMLDocumentEvents2_ondragstart # event found: HTMLDocumentEvents2_onselectstart # event found: HTMLDocumentEvents2_onerrorupdate # event found: HTMLDocumentEvents2_ondatasetchanged # event found: HTMLDocumentEvents2_ondataavailable # event found: HTMLDocumentEvents2_ondatasetcomplete # event found: HTMLDocumentEvents2_onpropertychange # event found: HTMLDocumentEvents2_onactivate # event found: HTMLDocumentEvents2_ondeactivate # event found: HTMLDocumentEvents2_onbeforeactivate # event found: HTMLDocumentEvents2_onfocusin # event found: HTMLDocumentEvents2_onfocusout # event found: HTMLDocumentEvents2_onreadystatechange # event found: HTMLDocumentEvents2_onrowsdelete # event found: HTMLDocumentEvents2_onmouseup # event found: HTMLDocumentEvents2_onmousemove # event found: HTMLDocumentEvents2_onmousedown # event found: HTMLDocumentEvents2_onkeyup # event found: HTMLDocumentEvents2_onkeypress # event found: HTMLDocumentEvents2_onkeydown # event found: HTMLDocumentEvents2_ondblclick # event found: HTMLDocumentEvents2_onclick # event found: HTMLDocumentEvents2_onmousewheel # event found: HTMLDocumentEvents2_onbeforedeactivate # event found: HTMLDocumentEvents2_onrowsinserted # event found: HTMLDocumentEvents2_oncontrolselect # event found: HTMLDocumentEvents2_oncellchange # event found: HTMLDocumentEvents2_onselectionchange # event found: HTMLDocumentEvents2_oncontextmenu Event HTMLDocumentEvents2_onreadystatechange(None, POINTER(DispCEventObj) ptr=0x272fa4 at 39e4ee0) Event HTMLDocumentEvents2_onmouseout(None, POINTER(DispCEventObj) ptr=0x27568c at 39e4da0) Event HTMLDocumentEvents2_onmousemove(None, POINTER(DispCEventObj) ptr=0x272f6c at 39e4f30) Event HTMLDocumentEvents2_onmouseover(None, POINTER(DispCEventObj) ptr=0x2755dc at 39e4d50) Event HTMLDocumentEvents2_onmousemove(None, POINTER(DispCEventObj) ptr=0x272eb4 at 39e4d00) Event HTMLDocumentEvents2_onmousemove(None, POINTER(DispCEventObj) ptr=0x27328c at 39e4c60) Event HTMLDocumentEvents2_onmousemove(None, POINTER(DispCEventObj) ptr=0x273a84 at 39e4c10) Event HTMLDocumentEvents2_onmousemove(None, POINTER(DispCEventObj) ptr=0x2755dc at 39e4ee0) Event HTMLDocumentEvents2_onmousemove(None, POINTER(DispCEventObj) ptr=0x272eb4 at 39e4da0) Event HTMLDocumentEvents2_onmousemove(None, POINTER(DispCEventObj) ptr=0x273a84 at 39e4f30) Event HTMLDocumentEvents2_onmousemove(None, POINTER(DispCEventObj) ptr=0x272f6c at 39e4d50) Event HTMLDocumentEvents2_onmousemove(None,
Re: [comtypes-users] SMARTPOINTER SNAFU revisted
Thomas Heller schrieb: I do not remember exactly how I managed to remove the contents attribute from POINTER(ISomeInterface), or how I prevented indexing. It makes no sense to dereference a COM pointer, the only interesting things that you can do with a COM pointer is to call methods on it. Well, now I know again. The ctypes baseclass of POINTER(ISomeInterface) is c_void_p; c_void_p does not support indexing nor has a .contents attribute so there was nothing to disable or to remove. The only public attribute of c_void_p instances is a .value attribute; for COM interface pointer classes this is redefined to return 'self'. -- Thomas - This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse012070mrt/direct/01/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
[comtypes-users] problem with [in, out] arguments (Was: SMARTPOINTER SNAFU revisted)
Matt Wilbur schrieb: I may be saved. I'm still not sure exactly why, though. My explanation will follow. After some desperate tracing, I found something that works ( I found an 'if' statement when calling the method which always went down one path when I passed in an LP_LP_c_double instance. I forced it down the other path by passing in an instance of LP_SAFEARRAY_c_double, as shown below): import ctypes import comtypes.safearray as safearray safearray module 'comtypes.safearray' from 'C:\Python25\lib\site-packages\comtypes\safearray.pyc' itrace = bench.SA.Traces[u'Trace1'] itrace POINTER(IIviSpecAnTrace) ptr=0x2216610 at 107a8a0 AmplitudeType = safearray._midlSAFEARRAY(ctypes.c_double) AmplitudeType class 'ctypes.LP_SAFEARRAY_c_double' amplitude = AmplitudeType() amplitude ctypes.LP_SAFEARRAY_c_double object at 0x00FB3DF0 itrace.FetchY(amplitude) ctypes.LP_SAFEARRAY_c_double object at 0x00FB3DF0 and amplitude.unpack() gives me what I was looking for all along. The intent of comtypes is that you can pass a sequence (list/tuple) of integers when a SAFEARRAY* of integers is expected by a COM method. This actually works (but only for [in] parameters, not for [in, out] parameters). How does it work? When you pass some Python object 'value' as argument to a COM method, the required argument type's .from_param(value) classmethod is called with this object, and the result is passed to the raw COM method. Usually the .from_param(value) implementation checks if 'value' already is an instance of the required type, if so it is used unchanged. If it is not (for example, 'value' is a sequence when a SAFEARRAY is required) then .from_param() calls a conversion function which will usually build the required ctype from it. So far, so good. With [in, out] parameters additional processing of arguments is required. comtypes (actually ctypes) scans the arguments passed to a function/method call, marks [in, out] parameters, and constructs and marks [out] parameters so that the return value can be retrieved from them after the COM method call has been done. The problem/bug is that the processing for [in, out] parameters is in the wrong order. First the marking of [in, out] parameters is done, after that the .from_param() conversion is done. This is the wrong order, because the return value(s) must be retrieved from the converted parameters, not from the unconverted ones. So, this is a ctypes bug which can only be fixed in the next Python version (2.6, and hopefully in the next 2.5.3 release). I hope that is is possible to build a workaround into comtypes so that it works as expected with the current Python/ctypes version. Fortunately Matt found a workaround that can even be used *now*: [in, out] parameters should not be passed as normal Python objects (tuple, list for SAFEARRAY), but as instances of the required argument type as he posted above. Hopefully this workaround will also solve Mustafa's problem; see the post titled 'Create a SAFEARRAY with COM pointer by reference'. -- Thanks, Thomas - This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse012070mrt/direct/01/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Draw a point in AutoCAD using comtypes
Kelie schrieb: Hello, First of all, I suppose most users on this list would have no interest in this topic. But I'm posting it anyway because it has puzzled for quite a while and finally thanks to Thomas who found a solution. I also want to thank Ed Blake who showed me a solution with win32com. The question started with how to pass the right parameter to AutoCAD's AddPoint function. It is supposed to be Variant (three-element array of doubles) according to the VBA API reference. The array.array function was the answer: import array import comtypes.client acadApp = comtypes.client.GetActiveObject(AutoCAD.Application) ms = acadApp.ActiveDocument.ModelSpace pt = array.array('d', [0,0,0]) ms.AddPoint(pt) print Done. The reason for this is the following. Acad declares the AddPoint method with this signature: [id(0x061a), helpstring(Creates a Point object at a given location), helpcontext(0x00010097)] HRESULT _stdcall AddPoint( [in] VARIANT Point, [out, retval] IAcadPoint** pPoint); so it expects a VARIANT specifying the Point coordinates. A VARIANT can contain a lot of different data types; it is unspecified above that Autocad only accepts a VARIANT containing a SAFEARRAY of doubles. By default, when you pass a Python sequence (tuple or list) for this parameter comtypes constructs a VARIANT containing a SAFEARRAY of VARIANTS. When you pass an array.array instance for the parameter, comtypes constructs a VARIANT containing a SAFEARRAY of type VT_R8 if the typecode of the array is 'd' (double), VT_R4 for the typecode 'f' (float), and so on. I assume this is the same for a lot of com servers requiring a VARIANT containing a SAFEARRAY. Thomas - This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] problem using comtypes with AutoCAD
Ed Blake schrieb: I just tested under comtypes 0.3 and 0.4 with Autocad 2008. I get this exception for both when using CreateObject: ## acad = client.CreateObject(AutoCAD.Application) Traceback (most recent call last): File input, line 1, in module File D:\Python25\Lib\site-packages\comtypes\client\__init__.py, line 203, in CreateObject return _manage(obj, clsid, interface=interface) File D:\Python25\Lib\site-packages\comtypes\client\__init__.py, line 171, in _manage obj = wrap(obj) File D:\Python25\Lib\site-packages\comtypes\client\__init__.py, line 122, in wrap typeattr = tinfo.GetTypeAttr() File D:\Python25\Lib\site-packages\comtypes\typeinfo.py, line 262, in GetTypeAttr return _deref_with_release(self._GetTypeAttr(), self.ReleaseTypeAttr) COMError: (-2147418111, 'Call was rejected by callee.', (None, None, None, 0, None)) ## I think this happens because comtypes is trying to talk to Autocad before it is finished its post startup initialization (loading modules, CUI, lisp files). Hm, is this a bug in Autocad, or is comtypes behaving wrong here; does this error code mean we have to wait a little and retry the call? How do other COM clients, like VB or pywin32, behave? Using client.GetActiveObject on the other hand successfully generates the Autocad modules and returns a pointer to the first running instance. It doesn't work if Autocad isn't running though. BTW Thomas: I had to switch back to version 0.3.3 because something broke between that version and the current. With this remark I assume you mean the code below, right? When I try to get a pointer to Microstation under 0.4.1 I get this: ## usta = client.GetActiveObject(MicroStationDGN.Application) # Generating comtypes.gen._CF9F97BF_39F2_4B8E_835C_8BE9E99DAF5B_0_8_0 Traceback (most recent call last): File input, line 1, in module File D:\Python25\Lib\site-packages\comtypes\client\__init__.py, line 166, in GetActiveObject return _manage(obj, clsid, interface=interface) File D:\Python25\Lib\site-packages\comtypes\client\__init__.py, line 171, in _manage obj = wrap(obj) File D:\Python25\Lib\site-packages\comtypes\client\__init__.py, line 134, in wrap mod = GetModule(tlib) File D:\Python25\lib\site-packages\comtypes\client\_generate.py, line 100, in GetModule is_current, mod = _CreateWrapper(tlib, pathname) File D:\Python25\lib\site-packages\comtypes\client\_generate.py, line 218, in _CreateWrapper mod = _my_import(fullname) File D:\Python25\lib\site-packages\comtypes\client\_generate.py, line 14, in _my_import return __import__(fullname, globals(), locals(), ['DUMMY']) File D:\Python25\lib\site-packages\comtypes\gen\_CF9F97BF_39F2_4B8E_835C_8BE9E99DAF5B_0_8_0.py, line 223, in module ( ['retval', 'out'], POINTER(_midlSAFEARRAY(POINTER(_DataBlock))), 'pVal' )), File D:\Python25\Lib\site-packages\comtypes\safearray.py, line 18, in _midlSAFEARRAY sa_type = _make_safearray_type(itemtype) File D:\Python25\Lib\site-packages\comtypes\safearray.py, line 46, in _make_safearray_type raise TypeError(itemtype) TypeError: class 'comtypes.POINTER(_DataBlock)' ## Something to do with the safearray refactor? In comtypes 0.4.1, safearrays containing com pointers are not implemented. They are, though, in the current SVN version. I wanted to release the next version after another MicroStation bug was examined, but the OP did not yet respond to my question. Maybe you can help; or I should release anyway? See http://sourceforge.net/tracker/index.php?func=detailaid=1919272group_id=115265atid=692940 Thomas - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] 'parameter not optional' problem
Jens schrieb: Hello Thomas, (now to correct list address...) That's great... Many thanks for the answer but unfortunately it does not help. and this is not so great ;-). I'm not experienced with (D)COM. As I see if I want to use the CoClass (resp. QueryInterface) I have to do this from comtypes.gen import AutomaticTesting #help (AutomaticTesting.AutomaticTesting) self.__appl=CreateObject(AutomaticTesting.AutomaticTesting) print self.__appl.SendService(1101).Value() but I get the same error parameter not optional as well as when I use QueryInterface: from comtypes.gen import AutomaticTesting instance=comtypes.CoCreateInstance(self.CLSID) self.__appl =instance.QueryInterface(AutomaticTesting.IAutomaticTesting) print self.__appl.SendService(1101).Value() print self.__appl.SendService(1101).Value() File C:\Programs\Python25\Lib\site-packages\comtypes\__init__.py, line 414, in func return self.Invoke(obj, memid, _invkind=1, *args, **kw) # DISPATCH_METHOD File C:\Programs\Python25\Lib\site-packages\comtypes\automation.py,line 596, in Invoke byref(result), byref(excepinfo), byref(argerr)) _ctypes.COMError: (-2147352561, 'Parameter nicht optional.', (None, None,None, 0, None)) The easiest way for me to further examine this problem would be if I install this com object on my own machine. Is this possible? Thanks, Thomas - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] GetModule gen_dir import
Roman Yakovenko schrieb: On Feb 12, 2008 11:06 PM, Thomas Heller [EMAIL PROTECTED] wrote: Here is a fix for this problem: Index: comtypes/client/_generate.py === --- comtypes/client/_generate.py(revision 59545) +++ comtypes/client/_generate.py(working copy) @@ -11,6 +11,10 @@ def _my_import(fullname): # helper function to import dotted modules +import comtypes.gen +if comtypes.client.gen_dir \ + and comtypes.client.gen_dir not in comtypes.gen.__path__: +comtypes.gen.__path__.append(comtypes.client.gen_dir) return __import__(fullname, globals(), locals(), ['DUMMY']) def _name_module(tlib): Thanks. If I understand right the code, I will not have to modify sys.path . Am I right? I added the gen_dir to comtypes.gen.__path__ so that the codegenerator itself can import the new module itself after creation. So, if you later want to import the module as part of the comtypes.gen package, you will probably have to extend comtypes.gen.__path__ yourself somewhere in your own code. The purpose of changing gen_dir was two use cases: - allow dynamic module generation only in memory (for py2exe'd applications where comtypes.gen lives inside a zipfile), - or (but this is totally untested) care about cases where the comtypes.gen directory is unwritable. It may be that both use cases do not yet work as intended. If you want to create the module somewhere else so that you can manually change it or whatever, you should better move it to a private package directory, and rename it. That's what I do, and that's how many of the modules in comtypes were born. Thomas - This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse012070mrt/direct/01/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] GetModule gen_dir import
Roman Yakovenko schrieb: I am trying to generate module to custom directory and the process fails with next error: # Generating comtypes.gen._106173A0_0173_4E5C_84E7_E915422BE997_0_2_0 # Generating comtypes.gen._00020430___C000_0046_0_2_0 Traceback (most recent call last): File pdb_reader.py, line 12, in module print comtypes.client.GetModule( r'D:\Program Files\Microsoft Visual Studio .NET 2003\Visual Studio SDKs\DIA SDK\bin\msdia71.dll' ) File e:\python25\Lib\site-packages\comtypes\client\_generate.py, line 100, in GetModule is_current, mod = _CreateWrapper(tlib, pathname) File e:\python25\Lib\site-packages\comtypes\client\_generate.py, line 206, in _CreateWrapper generate_module(tlib, ofi, pathname) File e:\python25\Lib\site-packages\comtypes\tools\tlbparser.py, line 704, in generate_module gen.generate_code(items.values(), filename=pathname) File e:\Python25\Lib\site-packages\comtypes\tools\codegenerator.py, line 239, in generate_code self.generate_all(sorted(items, self.cmpitems)) File e:\Python25\Lib\site-packages\comtypes\tools\codegenerator.py, line 181, in generate_all self.generate(item) File e:\Python25\Lib\site-packages\comtypes\tools\codegenerator.py, line 177, in generate mth(item) File e:\Python25\Lib\site-packages\comtypes\tools\codegenerator.py, line 616, in External comtypes.client.GetModule(ext.tlib) File e:\python25\Lib\site-packages\comtypes\client\_generate.py, line 100, in GetModule is_current, mod = _CreateWrapper(tlib, pathname) File e:\python25\Lib\site-packages\comtypes\client\_generate.py, line 218, in _CreateWrapper mod = _my_import(fullname) File e:\python25\Lib\site-packages\comtypes\client\_generate.py, line 14, in _my_import return __import__(fullname, globals(), locals(), ['DUMMY']) ImportError: No module named _00020430___C000_0046_0_2_0 Here is the relevant source code: import os import sys import comtypes import comtypes.client gen_dir = r'D:\dev\xyz' sys.path.append( gen_dir ) comtypes.client.gen_dir = gen_dir print comtypes.client.GetModule( r'D:\Program Files\Microsoft Visual Studio .NET 2003\Visual Studio SDKs\DIA SDK\bin\msdia71.dll' ) Thanks Here is a fix for this problem: Index: comtypes/client/_generate.py === --- comtypes/client/_generate.py(revision 59545) +++ comtypes/client/_generate.py(working copy) @@ -11,6 +11,10 @@ def _my_import(fullname): # helper function to import dotted modules +import comtypes.gen +if comtypes.client.gen_dir \ + and comtypes.client.gen_dir not in comtypes.gen.__path__: +comtypes.gen.__path__.append(comtypes.client.gen_dir) return __import__(fullname, globals(), locals(), ['DUMMY']) def _name_module(tlib): Thanks, Thomas - This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse012070mrt/direct/01/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Generated Python code contains error?
Roman Yakovenko schrieb: On Feb 12, 2008 10:48 PM, Thomas Heller [EMAIL PROTECTED] wrote: Roman Yakovenko schrieb: Hi. I looked on generated code for msdia71.dll and this is what I found: # values for enumeration 'SymTagEnum' ... SymTagEnum = 12 ... SymTagEnum = c_int # enum I guess there is a mistake here. Well, yes. I always has the desire to define a proper enum type for ctypes, but it will probably break too much code (and I haven't yet encountered an enum type that has the same type name as one of its values). What I imagined was something like this: class SymTagEnum(c_enum): SymTagNull = 0 SymTagExe = 1 SymTagCompiland = 2 SymTagCompilandDetails = 3 SymTagCompilandEnv = 4 SymTagFunction = 5 SymTagBlock = 6 ... but of course this would add another namespace to access the enum values. This is not as bad as you think about it. It will follow pretty close C++ examples/usage. No, it would not be bad, but IMO it's too late. I have too much code that accesses enums in typelib wrappers already. I'll think it over. Thomas - This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse012070mrt/direct/01/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] GetModule error
Roman Yakovenko schrieb: Unfortunately I have very basic COM knowledge and I thought, may I say expected :-) , comtypes will keep me long away from it. I will check the new versions, may be they don't have such problems. I will let you know. As I said, I'll have to investigate further. The problem with msdia71.dll is not yet solved. I will post here when I know more (but don't hold your breath). Thomas - This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse012070mrt/direct/01/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] GetModule error
Roman Yakovenko schrieb: Good morning. I got error while calling comtypes.client.GetModule function. Here is the call stack: e:\Python25\pythonw.exe -u pdb_reader.py Traceback (most recent call last): File pdb_reader.py, line 8, in module print comtypes.client.GetModule( r'D:\Program Files\Microsoft Visual Studio .NET 2003\Visual Studio SDKs\DIA SDK\bin\msdia71.dll' ) File e:\python25\Lib\site-packages\comtypes\client\_generate.py, line 100, in GetModule is_current, mod = _CreateWrapper(tlib, pathname) File e:\python25\Lib\site-packages\comtypes\client\_generate.py, line 191, in _CreateWrapper return True, imp.load_module(modname, file_, module_path, desc) File e:\Python25\lib\site-packages\comtypes\gen\_106173A0_0173_4E5C_84E7_E915422BE997_0_2_0.py, line 761, in module ( ['out'], POINTER(POINTER(IDiaSymbol)), 'ppSymbol' )), File e:\python25\Lib\site-packages\comtypes\__init__.py, line 239, in __setattr__ self._make_methods(value) File e:\python25\Lib\site-packages\comtypes\__init__.py, line 492, in _make_methods prototype = WINFUNCTYPE(restype, *argtypes) File e:\Python25\lib\ctypes\__init__.py, line 121, in WINFUNCTYPE class WinFunctionType(_CFuncPtr): TypeError: Error when calling the metaclass bases item 5 in _argtypes_ has no from_param method I am using standard Python 2.5 installation with ctypes module, which comes with it. I am using SVN version of comtypes. The interfaces, I try to access, are derived from IUnknown one. I can reproduce the problem, and will lokk into it. Thanks, Thomas - This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse012070mrt/direct/01/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Should I manually unload the dll when I am done?
[EMAIL PROTECTED] schrieb: Does comtypes automatically handle Object cleanup when the code goes out of scope? Or is there some command that I should send to release the Object/.dll? Unloading the server that implements the COM object is done by the COM runtime; there is nothing special that you have to do. Normally you do not even know or have to care which dll/exe this is. comtypes has saved the day Thanks for your hard work! You're welcome! Thomas - This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse012070mrt/direct/01/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
[comtypes-users] comtypes 0.4.1 released
I have released comtypes 0.4.1. Enjoy, Thomas New function comtypes.client.PumpEvents(timeout) which will make sure that COM events are dispatched. Added a postinstall script to the installer which will clear the comtypes.gen directory to avoid strange effects when generated modules are out of date. Several small bugfixes, see the ChangeLog. Changes since version 0.4.0: 2007-11-23 Thomas Heller [EMAIL PROTECTED] * Released version comtypes 0.4.1. * Add a PumpEvents(timeout) function to comtypes.client. This function calls the win32 CoWaitForMultipleHandles() function which will wait in a way compatible with all types of apartments; additionally this function can be interrupted with Control+C. 2007-11-21 Thomas Heller [EMAIL PROTECTED] * comtypes\__init__.py: Add docstrings to special methods. Make named_property a data descriptor by providing a __set__ method (which will raise AttributeError when called). 2007-11-15 Thomas Heller [EMAIL PROTECTED] * comtypes\__init__.py: Fix bound_named_property.__setitem__ so that COM properties can be set that require zero or more than one arguments. * comtypes\__init__.py: Restructure the code that extend the COM interface subclasses with __len__, __call__, __getitem__, and __iter__ methods. This is done with the comtypes.partial module, and apparently had strange behaviour when the code is run under a debugger. 2007-11-07 Thomas Heller [EMAIL PROTECTED] * Changed version number to 0.4.1. * Add an post-install script that will (after confirmation) remove the comtypes\gen directory containing the generated modules. - This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse012070mrt/direct/01/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Exception raised while trying to debug script which uses comtypes
Thomas Heller schrieb: I can reproduce your problem now, in PythonWin. Strange bug! I think I have a fix already, but I would like to understand the bug Although I tried, I have not really found out what was happening. Some very strange interaction between the comtypes.partial metaclass and the Python debugger (I could even reproduce the problem in the commandline debugger pdb.py). Anyway, I have changed the code in SVN so that the problem does not appear any longer. I will make a new release tomorrow, hopefully. Thomas - This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse012070mrt/direct/01/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Exception raised while trying to debug script which uses comtypes
Suraj Barkale schrieb: Hi, I am trying to debug a script which uses comtypes 0.4 for parsing word documents. However, whenever I set a breakpoint in the script, ide (PyScripter / PythonWin) stops with the exception at end of this mail. I tried this simple script: import comtypes.client #comtypes.client.GetModule(({00020905---C000-0046}, 8, 0, 1033)) from comtypes.gen import Word wa = comtypes.client.CreateObject('Word.Application') wa.Quit() The exception occurs *only* if I have set a breakpoint on any line of the script. Can anybody please tell me if this problem is specific to my system? Or how to work around this problem? Can you please try and remove all files from the comtypes\gen directory, and then rerun your script? Thomas - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Exception raised while trying to debug script which uses comtypes
Suraj Barkale schrieb: Hi, On 11/13/07, Thomas Heller [EMAIL PROTECTED] wrote: Can you please try and remove all files from the comtypes\gen directory, and then rerun your script? Note that script runs without problem. I get the exception only if I set breakpoint in either PyScriptor or PythonWin. I uninstalled 0.4 installed 0.3.3 (without deleting /gen) and everything worked fine. So I downloaded the zip distributions of 0.4 0.3.3 to try out using .pth method. (Apparently comtypes-0.3.3.zip does not contain 'partial.py' and I had to copy it from exe). So 0.3.3 does not need the partial.py module (IIRC) starting at clean install, I got no problem for 0.3.3 but 0.4 failed with following exception. The code I tried was: import comtypes.client comtypes.client.GetModule(({00020905---C000-0046}, 8, 0, 1033)) # set breakpoint on next line in ide wa = comtypes.client.CreateObject('Word.Application') wa.Quit() I can reproduce your problem now, in PythonWin. Strange bug! I think I have a fix already, but I would like to understand the bug Thanks for the heads-up. Thomas - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] Interface stability
Michael Eddington schrieb: First, thanks for comtypes :) You're welcome, and thanks for moving the question to the mailing list. I'm curious what the roadmap looks like for stabilizing the interfaces. The comtypes interface has been changing release to release creating a need to rewrite portions of code that use comtypes for later releases and creating version hell for end users (like me). Which interfaces do you mean, exactly? If the interface is going to be in flux for sometime it would be great to allow multiple versions of comtypes to be installed at once allowing different modules or apps to use the version they understand. Currently I'm porting a few modules I use to a common version of comtypes which is a less then optimal solution. You CAN install comtypes with easy_install as egg, in multi-version mode (or how it is called). That way, you have to write import setuptools; setuptools.require(comtypes==0.3.4) or something like that before importing comtypes. If I can help facilitate this by slinging some code let me know. Of course it helps to test the releases and provide feedback. The roadmap / TODO list that I have in mind: (A remark before: In our company we use an internal upstream version of comtypes to connect to ATL-written COM servers, and we use ATL to connect to comtypes implemented COM servers. Quite a lot. But we do not use dispinterfaces, only custom or dual interfaces. So dynamic dispatch support in comtypes is currently weak.) 1. Fix all the bugs that you guys find, of course. Most of them probably come because you users will use comtypes to interface servers that are normally thought to be driven by VB, or use dynamic dispatch. 2. Complete the safearray code. Currently VT_UNKNOWN and VT_DISPATCH typecodes ate not supported. The safearray code can unpack multidimensional safearray, but not pack them. I'm unsure how important packing multidim safearrays is, I'm also unsure whether they should be packed from nested Python lists (win32com supports that), ot if maybe numpy arrays should be accepted. Personally, I currently do NOT have the need for multidim arrays. 3. The upstream comtypes version contains much better COM server support. I would like to integrate these changes, but the interface must stabilize first. I fear these changes may have some impact on how the COM events code must be written. Thomas - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] property bindings
Rimon Barr schrieb: Hi Thomas, I noticed your new comtypes 0.4 release from Friday, which includes not only my patch, but a complete revamping of the safearray implementation. Thank you! I'm going to try it next week. With this new safearray support, I can likely get a particular COM piece of my system to work without requiring C++ or C#. In the meantime, I noticed something that I believe is a bug with how COM properties are mapped to object attributes... If you run the following code, it should display the problem: import comtypes, comtypes.client xl=comtypes.client.CreateObject('Excel.Application') xl.Visible=1 # (1) xl.Workbooks.Add() r=xl.Range['A1:B1'] r.Value# (2) r.Value() # (3) r.Value=1 # (4) Basically, this is equivalent to code in the Excel test case: http://svn.python.org/projects/ctypes/trunk/comtypes/comtypes/test/test_excel.py Incidentally, the test case fails on my system. Perhaps it runs fine on yours. This code worked for me when I had Office 97 installed, but it also fails for me now that I have Office 2003. Line (1) displays how properties should work, and it does work for me. Assigning to Python object attribute, updates the corresponding COM property. Line (2) should read the contents of the range of cells. But, it doesn't. Instead, I get an instance of a bound_named_property. Line (3) works, by calling the getter. But, why is it mapped this way? I think it's inconsistent, and I prefer behaviour (1) to (3). Furthermore, the assignment in line (4) simply overwrites the attribute, and has no COM effect. The reason that the code does not work with the newer office is the following: In Office 97, 'Value' was a simply property of the Range object. With simple I mean that the property did not take any arguments. (The LCID parameter is special, let us ignore it) In Office 2003, 'Value' is a property that take an optional parameter named 'RangeValueDataType'. Here is an excerpt from the generated typelib module: COMMETHOD(['propget'], HRESULT, 'Value', ( ['in', 'optional'], VARIANT, 'RangeValueDataType' ), ( ['in', 'lcid'], c_int, 'lcid', _lcid ), ( ['retval', 'out'], POINTER(VARIANT), 'RHS' )), The possible values for 'RangeValueDataType' are these: # values for enumeration 'XlRangeValueDataType' xlRangeValueDefault = 10 xlRangeValueXMLSpreadsheet = 11 xlRangeValueMSPersistXML = 12 So, in VB you can probably write something like v = ...Range(A1:B1).Value and VB will call the propget accessor with no arguments. This code will probably have the same effect: v = ...Range(A1:B1).Value(xlRangeValueDefault) Using one of the other xlRange... constants will return the contents as XML text (I tried this). All this because in VB there is not really a difference between method calls and property accesses AFAIU. In Python/comtypes, things are different. Long ago I decided that I wanted to access COM properties by using indexing syntax in Python. So, to access a parameterless COM property, one would write v = ...Range[A1:B1].Value ...Range[A1:B1].Value = xyz To access a COM property that requires parameters, one would write v = Range[A1:B1].Value[a, b, c] The consequence, of course, is that there is no way to pass named parameters to a property access (there is no Python syntax for that). I guess we have to live with that. To access a property with optional parameters, we have to use indexing with NO parameters. Unfortunately, this is not valid Python syntax: ...Range[A1:B1].Value[] but this is (it will pass an empty tuple to the __getitem__ method): ...Range[A1:B1].Value[()] Indeed, the test_excel.py unittests work when we change the code accordingly. The following code has the same effect, because apparently passing 'xlRangeValueDefault' is the same as passing nothing: ...Range[A1:B1].Value[xlRangeValueDefault] If we can live with the above, fine. If not, ONE possibility that I see would be that comtypes creates additional setter and getter functions for the 'Value' property, maybe called _setValue(...) and _getValue(...). Thomas - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
Re: [comtypes-users] View Word's toolbar events
Radu Adrian Ciora schrieb: But that this event then? # event found: _dispCommandBarControlEvents_Click Well, ShowEvents first prints the available events (methods) that it finds on the interface in this way (sample for InternetExplorer): con = ShowEvents(ie) # event found: DWebBrowserEvents2_OnMenuBar # event found: DWebBrowserEvents2_OnStatusBar # event found: DWebBrowserEvents2_OnFullScreen # event found: DWebBrowserEvents2_DocumentComplete # event found: DWebBrowserEvents2_OnTheaterMode # event found: DWebBrowserEvents2_WindowSetResizable # event found: DWebBrowserEvents2_WindowClosing # event found: DWebBrowserEvents2_WindowSetLeft # event found: DWebBrowserEvents2_WindowSetTop # event found: DWebBrowserEvents2_WindowSetWidth # event found: DWebBrowserEvents2_WindowSetHeight # event found: DWebBrowserEvents2_ClientToHostWindow # event found: DWebBrowserEvents2_SetSecureLockIcon # event found: DWebBrowserEvents2_FileDownload # event found: DWebBrowserEvents2_NavigateError # event found: DWebBrowserEvents2_PrivacyImpactedStateChange # event found: DWebBrowserEvents2_NewWindow3 # event found: DWebBrowserEvents2_SetPhishingFilterStatus # event found: DWebBrowserEvents2_WindowStateChanged # event found: DWebBrowserEvents2_PrintTemplateInstantiation # event found: DWebBrowserEvents2_PrintTemplateTeardown # event found: DWebBrowserEvents2_UpdatePageStatus # event found: DWebBrowserEvents2_StatusTextChange # event found: DWebBrowserEvents2_DownloadComplete # event found: DWebBrowserEvents2_CommandStateChange # event found: DWebBrowserEvents2_DownloadBegin # event found: DWebBrowserEvents2_ProgressChange # event found: DWebBrowserEvents2_PropertyChange # event found: DWebBrowserEvents2_TitleChange # event found: DWebBrowserEvents2_BeforeNavigate2 # event found: DWebBrowserEvents2_NewWindow2 # event found: DWebBrowserEvents2_NavigateComplete2 # event found: DWebBrowserEvents2_OnQuit # event found: DWebBrowserEvents2_OnVisible # event found: DWebBrowserEvents2_OnToolBar Now, when events actually occur, they are printed in this way: ie.Navigate2(http://www.heise.de;) Event DWebBrowserEvents2_PropertyChange(None, u'{265b75c1-4158-11d0-90f6-00c04fd497ea}') Event DWebBrowserEvents2_BeforeNavigate2(None, POINTER(IWebBrowser2) ptr=0x2652d4 at 12ec170, u'http://www.heise.de/', 0, None, None, None, False) Event DWebBrowserEvents2_DownloadBegin(None) Event DWebBrowserEvents2_PropertyChange(None, u'{D0FCA420-D3F5-11CF-B211-00AA004AE837}') Thomas - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
[comtypes-users] Receiving COM events
Hi, we had some discussions about messageloops on this list already. You may remember that you need to run a message loop to receive COM events. Well, this is only true for single threaded apartments, not for multithreaded apartments. Message loops are strange beasts, especially if you want them to terminate after a certain time, as is the case in test code or in interactive console usage. Finally I found out that the win32 function CoWaitForMultipleHandles is what should be used for this, and I found out how to use that function correctly. Here is the code: def pump_messages(timeout): # This following code waits for 'timeout' milliseconds in the way # required for COM, internally doing the correct things depending # on the COM appartment of the current thread. It is possible to # terminate the message loop by pressing CTRL+C, which will raise # a KeyboardInterrupt. hevt = ctypes.windll.kernel32.CreateEventA(None, True, False, None) handles = (ctypes.c_void_p * 1)(hevt) RPC_S_CALLPENDING = -2147417835 @ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_uint) def HandlerRoutine(dwCtrlType): if dwCtrlType == 0: # CTRL+C ctypes.windll.kernel32.SetEvent(hevt) return 1 return 0 ctypes.windll.kernel32.SetConsoleCtrlHandler(HandlerRoutine, 1) try: res = ctypes.oledll.ole32.CoWaitForMultipleHandles(0, int(timeout * 1000), len(handles), handles, ctypes.byref(ctypes.c_ulong())) except WindowsError, details: if details[0] != RPC_S_CALLPENDING: # timeout expired raise else: raise KeyboardInterrupt finally: ctypes.windll.kernel32.CloseHandle(hevt) ctypes.windll.kernel32.SetConsoleCtrlHandler(HandlerRoutine, 0) I think that this function should be provided by the comtypes.client module; I'm just not tto happy with the name. Any suggestions? Wait(timeout), maybe? Thomas - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users
[comtypes-users] comtypes 0.4.0 released
Instead of waiting any longer, I've released the current code as version 0.4.0. Download at http://sourceforge.net/project/showfiles.php?group_id=115265 The most important changes: - Several bugfixes and improvements. - Completely rewritten safearray implementation. - Support for propput and propputref COM properties. - Added support for UDT (user defined datatypes). Here is the changelog: 2007-11-02 Thomas Heller [EMAIL PROTECTED] * Bump version number to 0.4.0. Released version 0.4.0. * In _wrap_coclass, attach a __clsid attribute to the returned object. This allows, for example, to find outgoing interfaces when a CoClass is returned from a COM method call. 2007-10-26 Thomas Heller [EMAIL PROTECTED] * Implemented property get, put, and putref with arguments in comtypes.client.dynamic. * When a COM property has both propput and propputref accessor methods, the Python property fset methods determines the type of the argument. If the argument is a COM interface pointer, or a VARIANT containing one, then propputref is called, otherwise proput is called to set the property. * Allow the creation of SAFEARRAY(UDT) types even if the UDT has no _recordinfo_. Creating instances of these types will fail however since no IRecordInfo pointer can be created. This change allows to import typelib wrappers that have UDTs without guids. 2007-10-24 Thomas Heller [EMAIL PROTECTED] * When a COM property has a 'propputref' but no 'propput' accessor method, use the former in the same way as a 'propput' would work. When both 'propputref' and 'propput' are present, raise a TypeError because we cannot handle this case for now. * Fixed infinit recursion error in __getattr__ implementation. * comtypes.dynamic._Dispatch now implements a __setattr__ methods that will call to Invoke() with DISPATCH_PROPERTYPUT or DISPATCH_PROPERTYPUTREF. * Handle DISPATCH_PROPERTYPUTREF in IDispatch.Invoke implementation. * comtypes.dynamic._Dispatch objects can now be used as VARIANT value. 2007-10-22 Thomas Heller [EMAIL PROTECTED] * The repr of a COM pointer instance now includes the pointer value for easier debugging. 2007-10-17 Thomas Heller [EMAIL PROTECTED] * Disable the VT_UNKNOWN and VT_DISPATCH safearray codes, they do not work yet. * More multidimensional safearray tests, bug fixes. * Speed up the unpacking of 1- and 2-dimensional safearrays. * Lots of refatoring of the new SAFEARRAY code; added a docstring to the public function comtypes.safearray._midlSAFEARRAY. * For easier debugging, the repr of a VARIANT instance now contains the vartype. 2007-10-16 Thomas Heller [EMAIL PROTECTED] * Changed version number to 0.3.4. * Mega-patch: Completely rewritten safearray support. SAFERARRAYs are now automatically converted to Python tuples when they are received as [out] parameters in COM methods, and sequences are accepted as SAFEARRAY [in] parameters. Multidimensional safearray support still has to be added. * VARIANTs can now also contain SAFEARRAYs. VARIANTs containing SAFEARRAYs with a typecode other than VT_VARIANT, Python array.array instances can be used. * Added a comtypes.messageloop module that contains a simple messageloop which allows to add and remove custom filter functions. * Removed the comtypes.client.PumpWaitingMessages function. * Fixed the codegenerator so that it handles unnamed method parameters. 2007-10-04 Thomas Heller [EMAIL PROTECTED] * Several refactorings and a small bugfix from the upstream repository. * In the comtypes\gen\... type library wrappers, the code generator now creates a commented out template that shows an implementation for each interface it wraps. 2007-10-02 Thomas Heller [EMAIL PROTECTED] * comtypes.safearray.UnpackSafeArray can now unpack SAFEARRAYs that containt UDT (user defined data types). Patch by Rimon Barr, testcase by me. And thanks to all the feedback I got. Thomas - This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now http://get.splunk.com/ ___ comtypes-users mailing list comtypes-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/comtypes-users