Вопрос по .net, vba, visual-studio-2008 – Невозможно получить доступ к COM-методам в VBA

8

Я пытаюсь получить доступ к COM-методам в VBA.

Problem: Я вижу все методы по умолчанию (например,GetHashCode, GetType а такжеToString) в VBA нон те, которые являются частью интерфейса COM и специально написаны, чтобы быть видимыми для COM (например,getStringValue() ниже).

Подробности настройки:

Визуальная Студия 2008 Windows 7 x64 Офис 2007 .NET 3.5Interface 'IGetMyString.cs'
<code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace SimpleCOMAssembly
{
    [ComVisible(true), GuidAttribute("4153A1AC-ECE9-4f66-B56C-1DDEB6514D5D")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    interface IGetMyString
    {
        [DispId(1)]
        string getStringValue();
    }
}
</code>
Implementation 'GetMyString.cs'
<code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace SimpleCOMAssembly
{
    [ComVisible(true), GuidAttribute("0A3D4D65-CF50-4020-BF13-77001F8AAABE")]
    [ProgId("SimpleCOMAssembly.GetMyString")]
    [ClassInterface(ClassInterfaceType.None)]
    public class GetMyString : IGetMyString
    {
        public GetMyString() { }

        [ComVisible(true), Description("Get my string")]
        public string getStringValue()
        {
            return "hello";
        }
    }
}
</code>

В свойствах сборки я проверял «Сделать сборку видимой». (см. снимок ниже)

Также попросил Visual Studio 2005 сделать 'Зарегистрируйтесь для COM-взаимодействия' (см. снимок ниже)

И, наконец, как событие после сборки, я запускаю regasm.exe для регистрации .DLL, а также .TLB в реестре следующим образом:

<code>%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\regasm /codebase "$(TargetPath)" /tlb:"$(TargetDir)$(TargetName).lib"
</code>

В окне просмотра объектов Excel я включил COM-сервер (SimpleCOMAssembly, описанная выше), и теперь в обозревателе объектов он не перечисляет метод интерфейса COM (см. Ниже

Может кто-нибудь помочь мне узнать, чего мне не хватает, из-за чего методы интерфейса COM не отображаются в VBA?

РЕДАКТИРОВАТ Присоединение ITypeLib Просмотр сгенерированного TLB

Ваш Ответ

3   ответа
4

те внимание, как видны методы GetHashcode, GetType и ToString. Это методы, которые унаследованы от System.Object. Но ваш фрагмент явно (и правильно) использует [ClassInterface (ClassInterfaceType.None)], так что реализация класса скрыта.

Это не спрятано. Не очень уверенный, как это произошло, старая библиотека типов из более ранней попытки могла объяснить это. Но ваши шаги сборки очень подозрительны, вы слишком много помогаете. Параметр «Сделать типы сборок видимыми для COM» - довольно грубый способ заставить систему сборки отображать типы .NET. Но ваш код использует усовершенствованный способ выбора типа COM в верхнем правом углу, когда вы пьете чай. Который включает в себя атрибут [ComVisible (true)], что делает флажок, и атрибут [ClassInterface], который не делает флажок.

Так что проблема в том, что вы попросили систему сборки реализоватьдв интерфейсы. Независимо от того, что он унаследовал от базового класса, _Object в вашем случае, плюс то, что он унаследовал от объявления, IMyGetString в вашем случае. Что хорошо и все вполне COM-совместимо, но VBA не очень хороший потребитель COM. Ему нравится только интерфейс [Default], и это _Object в вашем случае. Хорошо видно на скриншоте.

Чтобы отключить опцию «Сделать сборку видимой».

И выберите между событием после сборки, которое вызывает Regasm, или флажком «Зарегистрироваться для взаимодействия COM». Выполнение этого в обоих случаях удваивает шансы, что вы не знаете, почему это не работает. Постбилд вам нужен только тогда, когда вам нужно зарегистрировать сборку для 64-битной версии Office.

Монстр, в этом проблема. Сообщение обновлено. Hans Passant
Ханс, на самом деле фрагмент кода и скриншоты синхронизированы, насколько я понимаю. Также я уже использую параметр / tlb в команде post-build. Я попробую другие предложенные исправления и скоро вернусь к ним. Благодарность peakit
Ханс, я добавил скриншот OLE View TLB выше. peakit
Мне нужно угадать на 2-й пули, это может переопределить атрибут. Что-то я никогда не ошибался случайно, поэтому я не знаю, что это может сделать. С побочным эффектом, интерфейс больше не является интерфейсом по умолчанию. Получите второе мнение, запустив OleView.exe из командной строки Visual Studio. Используйте File + View Typelib, чтобы посмотреть библиотеку типов. Проверьте coclass и посмотрите на интерфейс с аннотацией [Default]. Это не будет работать, если это не IMyGetString. Я исправлю свой ответ, если вы сможете это подтвердить. Hans Passant
Ганс, это то, что я вижу в OLE Viewcoclass GetMyString { [default] interface _Object; }; peakit
2

Руководство по вызову библиотеки .net из Excel Если я ссылаюсь на файл TLB с именем «Foo.tlb», в котором есть класс «FooClass», в котором есть открытые члены. Вы не сможете видеть эти элементы, потому что они созданы по умолчанию только с интерфейсом позднего связывания (связывания во время выполнения).

Вы можете изменить свой класс так, чтобы он имел раннее связывание, что позволит отображать intellisense и членов класса в обозревателе объектов.

C #:

[ClassInterface(ClassInterfaceType.AutoDual)]
public class FooClass
{
    public FooClass()
    {
    }
    public string DoSomething()
    {
        return "I am printing....";
    }
}

После применения этого изменения вы сможете увидеть метод DoSomething в браузере объектов. Примечание: сначала вам придется почитать dll.

1

если кому-то еще нужен этот ответ - у меня была точно такая же проблема, как эта (OLEView и все), и это сводило меня с ума. Я не мог понять, что я делаю неправильно, потому что я создал несколько C # COM раньше. Я забыл объявить интерфейс (в этом посте это будетIGetMyString) какpublic.

Надеюсь, это сэкономит кому-то время.

Похожие вопросы