无法将COM对象强制转换为Microsoft.Vbe.Interop.VBE

时间:2015-03-27 06:01:28

标签: c# com add-in vbe

我有一个COM add-in written in C#,与Microsoft Office完全兼容。

有一个GitHub issue asking if the add-in supported the VB6 IDE;有什么不同我需要做的,使它与Visual Studio 6.0一起使用吗?

以下是相关的班级列表:

using System;
using Extensibility;
using Microsoft.Vbe.Interop;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Windows.Forms;

namespace Rubberduck
{
    [ComVisible(true)]
    [Guid(ClassId)]
    [ProgId(ProgId)]
    [EditorBrowsable(EditorBrowsableState.Never)]
    //underscores make classes invisible to VB6 object explorer
    //Nothing breaks because we declare a ProgId
    public class _Extension : IDTExtensibility2, IDisposable
    {
        public const string ClassId = "8D052AD8-BBD2-4C59-8DEC-F697CA1F8A66";
        public const string ProgId = "Rubberduck.Extension";

        private App _app;

        public void OnAddInsUpdate(ref Array custom)
        {
        }

        public void OnBeginShutdown(ref Array custom)
        {
        }

        public void OnConnection(object Application, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom)
        {
            try
            {
                // these casts fail when host is VB6 environment
                _app = new App((VBE)Application, (AddIn)AddInInst);
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message, "Rubberduck Add-In could not be loaded", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public void OnStartupComplete(ref Array custom)
        {
            if (_app != null)
            {
                _app.CreateExtUi();
            }
        }

        public void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom)
        {
            Dispose();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing & _app != null)
            {
                _app.Dispose();
            }
        }
    }
}

VBEAddIn类型的演员阵容只会爆炸。程序集已注册,并且与Office 中的预期完全一致。

我在寻找有关扩展VB6的文档时遇到了一些困难,但我的理解是所涉及的接口是相同的 - 通过附加到VB6进程,在转换之前中断,并检查{{ 1}}对象,我可以看到我期待看到的所有成员。

为什么它不起作用呢?以下是项目文件中的相关参考:

Application

...

<Reference Include="extensibility, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
  <EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>

1 个答案:

答案 0 :(得分:2)

问题在于VBA拥有自己的VBIDE类型库,VB6也有自己的VBIDE类型库。两个类型库都非常相似(尽管VB6版本更丰富),并且都暴露了IDTExtensibility2接口。此外,由于IDTExtensibility2是在VB6和Office 2000的VBA 6.x中引入的,因此还有VBIDE版本的VB5,我认为,对于Office 97的VBA 5.x,它会暴露原始的IDTExtensibility

与Hans Passant的回答相反,加载项不是Office加载项,但实际上是VBE加载项,因此它适用于支持VBA 6/7的任何主机(Office,AutoCAD,CorelDraw, SolidWorks等)它在VB6中也绝对可以工作......只需要多做一些工作。

如果您想支持VB6(或VB5或VBA 5.x),那么您需要添加对相关Interop程序集的引用,,您需要将其转换为适当的连接类型。

我发布了支持VB6和VBA 6.x \ 7.x的proof of concept on CodeReview。它远不是一个完整的实现,但你会看到我创建了一个IVBE接口来抽象不同的VBIDE实现。

相关问题