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