Ошибка интерфейса оболочки C #:E_NOINTERFACE - ИНТЕРФЕЙС

StackOverflow https://stackoverflow.com/questions/935768

  •  06-09-2019
  •  | 
  •  

Вопрос

Я пытаюсь создать оболочку C # для COM-объекта, который у меня есть (с именем SC_COM.dll), но у меня возникли некоторые проблемы, связанные с Visual Studio 2008 (работает под управлением Vista).Мне нужно сделать это без регистрации с помощью COM DLL -я использую файл манифеста, чтобы сообщить Visual Studio об SC_COM.dll, и это, похоже, работает.Я использовал TblImp.exe для создания библиотеки типов (SC_COMtlb.dll), что я ссылки в Visual Studio 2008 с, так что я могу сделать раннее связывание с DLL, что мне нужно.Библиотеки DLL находятся в том же каталоге, что и манифест и исполняемый файл.

Вот в чем проблема:Когда я создаю экземпляр объекта и пытаюсь вызвать один из его методов на C #, он выдает следующую ошибку:

Обнаружена ошибка:Не удалось преобразовать COM-объект типа 'SC_COMtlb.SCAccessObjClass' в интерфейс типа 'SC_COMtlb.ISCUploader'.Эта операция завершилась неудачно, поскольку вызов QueryInterface COM-компонента для интерфейса с IID '{C677308A-AC0F-427D-889A-47E5DC990138}' завершился неудачно из-за следующей ошибки:Такой интерфейс не поддерживается (Исключение из HRESULT:0x80004002 (E_NOINTERFACE)).

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

Вероятно, мне следует отметить, что я не совсем уверен, как созданная мной библиотека типов (S\C_COMtlb.dll) знает, где находится фактическая COM DLL, поскольку она не зарегистрирована в системе - я предполагаю, что она просто выглядит в том же каталоге.Может ли это потенциально быть проблемой, и если да, то как я могу лучше связать их?

Это было полезно?

Решение

Попробуйте добавить это в свой App.exe.manifest:

<comInterfaceExternalProxyStub 
  name="ISCUploader" 
  iid="{C677308A-AC0F-427D-889A-47E5DC990138}"
  proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
  baseInterface="{00000000-0000-0000-C000-000000000046}"
  tlbid = "{PUT-YOUR-TLB-GUID-HERE}" />

Где можно найти TLBID из вашего собственного сгенерированного Visual Studio.Пространство имен.Assembly.Name.manifest, выглядит следующим образом:

<typelib tlbid="{A-GUID-IS-HERE--USE-IT}"
  version="1.0" helpdir="" resourceid="0" flags="HASDISKIMAGE" />

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

Другие советы

код ошибки означает, что Visual Studio думает что определенный объект должен реализовывать определенный интерфейс, но когда я пытаюсь "подключиться" к этому интерфейсу, объект отвечает, что он не знает об этом.

Я бы предположил, что проблема в SC_COM.dll.TLBIMP.EXE извлекает информацию о классе и интерфейсе из метаданных, хранящихся в библиотеке DLL, и создает оболочки для класса.

Например, если SC_COM написан на C ++, это может произойти, если создатель библиотеки DLL указал в IDL-файле, что класс реализует этот интерфейс, но фактический код не поддерживает этот интерфейс.

Вот еще один распространенный источник проблем, которые могут возникнуть у этой библиотеки DLL:иногда у вас есть класс, реализующий интерфейс ISomething2, который является производным от интерфейса ISomething, но реализация класса распознает только ISomething2.Если вы реализуете производный интерфейс, вы также должны распознать его базовый интерфейс.Это распространенная ошибка.

У вас есть (и вы контролируете) исходный код библиотеки DLL?

Какая версия Windows?Начиная с Windows Vista, внутренний манифест переопределяет внешний манифест.По умолчанию исполняемые файлы C # имеют внутренние манифесты, что означает, что ваш whatever.exe.manifest файл будет проигнорирован.

Если вы перейдете на страницу свойств вашего C # EXE, вы увидите, что на "вкладке приложения" есть раздел "Значок и манифест".Установите "Manifest" в качестве имени вашего файла манифеста, и он будет встроен вместо файла по умолчанию.

Если это не сработает, возможно, вам придется выполнить некоторые действия после сборки с MT.EXE чтобы объединить ваш внешний манифест с внутренним по умолчанию и поместить объединенный манифест обратно в .EXE-файл.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top