#c# #azure-web-app-service #com-interop #azure-appservice
Вопрос:
Попытка использовать библиотеку COM в службе приложений Azure. Библиотека 32-разрядная, и служба также настроена для работы в 32-разрядной версии.
Чтобы запустить его на локальной машине без регистрации, я создал файл манифеста, а также скопировал пользовательский код активации из примеров, найденных по адресу https://www.manifestmaker.com/sxs/help/iis_aspnet.htm. Таким образом, библиотека dll успешно загружается и активируется на локальном компьютере без регистрации COM.
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
<assemblyIdentity name="pp_cli_com_lib" version="1.0.0.0" type="win32" />
<file name="pp_cli_com.dll" asmv2:size="460800">
<hash xmlns="urn:schemas-microsoft-com:asm.v2">
<dsig:Transforms>
<dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<dsig:DigestValue>JQXRI2IOR9A7KAn4 yW8n9pGMz0=</dsig:DigestValue>
</hash>
<typelib tlbid="{85796a56-cee8-426a-81e2-c896d7b3dbbd}" version="1.0" helpdir="" resourceid="0" flags="HASDISKIMAGE" />
<comClass clsid="{6d7c883b-9cca-4fc1-badb-fdc367b44ae7}" threadingModel="Apartment" tlbid="{85796a56-cee8-426a-81e2-c896d7b3dbbd}" progid="Pp_cli_com.KCP.1" description="KCP Class" />
</file>
</assembly>
var wmh = new WebManifestHelper();
var activated = wmh.ActivateWebManifest("pp_cli_com_lib.manifest");
if (!activated)
{
throw new InvalidOperationException($"Unable to activate! Error code: {wmh.dwError}.");
}
var kcpObject = new PP_CLI_COMLib.KCP();
Однако при попытке сделать то же самое в службе приложений Azure я получаю следующую ошибку:
[Исключение загрузки файла: Не удалось получить фабрику классов COM для компонента с идентификатором CLSID {6D7C883B-9CCA-4FC1-BADB-FDC367B44AE7} из-за следующей ошибки: 8007045a Не удалась процедура инициализации библиотеки динамической связи (DLL). (Исключение из HRESULT: 0x8007045A).] System.RuntimeTypeHandle.CreateInstance(тип типа RuntimeType, логический общедоступный, Логическая проверка, Логический и кэшированный, RuntimeMethodHandleInternal и ctor, Логическая проверка и проверка безопасности) 0 System.RuntimeType.CreateInstanceSlow(Логический только для публики, Логическая проверка пропусков, Логический кэш заполнения, StackCrawlMark и stackMark) 122 Системы.Тип времени выполнения.CreateInstanceDefaultCtor(Логический только для публики, Логическая проверка пропусков, Логический кэш заполнения, StackCrawlMark и stackMark) 239 Система.Активатор.CreateInstance(Тип типа, логический непубличный) 85 Систем.Активатор.CreateInstance(Тип типа) 12
Означает ли это, что эта конкретная библиотека COM несовместима со средой песочницы службы приложений Azure?
Комментарии:
1. Ошибка-ERROR_DLL_INIT_FAILED, что означает, что .dll явно вернул значение FALSE при вызове DLL_PROCESS_ATTACH docs.microsoft.com/en-us/windows/win32/dlls/dllmain . Это может быть библиотека DLL COM-объекта или библиотека зависимостей. Это может быть несовместимость с Azure, зависит от .dll
2. Похоже, проблема в том, что . библиотека dll зависит от среды выполнения Visual C , которая по умолчанию не включена в службы приложений Azure
3. Если мой ответ полезен, пожалуйста, примите его как ответ(нажмите на опцию пометить рядом с ответом, чтобы переключить его с серого на заполнение.), см. meta.stackexchange.com/questions/5234/…
Ответ №1:
При создании сервера приложений azure по умолчанию используются параметры Publish
кода, использующие среду песочницы.
Таким образом, веб-приложение, созданное по умолчанию, не поддерживает Com без регистрации.
Но Azure App Service
поддерживает контейнеры Windows, вы можете настроить контейнер.
Комментарии:
1. Потребовалось некоторое время, чтобы понять, как настроить контейнер для совместимости . dll, но в конце концов это работает. Спасибо!
Ответ №2:
Для запуска COM без регистрации в службе приложений Azure были предприняты следующие шаги:
- Создайте и опубликуйте пользовательский контейнер, как описано в https://docs.microsoft.com/en-us/azure/app-service/quickstart-custom-container?pivots=container-windows
- Переключите пул приложений в 32-разрядный режим
- Добавьте распространяемый файл Visual C в образ контейнера (требуется для этой конкретной библиотеки COM)
Результирующий файл Dockerfile:
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'SilentlyContinue'; $ProgressPreference = 'SilentlyContinue';"]
ADD https://download.microsoft.com/download/C/6/D/C6D0FD4E-9E53-4897-9B91-836EBA2AACD3/vcredist_x86.exe /vcredist_x86.exe
RUN Start-Process -filepath C:vcredist_x86.exe -ArgumentList "/install", "/passive", "/norestart", "'/log vcredist-setup.log'" -PassThru | wait-process
RUN "C:\Windows\System32\inetsrv\appcmd.exe set apppool /apppool.name:DefaultAppPool /enable32BitAppOnWin64:true"
ARG source
WORKDIR /inetpub/wwwroot
COPY ${source:-obj/Docker/publish} .