TraceKira
TraceKira

Reputation: 281

how to call a Windows COM method from a C# DLL from Python?

Someone wrote a C# COM DLL , from which i need to call some functions Most important part of it is:

using System;
using System.Runtime.InteropServices; //For using COM interop
using VRTAComms;
namespace StepsToEveConverter
{
    interface IManagedInterface // needed for COM
    {
    }
    //GUID ec456b4b-5ac4-46e8-99e8-64c193c316af 32 - bit StepsToEveConverter
    [GuidAttribute("ec456b4b-5ac4-46e8-99e8-64c193c316af")]
    [ComVisible(true)]
    [ProgId("StepsToEveConverter")]
    public class StepsToEveConverter : IManagedInterface
    {
        //...bla bla
        public StepsToEveConverter()
        {
            System.Console.WriteLine("\nStepsToEveConverter::Constructor called\n");
        }
        public void StartvECU(string PathOfVECU)
        {
            System.Console.WriteLine("\nStepsToEveConverter::StartvECU called\n");
            connection = VECUFinder.Load("localhost", @PathOfVECU);
            connection.Start();
        }
    }
}

I am having problems calling method StartvECU(); I can create in python an object like this:

...
    self.COMInterfaceObj = comtypes.client.CreateObject("StepsToEveConverter");
...

Which prints in python the C# message

"StepsToEveConverter::Constructor called"

But if I call the method from C# DLL module:

public void StartvECU(string PathOfVECU)

using python code

 self.COMInterfaceObj.StartvECU("123");

I get the error Python execution error

  File "C:\Users\XXX\AppData\Local\Continuum\Anaconda\lib\site-packages\comtypes-1.1.2-py2.7.egg\comtypes\__init__.py", line 277, in __getattr__
    raise AttributeError(name)
AttributeError: StartvECU

What am I doing wrong ?

PS: some perl code works fine. Why is it so difficult in python than is in perl ?

 $PathOfVECU = 'c:\x.exe';
$handle = Win32::OLE->new('StepsToEveConverter');
$handle->StartvECU($PathOfVECU);

Ps: I can get some extra info on the python COM object created using

help(self.COMInterfaceObj);

Help on POINTER(_StepsToEveConverter) in module comtypes object:

class POINTER(_StepsToEveConverter)(comtypes.gen._F0E8D21A_98E7_42D5_A8CD_A5001E215F96_0_1_0._StepsToEveConverter, POINTER(IDispatch))
 |  Method resolution order:
 |      POINTER(_StepsToEveConverter)
 |      comtypes.gen._F0E8D21A_98E7_42D5_A8CD_A5001E215F96_0_1_0._StepsToEveConverter
 |      POINTER(IDispatch)
 |      comtypes.automation.IDispatch
 |      POINTER(IUnknown)
 |      IUnknown
 |      _compointer_base
 |      ctypes.c_void_p
 |      _ctypes._SimpleCData
 |      _ctypes._CData
 |      __builtin__.object
 |  
 |  Methods defined here:
 |  
 |  __getattr__(self, name)
 |      Implement case insensitive access to methods and properties
 |  
 |  __setattr__(self, name, value)
 |      Implement case insensitive access to methods and properties
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __com_interface__ = <class 'comtypes.gen._F0E8D21A_98E7_42D5_A8CD_A500...
 |  
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes inherited from comtypes.gen._F0E8D21A_98E7_42D5_A8CD_A5001E215F96_0_1_0._StepsToEveConverter:
 |  
 |  __map_case__ = {}
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from POINTER(IDispatch):
 |  
 |  __ctypes_from_outparam__ = wrap_outparam(punk)
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from comtypes.automation.IDispatch:
 |  
 |  GetIDsOfNames(self, *names, **kw)
 |      Map string names to integer ids.
 |  
 |  GetTypeInfo(self, index, lcid=0)
 |      Return type information.  Index 0 specifies typeinfo for IDispatch
 |  
 |  GetTypeInfoCount(...)
 |  
 |  Invoke(self, dispid, *args, **kw)
 |      Invoke a method or property.
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from IUnknown:
 |  
 |  AddRef(self)
 |      Increase the internal refcount by one and return it.
 |  
 |  QueryInterface(self, interface, iid=None)
 |      QueryInterface(interface) -> instance
 |  
 |  Release(self)
 |      Decrease the internal refcount by one and return it.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from IUnknown:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes inherited from IUnknown:
 |  
 |  __metaclass__ = <class 'comtypes._cominterface_meta'>
 |      Metaclass for COM interfaces.  Automatically creates high level
 |      methods from COMMETHOD lists.
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from _compointer_base:
 |  
 |  __cmp__(self, other)
 |      Compare pointers to COM interfaces.
 |  
 |  __del__(self, _debug=<bound method Logger.debug of <logging.Logger object>>)
 |      Release the COM refcount we own.
 |  
 |  __eq__(self, other)
 |  
 |  __hash__(self)
 |      Return the hash value of the pointer.
 |  
 |  __repr__(self)
 |  
 |  ----------------------------------------------------------------------
 |  Class methods inherited from _compointer_base:
 |  
 |  from_param(klass, value) from comtypes._compointer_meta
 |      Convert 'value' into a COM pointer to the interface.
 |      
 |      This method accepts a COM pointer, or a CoClass instance
 |      which is QueryInterface()d.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from _compointer_base:
 |  
 |  value
 |      Return self.
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from _ctypes._SimpleCData:
 |  
 |  __init__(...)
 |      x.__init__(...) initializes x; see help(type(x)) for signature
 |  
 |  __nonzero__(...)
 |      x.__nonzero__() <==> x != 0
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes inherited from _ctypes._SimpleCData:
 |  
 |  __new__ = <built-in method __new__ of _ctypes.PyCSimpleType object>
 |      T.__new__(S, ...) -> a new object with type S, a subtype of T
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from _ctypes._CData:
 |  
 |  __reduce__(...)
 |  
 |  __setstate__(...)

Thanx

Upvotes: 1

Views: 976

Answers (1)

TraceKira
TraceKira

Reputation: 281

Ok i found the solution

import win32com.client
o = win32com.client.Dispatch("StepsToEveConverter");
o.StartvECU('c:\x.exe');

The problem with python is that there are so many packages , and a lot of hours is wasted untill a package that work simple enough is found :(

Upvotes: 1

Related Questions