在Windows 8和Windows 10上使用Office 2016 64位引发COM事件时出错

时间:2017-01-31 12:33:55

标签: c# excel excel-interop excel-2016

尝试处理在Windows 8或Windows 10上的Office 2016 64位中的多线程C#dll引发的事件时出错。它适用于32位和64位版本的Office 2013。它适用于Server 2008和Server 2012 R2上的Office 16 64位。错误是运行时错误'-2146232829(80131603)'对象与目标类型不匹配。

堆栈跟踪是:

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)    在COMTest.Counter.IncrementCounter()

c#代码是:

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 });
            }
        }
    }
}

我运行tlbexp来生成类型库。

我运行了regasm / codebase来注册dll。

我在Excel中创建了Class1,如下所示:

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 COMTest.ICounterProgressedEventArgs)
    Sum = Sum + e.progress
    Range("A1").Value = Sum
End Sub

我使用以下宏调用Class1

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

执行时,宏应在单元格A1中显示15,但抛出“对象与目标类型不匹配”异常。

0 个答案:

没有答案