VBA - ActiveX не может создать объект для .net DLL с зависимостями - PullRequest
0 голосов
/ 08 января 2019

Я написал библиотеку .Net, в которой заключена часть моей бизнес-логики, которая должна взаимодействовать с устаревшей системой. Цель этой библиотеки - предоставить интерфейс COM, чтобы я мог вызывать его из приложений Office, используя VBA.

Я сделал все, что мне нужно, чтобы зарегистрировать его, используя 64-битный Regasm.exe с флагами / codebase / tlb. Это видно в моих приложениях Office и даже отображается в intellisense. Тем не менее, я продолжаю получать сообщение об ошибке «ActiveX Component не может создать объект».

Чтобы попытаться определить, произошла ли ошибка в моей настройке / конфигурации интерфейса COM, я создал отдельную библиотеку .Net как часть моего решения, используя только базовый класс и метод для возврата «Hellow World». Это на самом деле работает, как и ожидалось, то есть я регистрирую его в диалоговом окне «Ссылки» в приложении VBA и могу создать его экземпляр и запустить метод «HelloWorld».

Dim simple as SimpleInterface.MyClass
Set simple = New SimpleInterface.MyClass

MsgBox simple.HelloWorld("Say Hello")

Затем я делаю ссылку в моем новом базовом проекте VS на мой желаемый проект (бизнес-логику) и выполняю вызов одного метода здесь, а затем создаю другой метод в моем простом проекте, чтобы представить его как интерфейс COM. Я отменяю регистрацию dll и регистрируюсь как в методе выше.

В моем приложении VBA я отменил выбор файла .tlb, закрыл его, снова открыл его, а затем снова сослался на него, а затем попытался запустить код. Это когда я получаю «ActiveX компонент не может создать объект». Я предполагаю, что это как-то связано с зависимыми DLL в моем проекте, но я не уверен, так как с ошибкой очень мало деталей.

Я не уверен, что мне здесь делать? Нужно ли регистрировать все другие зависимые библиотеки DLL, т.е. у меня есть около 2 или 3 внешних библиотек DLL, на которые я просто ссылаюсь в проекте VS? Может кто-нибудь сказать мне, как можно найти еще более подробную информацию, то есть, что является точной оскорбительной DLL?

1 Ответ

0 голосов
/ 08 января 2019

Ошибка «Компонент ActiveX не может создать объект» обычно означает, что возникла проблема с обнаружением сборки или одной из ее зависимостей или что сборка не содержит какого-либо открытого класса с запрошенным ProgID. Чтобы получить более подробную информацию об устранении неполадок при загрузке сборки, я бы предложил использовать Просмотр журнала привязки сборки .

Что нужно проверить

  • То есть вы на самом деле используете 64-битную версию MS Office? (У меня сложилось впечатление, что 32-разрядная версия по-прежнему наиболее часто используется из-за несовместимости между 64-разрядной и 32-разрядной версиями в отношении форматов / ограничений файлов для таких вещей, как документы Excel, но, возможно, это не так. это уже не так ...?)
  • Какую целевую платформу вы выбрали при компиляции проекта Visual Studio?
  • Был ли проект когда-либо скомпилирован с флажком «Регистрация для COM-взаимодействия», установленным в настройках проекта?

Что я здесь получу, так это: есть ли какая-либо вероятность того, что вы на самом деле создаете / регистрируете неправильную платформу / битность (т. Е. Не соответствует битности вашей установки MS Office) ? Может ли существовать старая регистрация для правильной битности, которая может объяснить, почему вы по-прежнему видите библиотеку типов в диалоговом окне «Ссылки» IDE VBA, несмотря на сборку для неверной целевой платформы?

Еще одна важная вещь, о которой следует помнить при представлении классов .NET через COM-взаимодействие

По умолчанию Visual Studio будет генерировать новые случайные идентификаторы ProgID для ваших открытых классов каждый раз, когда вы компилируете проект . Вот почему вы должны решить проблему удаления ссылок, а затем добавить их снова в IDE VBA, чтобы все снова заработало после повторной компиляции проекта .NET.

Не только это, но также загромождает реестр большим количеством устаревших ключей, если только вы не убедитесь, что всегда отменили регистрацию (RegAsm /u /tlb) вашей сборки перед тем, как перезаписать ее новой скомпилированной версией.

Чтобы предотвратить эти вещи, вы должны явно установить GUID ProgID, используя атрибуты ProgID для COM-классов в вашем .NET-коде. Также рекомендуется использовать атрибут ComVisible и установить для него значение false на уровне сборки и явно установить значение true только для тех типов, которые должны быть доступны для COM.

Относительно зависимостей .NET

Вам нужно только зарегистрировать DLL, которая содержит «точку входа» для вашего компонента, то есть метод, который вы вызываете из VBA. Однако среда выполнения .NET должна иметь возможность находить зависимости, как и для любого типа сборки .NET. Обычно это достигается сохранением копий зависимостей в той же папке, что и точка входа DLL. Visual Studio обычно копирует зависимости в выходную папку по умолчанию для сборок / ссылок на проекты, за исключением сборок, которые существуют в GAC.

Как использовать отладчик Visual Studio

Вы можете отлаживать код .NET во время его вызова из VBA, подключив отладчик Visual Studio к запущенному процессу excel.exe (Debug > Attach to Process из меню). Убедитесь, что «Управляемый» упоминается в столбце «Тип» для процесса Excel, и что отладчик будет подключаться к нему (это должно происходить автоматически, если вы не позаботились о настройках).

Если «Управляемый» не упоминается для процесса Excel, это означает, что Excel еще не загрузил вашу сборку; попробуйте запустить код VBA с точкой останова сразу после оператора, который создает объект COM, затем попробуйте снова подключить отладчик.

После того, как вы подключите отладчик Visual Studio, вы получите доступ к гораздо большей информации о том, что происходит. После этого вы сможете прерывать отладчик VS при возникновении исключения .NET, а также добавлять точки останова и проходить по коду .NET. Действительно стоит посмотреть, если вы еще этого не сделали.

...