1

I am currently trying to create a COM object that is made in C# in .NET Core 6.0. The COM object itself works as intended. The issue that I am having is related to the custom events that the COM object contains. I have tested Excel as a client and there the events would work fine. When I try to use the COM object with its events in Python though it won't work.

I tried it like this:

import win32com
from win32com.client import DispatchWithEvents
import pythoncom
import pywintypes

class ComEvents():
    def OnAdditionDone():
        print('Addition is done.')

unk = pythoncom.CoCreateInstance(pywintypes.IID('ComplexComObject'), None, pythoncom.CLSCTX_ALL, pythoncom.IID_IUnknown)
dispevents = DispatchWithEvents(unk.QueryInterface(pythoncom.IID_IDispatch), ComEvents)

I get the following error message:

  Message=This COM object can not automate the makepy process - please run makepy manually for this object
  Source=C:\PathToProject\PythonEventTesting\PythonEventTesting\PythonEventTesting.py
  StackTrace:

During handling of the above exception, another exception occurred:

  File "C:\PathToProject\PythonEventTesting\PythonEventTesting\PythonEventTesting.py", line 13, in <module> (Current frame)
    dispevents = DispatchWithEvents(unk.QueryInterface(pythoncom.IID_IDispatch), ComEvents)

I am not sure if am trying to access the COM events in python correctly.

I also tried to do it like this:

import win32com.client
from win32com.client import Dispatch
import pythoncom
import pywintypes

EventListener = win32com.client.getevents('ComplexComObject')
class Events(EventListener):
    def OnAdditionDone():
        print('Addition is done.')

unk = pythoncom.CoCreateInstance(pywintypes.IID('ComplexComObject'), None, pythoncom.CLSCTX_ALL, pythoncom.IID_IUnknown)
dispevents = Dispatch(unk.QueryInterface(pythoncom.IID_IDispatch))

Which led to this error:


  Message=NoneType takes no arguments
  Source=C:\PathToProject\PythonEventTesting\PythonEventTesting\PythonEventTesting.py
  StackTrace:
  File "C:\PathToProject\PythonEventTesting\PythonEventTesting\PythonEventTesting.py", line 9, in <module> (Current frame)
    class Events(EventListener):

I am not sure what I am doing wrong or if there is a better approach to consuming COM events in python. Since I am not that proficient with Python, these two approaches were the only ones I was able to find and neither would work for me.

I am not sure if there is an issue inside my C# code, since the events do work for Excel.

The C# COM object code can be found inside this GitHub repository: https://github.com/Spikxzy/ComInDotNETCore

If you want to test the code yourself be sure to edit the following tag inside the ComObjectWithEvents.csproj correctly:

    <PropertyGroup>
        <!--
        Change the following tags so that this path 'C:\$(VSLocation)\Microsoft Visual Studio\$(VSVersion)\VC\Tools\MSVC\$(CLVersion)\bin\Hostx64\x64'
        is valid for your Visual Studio installation (the path should lead to a cl.exe).
        -->
        <VSVersion>2022\Professional</VSVersion>
        <VSLocation>Program Files</VSLocation>
        <CLVersion>14.31.31103</CLVersion>
        <DriveLetter>N:</DriveLetter>
        <KitsVersion>10.0.19041.0</KitsVersion>
    </PropertyGroup>

After building the project be sure to register the generated '*.comhost.dll' file with 'regsvr32' in the command line tool.

5
  • your github link is wrong. Commented Mar 23, 2022 at 11:07
  • What exactly do you mean when you say "The link is wrong", does it not work or do you mean I should post the link to the specific project? Anyway, this would be the specific project link: github.com/Spikxzy/ComInDotNETCore/tree/master/… Commented Mar 24, 2022 at 8:09
  • 2
    That will result in a 404 error. Isn't it in a public state? Commented Mar 24, 2022 at 8:12
  • Means it doesn't work. Try it yourself with an incognito-mode browser. Commented Mar 24, 2022 at 8:26
  • I forgot to make it public it should work now Commented Mar 24, 2022 at 9:00

1 Answer 1

1

This is a correct python code:

import win32com.client
from win32com.client import Dispatch
import pythoncom
import pywintypes

unk = pythoncom.CoCreateInstance(pywintypes.IID('ComplexComObject'), None, pythoncom.CLSCTX_ALL, pythoncom.IID_IUnknown)
dispevents = Dispatch(unk.QueryInterface(pythoncom.IID_IDispatch))

class MyEvents:
    def OnAdditionDone(self):
        print('Addition is done.')

EventListener = win32com.client.WithEvents(dispevents, MyEvents)

print(dispevents.Addition(123, 456))

But it won't work as is.

First thing to do is make sure the type library (.tlb) you prepare is registered. It's not the case in the ComObjectWithEvents project but you can borrow and adapt the code you already have in the ComObjectWithTLBRegistration project.

If you don't do that you'll get ti = disp._oleobj_.GetTypeInfo() pywintypes.com_error: (-2146234011, 'OLE error 0x80131165', None, None) which is TLBX_W_LIBNOTREGISTERED.

After that you will get another error: Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. error. This is because your dispinterface is incorrectly defined in C#, it is currently:

[ComVisible(true)]
[Guid(AssemblyInfo.ComEventsGuid)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)] // not good
public interface ComEvents
{
    [DispId(1)]
    void OnAdditionDone();
}

while it must be this:

[ComVisible(true)]
[Guid(AssemblyInfo.ComEventsGuid)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ComEvents
{
    [DispId(1)]
    void OnAdditionDone();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.