none
Error Raising COM Event With Office 2016 64 bit on Windows 8 and Windows 10 RRS feed

  • Question

  • I get an error when trying to process events raised from a multi-threaded C# dll in Office 2016 64 bit on Windows 8 or 10. It works with Office 2013 for both 32 and 64 bit versions. It works with Office 16 64 bit on Server 2008 and Server 2012 R2. The error is Run-time error ‘-2146232829 (80131603)’ Object does not match target type.

    The stack trace is:

    at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)

    at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)

    at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)

    at COMTest.ICounterEvents.CounterProgressed(Object sender, CounterProgressedEventArgs e) at COMTest.Counter.IncrementCounter()

    The c# code is:

    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    
    namespace COMTest
    {
        [ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("1912B8CF-0B0A-4F9D-A76D-5C10D6B85548")]
        public interface ICounter
        {
            void Progress();
    
            int Count { get; }
        }
    
        [ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("5150CD23-DF7A-4FBE-838A-7AFEA84A0CFC")]
        public interface ICounterProgressedEventArgs
        {
            int Progress { get; }
        }
    
        [ComVisible(true), ClassInterface(ClassInterfaceType.None)]
        public class CounterProgressedEventArgs : EventArgs, ICounterProgressedEventArgs
        {
            public int Progress { get; internal set; }
        }
    
        [ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIDispatch), Guid("1698856D-AFDA-4C94-B6B4-5EA94958B40D")]
        public interface ICounterEvents
        {
            [DispId(1)]
            void CounterProgressed(object sender, CounterProgressedEventArgs e);
        }
    
        [ComSourceInterfaces(typeof(ICounterEvents))]
        [ComVisible(true), ClassInterface(ClassInterfaceType.None)]
        [Serializable]
        public sealed class Counter : ICounter
        {
            public event CounterProgressedEventHandler CounterProgressed;
            public delegate void CounterProgressedEventHandler(object sender, CounterProgressedEventArgs e);
    
            public int Count { get; private set; }
    
            public void Progress()
            {
                if (CounterProgressed != null)
                {
                    RunTasks(5);
                }
            }
    
            private void RunTasks(int threads)
            {
                var tasks = new Dictionary<int, Action>();
    
                var asyncResults = new IAsyncResult[threads];
    
                for (int i = 0; i < threads; i++)
                {
    
                    tasks.Add(i, IncrementCounter);
                }
    
                for (int i = 0; i < threads; i++)
                {              
                    var task = tasks[i];
                    asyncResults[i] = task.BeginInvoke(null, null);
                }
    
                for (int i = 0; i < threads; i++)
                {
                    var task = tasks[i];
                    task.EndInvoke(asyncResults[i]);
                }
            }
    
            private void IncrementCounter()
            {
                if (CounterProgressed != null)
                {
                    Count++;
                    CounterProgressed(this, new CounterProgressedEventArgs { Progress = Count });
                }
            }
        }
    }

    I used tlbexp to generate the type library and regasm to register the dll.

    I created Class1 in Excel as follows:

    Public WithEvents comCounter As Counter
    
    Public Sum As Long
    
    Public Sub Test()
        Set comCounter = New Counter
        comCounter.progress
    End Sub
    
    Private Sub comCounter_CounterProgressed(ByVal sender As Variant, ByVal e As CounterProgressedEventArgs)
        Sum = Sum + e.progress
        Range("A1").Value = Sum
    End Sub

    I called Class1 using the following macro:

    Public Sub Run()
        Dim c As Class1
        Set c = New Class1
        c.Test
    End Sub

    When executed the macro should display 15 in cell A1 but the ‘Object does not match target type’ exception is thrown.


    Tuesday, January 31, 2017 2:52 PM

All replies

  • Hello Patrick,

    The article suggests the following:

    1. Change the System.Threading.Thread.CurrentThread.CultureInfo property before calling Excel methods or accessing properties.

    2. Or use the InvokeMember method. In this case you can directly specify CultureInfo for any call.

    Do you get any error or exception when you try to set the Value property on the main thread only?

    The fact is that Office applications use the single-thread apartment model which requires dealing with their object models on the main thread only.


    profile for Eugene Astafiev at Stack Overflow, Q&A for professional and enthusiast programmers

    Tuesday, January 31, 2017 9:32 PM
  • Hi Eugene,

    Thanks for the response. Unfortunately I'm not using VSTO to manipulate Excel from C#, I think that the article applies to VSTO only. I’m using VBA to call a C# dll via a COM wrapper. I used the following VBA to confirm that there are no issues with the locale.

    Range("A1").Value = Application.LanguageSettings.LanguageID(msoLanguageIDUI)
    Range("A2").Value = Application.LanguageSettings.LanguageID(msoLanguageIDInstall)

    Excel and Windows are both using US English.

    Wednesday, February 1, 2017 10:17 AM
  • It doesn't matter where you deal with the Excel object model - VSTO or  .Net application . 

    You just need to set the CultureInfo property of the current thread class where you run the code in .Net, not the Value property. Did you have a chance to read the article I mentioned and adapt the code listed there?


    profile for Eugene Astafiev at Stack Overflow, Q&A for professional and enthusiast programmers

    Wednesday, February 1, 2017 11:42 AM
  • Hi,

    What is your office version?

    It works for me in Version 1701 (Build 7766.2039) / Version 1609 (Build 7369.2115) / Win10.


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, February 2, 2017 10:14 AM
    Moderator
  • The c# code does not deal with the Excel object model. Excel is calling a c# dll via COM. The c# dll can be called from any COM aware language or client. The c# code is unaware of Excel. I have read the article.

    Monday, February 6, 2017 9:53 AM
  • Hi Celeste,

    I'm using Version 1611 (Build 7571.2019).  I'm running Windows 10 Enterprise on Azure at version 1607 (OS build 14393.693). 

    Monday, February 6, 2017 10:28 AM
  • Patrick,

    Again, you need to set the CultureInfo property of the current thread where you run the code in .Net. Did you try doing so? If so, how your code looks like now?


    profile for Eugene Astafiev at Stack Overflow, Q&A for professional and enthusiast programmers

    Monday, February 6, 2017 1:11 PM
  • Hi,Patrick

    Sorry that I failed to find the same version as yours to test if the issue is related to Office version.  I suggest you update your office to have a test.

    Did you try the suggestion from Eugene and what is the result?

    Regards,

    Celeste


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, February 10, 2017 6:39 AM
    Moderator
  • Hi Celeste

    I've tried setting the culture of the thread, which was the closest I could get my code to that suggested in the article by Eugene. This did not work.

    Regards,

    Patrick

    Monday, February 27, 2017 10:49 AM