3

我有一个用 C# 编写的 COM 插件,与 Microsoft Office 完美配合。

有一个GitHub 问题,询问插件是否支持 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 进程,在强制转换之前中断并检查Application对象,我可以看到我希望在那里见到的所有成员。

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

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

...

<COMReference Include="VBIDE">
  <Guid>{0002E157-0000-0000-C000-000000000046}</Guid>
  <VersionMajor>5</VersionMajor>
  <VersionMinor>3</VersionMinor>
  <Lcid>0</Lcid>
  <WrapperTool>primary</WrapperTool>
  <Isolated>False</Isolated>
  <EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
4

1 回答 1

2

问题是 VBA 有它自己的 VBIDE 类型库,而 VB6 也有它自己的 VBIDE 类型库。两个类型库都非常相似(尽管 VB6 版本要丰富得多),并且都暴露了IDTExtensibility2接口。此外,正如IDTExtensibility2VB6 和 Office 2000 的 VBA 6.x 所介绍的那样,也有 VB5 的 VBIDE 版本,我假设对于 Office 97 的 VBA 5.x,它们公开了原始的IDTExtensibility.

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

如果要支持 VB6(或 VB5 或 VBA 5.x),则需要添加对相关互操作程序集的引用,并且需要在连接时强制转换为适当的类型。

在 CodeReview 上发布了一个概念证明,它支持 VB6 和 VBA 6.x\7.x。它远不是一个完整的实现,但您会看到我创建了一个 IVBE 接口来抽象不同的 VBIDE 实现。

于 2016-09-04T23:47:03.623 回答