Search code examples
c#.netregistrycom-interopcomvisible

COM Interop: Interface Not Found in VBA Despite Correct Class Registration


Problem Description: I'm working on using COM interop to call a C# asynchronous method from VBA. The class (NewAsyncTaskRunner) is recognized and works fine, but the interface (INewCallback) is not recognized in VBA. Upon checking the registry, I think the interface is not named correctly.I'm using Visual Studio Code for development.

C# Code: NewAsyncTaskRunner.cs

using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace NewAsyncCallbackTest
{
    [ComVisible(true)]
    [Guid("dd9e3e74-f630-4ecc-8b09-e45512da443c")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface INewCallback
    {
        void OnTaskCompleted(string result);
    }

    [ComVisible(true)]
    [Guid("22222222-2222-2222-2222-222222222222")]
    [ClassInterface(ClassInterfaceType.None)]
    public class NewAsyncTaskRunner
    {
        public void RunAsyncTask(string input, INewCallback callback)
        {
            Task.Run(async () =>
            {
                await Task.Delay(5000); // 5 seconds delay
                string result = $"Task completed with input: {input}";
                callback.OnTaskCompleted(result);
            });
        }
    }
}

AssemblyInfo.cs

using System.Runtime.InteropServices;

[assembly: ComVisible(true)]

Project File: NewAsyncCallbackLibrary.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <LangVersion>10.0</LangVersion>
    <SignAssembly>true</SignAssembly>
    <AssemblyOriginatorKeyFile>MyKeyFile.snk</AssemblyOriginatorKeyFile>
  </PropertyGroup>

</Project>

Registered the assembly using:

& "C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe" "C:\Path\To\Your\DLL\NewAsyncCallbackLibrary.dll" /codebase /tlb

Registry Verification:

Interface: Found GUID dd9e3e74-f630-4ecc-8b09-e45512da443c under HKEY_CLASSES_ROOT\Interface, but it only shows numbers and version, not INewCallback.

Class: Found GUID 22222222-2222-2222-2222-222222222222 under HKEY_CLASSES_ROOT\CLSID with NewAsyncTaskRunner correctly named.

Issue: The class NewAsyncTaskRunner is recognized in VBA, but the interface INewCallback is not. The interface appears in the registry without its name.

Any insights or suggestions on what might be wrong with the interface registration and how to fix it would be greatly appreciated. Thank you!


Solution

  • As I explained in comment above I had wrong interface search in registry for NewAsyncCallbackTest.INewCallback instead of INewCallback and I have also used NewAsyncCallbackTest.INewCallback in VBA so I thought I miss INewCallback.

    So as @Hans Passant said: nothing wrong with C# Code: NewAsyncTaskRunner.cs. Used attribute InterfaceIsIDispatch. DLL is properly registered.

    So the correct approach in VBA:

    class module TaskRunnerEventHandler

    Option Compare Database
    Option Explicit
    
    Implements INewCallback 
    
    Private Sub INewCallback_OnTaskCompleted(ByVal result As String)
        Debug.Print result
    End Sub
    

    Usage module

    Option Compare Database
    Option Explicit
    
    Dim obj As Object
    Dim CallbackHandler As CallbackHandler
    
    Sub StartTask(taskParam As String)
        Set CallbackHandler = New CallbackHandler
        Set obj = CreateObject("NewAsyncCallbackTest.NewAsyncTaskRunner")
        obj.RunAsyncTask taskParam, CallbackHandler
    End Sub
    
    Sub TestMultipleTasks()
        Dim i As Integer
        
        ' Loop ten times to check multiple tasks
        For i = 1 To 10
            StartTask "Task " & i
            Sleep 100
            Debug.Print "Task " & i & " is running asynchronously!"
        Next i
    End Sub
    

    So it works perfect now...