Registration-free COM works on a local machine, but throws exception in Azure App Service

0

Trying to use a COM library in Azure App Service. The library is 32-bit, and the service is configured to run in 32-bit as well.

In order to make it run on a local machine without registration I've created a manifest file, as well as copied custom activation code from the examples found at https://www.manifestmaker.com/sxs/help/iis_aspnet.htm. This way the dll is successfully loaded and activated on a local machine without COM registration.

<?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();

However when trying to do the same in Azure App Service I get the following error:

[FileLoadException: Retrieving the COM class factory for component with CLSID {6D7C883B-9CCA-4FC1-BADB-FDC367B44AE7} failed due to the following error: 8007045a A dynamic link library (DLL) initialization routine failed. (Exception from HRESULT: 0x8007045A).] System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0 System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +122 System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +239 System.Activator.CreateInstance(Type type, Boolean nonPublic) +85 System.Activator.CreateInstance(Type type) +12

Does it mean that this particular COM library is not compatible with the Azure App Service sandbox environment?

c#
azure-web-app-service
com-interop
azure-appservice

2 Answers

1

When you create azure app server, the default options of Publish is Code which use sandbox environment.

So the webapp created by default not support Registration-free Com.

enter image description here

But Azure App Service supports Windows Containers, you can customize the container.

answered on Stack Overflow Mar 25, 2021 by Jason Pan
1

In order to run the reg-free COM in Azure App Service the following steps were taken:

  1. Create & publish custom container as described in https://docs.microsoft.com/en-us/azure/app-service/quickstart-custom-container?pivots=container-windows
  2. Switch application pool into 32-bit mode
  3. Add Visual C++ redistributable to the container image (required for this particular COM library)

Resulting 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} .
answered on Stack Overflow Mar 31, 2021 by Nikolay Vasilyev

User contributions licensed under CC BY-SA 3.0