I'd like to be able to call an OLE Automation (IDispatch) server from python to automate an existing application. I'm not at liberty to change the existing automation interface provided by the application so I need to get it to work with what the app currently exposes.

The interface I'm attempting to work with makes use of "out params". Here's an excerpt from the IDL for a small sample app I created to reproduce the issue.

==========
    dispinterface IMyApp
    {
        properties:

        methods:
            [id(1)] void ShowMessage(BSTR msg);
[id(2)] void SetSettingValue(BSTR settingName, BSTR settingValue); [id(3)] void GetSettingValue(BSTR settingName, BSTR* settingValue);
    };
==========

The first two methods are straightforward and I had no problem calling them from python. The problem is the third one, GetSettingValue, since it requires you to pass in a reference to a variable which it then fills in for you.

I read through CH12 of "Python Programming on Win32" by Hammond/Robinson as a guide. Based on that I installed pywin32 and then tried running MakePy. Here's an excerpt of the code generated by MakePy.

==========
def GetSettingValue(self, settingName=defaultNamedNotOptArg, settingValue=defaultNamedNotOptArg): return self._oleobj_.InvokeTypes(3, LCID, 1, (24, 0), ((8, 0), (16392, 0)),settingName
            , settingValue)

def SetSettingValue(self, settingName=defaultNamedNotOptArg, settingValue=defaultNamedNotOptArg): return self._oleobj_.InvokeTypes(2, LCID, 1, (24, 0), ((8, 0), (8, 0)),settingName
            , settingValue)

    def ShowMessage(self, msg=defaultNamedNotOptArg):
        return self._oleobj_.InvokeTypes(1, LCID, 1, (24, 0), ((8, 0),),msg
            )
==========

Comparing what it generated for GetSettingValue vs. SetSettingValue I noted the difference of 16392 vs. 8. Looking up those in the windows headers it appears those numeric constants correspond to VT_BYREF|VT_BSTR vs. VT_BSTR. So MakePy is generating something different for the "out param" and it seems to even be noticing that its by reference.

I haven't figured out how to actually call this, though. In CH12 of the book I mentioned, it is noted that for such methods the params are converted to return values instead. The example given in the book is:

==========
ok = GetSize( &left, &right, &top, &bottom);
     becomes
left, right, top, bottom = GetSize()
==========

It doesn't appear that this is happening with the MakePy results I'm getting. But clearly MakePy is detecting the "by reference" parameter.

Here's the output I get when attempting to call this method. I just sort of guessed at how I might call that method.

==========
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import win32com.client
>>> x = win32com.client.Dispatch("MyApp.Application")
>>> x.ShowMessage("Hello, world")
>>> x.SetSettingValue("sName","sValue")
>>> sValue = ""
>>> x.GetSettingValue("sName",sValue)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<COMObject MyApp.Application>", line 2, in GetSettingValue
pywintypes.com_error: (-2147352571, 'Type mismatch.', None, 2)
>>> sValue = x.GetSettingName("sName")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
File "C:\Users\dave\apps\Python273\lib\site-packages\win32com\client\dynamic.py", line 522, in __getattr__
    raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: MyApp.Application.GetSettingName
>>>
==========

Any advice on how I can make use of this method, which takes "out params", from python?

_______________________________________________
python-win32 mailing list
python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to