Как мне открыть библиотеку .netstandard2.0 с COM для использования в VB6? - PullRequest
4 голосов
/ 05 марта 2020

У меня есть базовая библиотека do tnet, библиотека framework 4.7.2 и приложение vb6.

Я хочу написать общую библиотеку для доступа к ним всем, поэтому выберите .netstandard2.0

Я пробовал библиотеку оболочки оболочки 4.7.2 между библиотекой .netstandard2.0 и vb6.

Однако я столкнулся с проблемами с привязкой сборки

Looking на документы Я вижу

In. NET Ядро, процесс экспонирования. NET объектов для COM был значительно упрощен по сравнению с. NET Фреймворк.

Однако никаких упоминаний .netstandard2.0

Я все равно решил попробовать следовать документам, даже если мой проект использует .netstandard2.0

Я получил до инструкции по созданию COM-хоста, в этом случае выходные файлы ProjectName.dll, ProjectName.deps. json, ProjectName.runtimeconfig. json и ProjectName.comhost.dll должны быть скомпилированы.

Однако ProjectName .comhost.dll и ProjectName.runtimeconfig. json не создаются.

В этой do tnet стандартной проблеме я вижу, что Microsoft планирует включить поддержку инструментов в «Preview 4»

Я использую VS 16.4.5

[Обновление]

Я решил попробовать создать библиотеку оболочки ядра. net и включить ее для com.

Мне удалось добавить мой .netstandard в библиотеку оболочки через пакет nuget (я собираю библиотеку .netstandard с использованием azure devops)

Когда я собираю библиотеку оболочки, .dll, .deps . json, .pdb, .runtimeconfig.dev. json и .runt Файлы imeconfig. json создаются в папке bin \ Debug \ netcoreapp3.1.

Однако ни один из файлов библиотеки .netstandard не появляется в папке bin \ debug.

Я скопировал библиотеку .netstandard и библиотеки оболочки .netcore в одну папку и запустил

regsvr32 MyCoreComWrapper.comhost.dll  

Однако не создан файл .tlb, который мне нужно использовать из VB6

. В документации я отмечаю следующее

В отличие от. NET Framework, поддержка не поддерживается. NET Ядро для создания библиотеки типов COM (TLB) из сборки ядра. NET. Руководство заключается в том, чтобы либо вручную написать файл IDL или заголовок C / C ++ для собственных объявлений COM-интерфейсов.

Я нашел некоторую информацию на github , но мне бы очень хотелось пошаговое руководство по созданию .tlb

Я думал об использовании позднего связывания, но не уверен, как использовать его с библиотекой com.

[Обновить]

I поместите пример проекта на GitHub , включая некоторые файлы VB6. С VB6 ссылается на .tlb, на который ссылается библиотека Framework.

Когда я пытаюсь запустить его, я получаю

Could not load file or assembly 'Microsoft.EntityFrameworkCore, Version=3.1.2.0, 
Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The system cannot find the file specified.

Так что я скопировал все файлы из моего тестового проекта Framework в мою папку VB6. , восстановил и запустил.

Затем я получил ошибку

Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=3.1.0.0, 
Culture=neutral, PublicKeyToken=adb9793829ddae60' or one of its dependencies. The system cannot find the file specified.

Я вижу файл Microsoft.Extensions.DependencyInjection.dll присутствует с версией файла 3.100.220.6706

Ответы [ 2 ]

2 голосов
/ 13 марта 2020

Проблема связана с разрешением привязки сборки, которое не выполняется при запуске из VB6 (IDE или скомпилированный файл .exe).

Ниже приведены инструкции по ее решению:

  • Компиляция проект VB, например, предположим, что скомпилированный файл Project1.exe.
  • Copy all. NET сборок (включая каталоги x86 и x64 и каталог языков, если важна локализованная версия), кроме скомпилированного VB6 file
  • Теперь запустите Project1.exe, вы получите ошибку, подобную этой:

enter image description here

Ошибка явно несоответствие между версией ваших сборок, кроме файла Project1.exe, и версией ссылочных сборок (не ссылки, которые вы создали сами, а ссылки, встроенные в эти сборки ...). Вы не видите этого, когда запускаете программу. NET, потому что разрешение - это очень сложный процесс, который зависит от множества параметров (и с улучшением это не улучшается. NET Core, Framework, Standard, nugets, et c.).

Для дальнейшей проверки, что это ошибка несоответствия, вы также можете использовать инструмент Fuslogvw.exe (Просмотр журнала привязки сборки) *1024* из SDK.

Теперь мы знаем, что это проблема несоответствия версий сборки, что вы можете сделать, это создать файл с именем Project1.exe.config в стороне Project1.exe и добавить привязку сборки перенаправления к нему.

Самый простой способ настроить его - перенаправить все возможные версии на те, которые присутствуют в каталоге, содержащем вашу программу, так что в вашем случае (и на сегодняшний день, как все они могут развиваться ...), это будет что-то вроде этого, возможно, для каждой сборки, на которую вы прямо или косвенно ссылаетесь:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      ...
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Extensions.DependencyInjection.Abstractions" publicKeyToken="adb9793829ddae60" />
        <!-- 3.1.2.0 is the version of the assembly you ship -->
        <bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="3.1.2.0" />
      </dependentAssembly>
      ...
    </assemblyBinding>
  </runtime>
</configuration>

К сожалению, есть много спутниковых сборок, и создавать все перенаправления с помощью некоторых утомительных правильная информация, поэтому я создал инструмент, который создает файл .config с перенаправлениями, автоматически настроенными для всех сборок NET в данном каталоге: https://github.com/smourier/BindingRedirectGenerator.

Если вы хотите, чтобы он работал и в VB6 IDE, вам придется использовать ту же процедуру в файле VB6.exe.config, кроме VB6.exe.

2 голосов
/ 09 марта 2020

Что касается стандарта. NET, я могу ошибаться, но я думаю это здесь не применимо, потому что взаимодействие COM-объектов находится на более высоком уровне, чем у стандарта. NET таргетинг; мы можем говорить только о. NET Core или. NET Framework для взаимодействия COM.

Если вы хотите сгенерировать библиотеку типов, у вас есть несколько вариантов.

Безусловно, самый простой способ - просто использовать. NET Framework. Тот факт, что вы хотите создать библиотеку типов, сводит на нет преимущества. NET Core уже потому, что некоторые COM, особенно функции "Автоматизация", Windows -только. Использование Framework будет хорошо, по крайней мере, до тех пор, пока не выйдет NET Core 5.

Тем не менее, если у вас есть деловая причина для использования. NET Core, но вам все еще нужна поддержка COM, включая библиотеку типов, затем, основываясь на этом комментарии GitHub , вы сможете составить свой собственный IDL. Обратите внимание, что вам необходимо установить инструменты сборки C ++, потому что компилятор MIDL на самом деле не является отдельной вещью, которую вы можете получить без остальных инструментов сборки C ++.

Настоятельно рекомендуется прочитать документацию о том, как. NET Core обрабатывает активацию COM .

Предполагается, что наличие инструментов сборки C ++ не является препятствием для вам, шаги будут следующие:

1) Создайте файл .idl, который определяет все ваши интерфейсы COM в формате IDL. Это требует некоторого перевода между интерфейсом. NET и интерфейсом COM. Вот частичный пример того, как вам нужно выполнить перевод между вашим C# интерфейсом и COM-интерфейсом, как определено в IDL:

[
  Guid("<some gooey>"),
  InterfaceType(ComInterfaceType.InterfaceIsDual)
]
public interface IFoo 
{
   string Bar { get; }
   string Baz(int Fizz);
}

будет переведен в IDL:

[
  uuid(<assembly gooey>),
  version(1.0)
]
library myFoo
{
  [
    uuid(<some gooey>),
    object,
    dual
  ]
  interface IFoo : IDispatch {
    [propget] HRESULT Bar([out, retval] BSTR* retVal);
    HRESULT Baz([in] long Fizz, [out, retval] BSTR* retVal);
  }
}

После того как вы определили файл .idl, и он является точным представлением, вы можете использовать MIDL для компиляции файла .idl в файл .tlb. Обычно что-то вроде midl foo.idl /tlb: foo.tlb. Вам следует использовать справочник по языку MIDL , чтобы помочь вам написать файл .idl. Для быстрого начала работы вы можете скопировать свои интерфейсы C# в проект фреймворка. NET, использовать tlbexp, а затем oleview (доступно через командную строку разработчика Visual Studio) или * 1036. * для просмотра итогового файла IDL для начала работы.

Следующим шагом является создание разделов реестра, чтобы ваш CLSID мог ссылаться на библиотеку типов. Вам понадобится GUID вашей сборки, и он также должен использоваться как library uuid в файле .idl.

Используя пример интерфейса IFoo, вам нужно будет создать реестр, подобный приведенному ниже (используя формат .reg для простого совместного использования / понимания и предполагая установку для пользователя, а не для компьютера):

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\Interface\{<some gooey>}]
@="IFoo"

[HKEY_CURRENT_USER\Software\Classes\Interface\{<some gooey>}\ProxyStubClsid32]
@="{00020424-0000-0000-C000-000000000046}"

[HKEY_CURRENT_USER\Software\Classes\Interface\{<some gooey>}\TypeLib]
@="{assembly gooey}"
"Version"="1.0"

Вам также потребуется создать реестр в CLSID, Interface, TypeLib и Record по мере необходимости. В этой статье представлен хороший обзор всех ключей реестра, но имейте в виду, что он предполагает. NET framework, а не. NET Core, поэтому не все ключи применимы, особенно в ветке CLSID .

Обратите внимание, что когда вы запускаете regsvr32, он обычно создает ключи в ветвях CLSID и Interface, но вам нужно будет добавить ключи TypeLib в ветке Interface и также запись в ветку TypeLib. Вам также нужно будет создать ключи ProgId, если вы хотите поддерживать функциональность CreateObject.

Изначально вы можете начать с файла .reg, который можно обновлять и поддерживать вручную, но если у вас есть несколько объектов, тогда становится желательно автоматизировать это. Это также можно сделать с помощью вызова DllRegisterServer, чтобы при выполнении regsvr32 он позаботился о регистрации ключей. С другой стороны, теперь вы загрязняете свою кодовую базу регистрационным кодом. Некоторые предпочитают использовать установщики для записи ключей реестра.

Надеюсь, это поможет вам начать!

...