Попытка построить COM-компонент в C #, на который можно ссылаться и использовать из VB5 / 6. - PullRequest
3 голосов
/ 28 апреля 2011

Я пытаюсь выяснить, могу ли я создать COM-компонент в C # (.NET 4), который я могу использовать из программы VB5 (см. Насмешливые замечания) для доступа к веб-службе.Следуя всем инструкциям, которые мне удалось найти в MSDN и CodeProject, выполните следующие действия:

Я написал следующее:

[Guid("7A715F02-D349-45DC-B0AE-9925FD3B943C")]
public interface ARCOM_Interface
{
    [DispId(1)]
    string GetServiceResponse();
}

[Guid("5130F041-619E-41F9-84B6-8332642228F6")
    , InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ARCOM_Events
{
}

[Guid("0A77754F-34CF-4E0E-AAC2-85FD686758E0")
    , ClassInterface(ClassInterfaceType.None)
    , ComSourceInterfaces(typeof(ARCOM_Events))]
[ComVisible(true)]
public class ARCOM_Class : ARCOM_Interface
{
    public string GetServiceResponse()
    {
        string response = string.Empty;

        ARWebService.ARWebService svc = new ARWebService.ARWebService();

        response = svc.PingMeBack();

        return response;
    }
}

Соответствующая сборка подписана строгим именем, а выход зарегистрирован для COM-взаимодействия.После сборки я применил к нему RegAsm и сгенерировал библиотеку типов с помощью tlbexp.exe.

В VB6, когда я открываю список ссылок из свойств проекта, я могу найти сборку в списке и проверить ее.Я даже могу сделать следующее в коде VB6:

Private Sub HitWebService()

    Dim arcom As ARCOMObject.ARCOM_Class

    arcom. <== Intellisense doesn't sense anything!

End Sub

Intellisense видит ARCOMObject и класс, но ничего, что находится внутри самого ARCOM_Class (за исключением обычного GetType, Equals идругие общие методы / свойства объекта).В частности, кажется, что он не видит метод GetServiceResponse (), поэтому я не могу вызвать его.

Что я пропускаю?

Ответы [ 2 ]

2 голосов
/ 28 апреля 2011

Я вижу, что вы нашли способ получить то, что вы хотите, пока я печатал этот ответ, но я все равно продолжу, потому что он может рассказать вам кое-что, чего вы не знаете ...

Вы применили атрибут ClassInterface (ClassInterfaceType.None) к классу. Это говорит COM-взаимодействию не определять явный интерфейс для класса, и поэтому ваш клиент должен использовать IDispatch (позднее связывание). Это означает, что ваш клиент должен заранее знать интерфейсы, которые реализует класс. То есть вы (программист) знаете, какие методы доступны, но такие инструменты, как IntelliSense, не могут найти эту информацию.

Просто продолжайте и назовите метод:

Dim response As String
response = arcom.GetServiceResponse
2 голосов
/ 28 апреля 2011

ОК, я обнаружил нечто, что неожиданно изменило ситуацию.

Обратите внимание, что приведенный выше код содержит оформление [ComVisible (true)].Конечно, важно сделать сборку видимой для COM.Я думал, что это покрывало это, но после дальнейших поисков я обнаружил, что есть другое место, чтобы отметить это.Если вы посмотрите в свойствах проекта, на вкладке Приложение вы найдете кнопку Информация о сборке ....Нажмите на нее, и в нижней части диалогового окна вы увидите флажок «Сделать сборку видимой COM».Я проверил его, перекомпилировал (и перезапустил tlbexp и regasm), а затем обнаружил, что метод GetServiceResponse () был видим.т.

Отредактировано, чтобы добавить: Думаю, я вижу, что с этим случилось.ComVisible (true) делает класс видимым для COM, но не для сборки;вот почему необходимо проверять «Сделать сборку видимой для COM», потому что метод GetServiceResponse, кажется, получает свою видимость COM через ARCOM_Interface, который не помечен как ComVisible, если сборка также не является.

...