Невозможно преобразовать 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>

person Mathieu Guindon    schedule 27.03.2015    source источник
comment
Я думаю, вопрос в том, что на самом деле происходит как Application.   -  person RubberDuck    schedule 27.03.2015
comment
@downvoter: не нравится VB6 - слабая причина для отрицательного голосования.   -  person Mathieu Guindon    schedule 27.03.2015
comment
Это надстройка Office, она может работать только внутри приложения Office, такого как Excel или Word. Попытка использовать его из VB6 IDE не имеет смысла, это совсем не похоже на приложение Office. До сих пор существует древняя статья базы знаний, посвященная разработке расширений Office в VB6. Ваш существующий код не поможет в этом.   -  person Hans Passant    schedule 27.03.2015
comment
Я немного скептически отношусь к этому @HansPassant. MZ Tools поддерживает VS6 и VBE. mztools.com/v3/download.aspx   -  person RubberDuck    schedule 27.03.2015


Ответы (1)


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

person ThunderFrame    schedule 04.09.2016
comment
Последствия для Rubberduck VBA заключаются в том, что интерфейс IDTExtensibility2 в настоящее время ограничивает Rubberduck VBA поддержкой VBA 6/7 (что для приложений Office означает версию 2000 и новее). - person ThunderFrame; 05.09.2016
comment
Есть также причина, по которой у MZ Tools 3 были отдельные установщики для VB5, VB6 и VBA. Инструменты MZ изначально были написаны на VB6, и, поскольку все библиотеки типов VBE имеют одно и то же имя: VBIDE, решение VB6 не могло содержать ссылки более чем на одну VBIDE. - person ThunderFrame; 05.09.2016