Невозможно преобразовать COM-объект в Microsoft.Vbe.Interop.VBE.

У меня есть надстройка COM, написанная на C#, которая отлично работает с Microsoft Office.

Возникла проблема с GitHub, спрашивающая, поддерживает ли надстройка IDE VB6; Есть ли что-то другое, что мне нужно сделать, чтобы он работал с 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();
            }
        }
    }
}

Броски к VBE а также AddIn Типы просто взрывают. Сборка зарегистрирована и работает точно так, как задумано в 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>

1 ответ

Решение

Проблема в том, что VBA имеет свою собственную библиотеку типов VBIDE, а VB6 также имеет свою собственную библиотеку типов VBIDE. Обе библиотеки типов очень похожи (хотя версия VB6 гораздо богаче), и обе IDTExtensibility2 интерфейс. Кроме того, как IDTExtensibility2 был представлен с VB6 и Office 2000 VBA 6.x, также есть версии VBIDE для VB5 и, как я полагаю, для Office 97 VBA 5.x, которые раскрывают оригинал IDTExtensibility,

Вопреки ответу Ханса Пассанта, надстройка НЕ ​​является надстройкой Office, но фактически является надстройкой VBE, поэтому она работает на любом хосте, поддерживающем VBA 6/7 (Office, AutoCAD, CorelDraw, SolidWorks и т. Д..) и это может абсолютно работать в VB6 тоже... Это займет немного больше работы.

Если вы хотите поддерживать VB6 (или VB5, или VBA 5.x), то вам нужно добавить ссылку на соответствующие сборки Interop, и вам нужно будет привести их к соответствующим типам при подключении.

Я разместил подтверждение концепции на CodeReview, которая поддерживает VB6 и VBA 6.x\7.x. Это далеко от полной реализации, но вы увидите, что я создал интерфейс IVBE для абстрагирования различных реализаций VBIDE.

Другие вопросы по тегам