How to use embedded registration-free manifest for

2020-07-30 02:15发布

问题:

I would like to use a specific version of ActiveX component that is not registered system- or user-wide. Everything works as expected if I use manifest files. However embedded manifest works only for C++ client code only.

Here is dependency declaration

<dependency>
  <dependentAssembly>
    <assemblyIdentity type="win32" name="MapWinGIS.ocx" version="4.9.1.0" />
  </dependentAssembly>
</dependency>

If I use SxStrace, I see the following

INFO: Parsing Manifest File C:\OSGeo4W\bin\TestApplication.exe.
    INFO: Manifest Definition Identity is MyApplication.app,version="1.0.0.0".
    INFO: Reference: MapWinGIS.ocx,type="win32",version="4.9.1.0"
INFO: Resolving reference MapWinGIS.ocx,type="win32",version="4.9.1.0".
    INFO: Resolving reference for ProcessorArchitecture MapWinGIS.ocx,type="win32",version="4.9.1.0".
        INFO: Resolving reference for culture Neutral.
            INFO: Applying Binding Policy.
                INFO: No binding policy redirect found.
            INFO: Begin assembly probing.
                INFO: Did not find the assembly in WinSxS.
                INFO: Attempt to probe manifest at C:\OSGeo4W\bin\MapWinGIS.ocx.DLL.
                INFO: Attempt to probe manifest at C:\OSGeo4W\bin\MapWinGIS.ocx.MANIFEST.
                INFO: Attempt to probe manifest at C:\OSGeo4W\bin\MapWinGIS.ocx\MapWinGIS.ocx.DLL.
                INFO: Attempt to probe manifest at C:\OSGeo4W\bin\MapWinGIS.ocx\MapWinGIS.ocx.MANIFEST.
                INFO: Did not find manifest for culture Neutral.
            INFO: End assembly probing.
    ERROR: Cannot resolve reference MapWinGIS.ocx,type="win32",version="4.9.1.0".
ERROR: Activation Context generation failed.

So apparently it just wants DLL no matter what. The problem is that DLL I get from AxImp does not have an embedded manifest. Is there a nice way to use embedded manifest? I feel like I can try for mt to embed one into DLL I get from AxImp but that seems hackish.

P.S. I'm not sure whether renaming ocx into dll is a good approach as AxImp also generates same name DLL for COM stuff and it looks like there is no flags to explicitly provide output name for COM CLR proxy.

回答1:

Your manifest is missing essential entries, like <comClass>. Which is why you see Windows continue hunting for another manifest to find what it needs. The workaround you found isn't that great, it puts the manifest entries in the wrong file. It should go in the manifest of the EXE.

The Smart Way to do this is to just let the build system take care of this. Register the .ocx and just set the Isolated property of the reference to True. That will get the build system to read the required manifest entries from the registry and merge them into the application manifest.

If you don't want to leave the .ocx registered for some reason then do this just once. Find the .manifest file back in the build directory. Open it with a text editor and copy/paste the entries into your app manifest. Do beware that this can invoke DLL Hell, if you update the COM server then your manifest will be outdated. Always hard to troubleshoot since this will happen a year or two from now and probably to a programmer that doesn't have a clue what you did.



回答2:

Well... the trick with

regsvr32 MapWinGIS.ocx
AxImp MapWinGIS.ocx
mt -inputresource:MapWinGIS.ocx;#2 -outputresource:MapWinGIS.dll;#2
regsvr32 /u MapWinGIS.ocx

worked for me. Although it does not seem neat. Is there a way without copying embedded manifest into a CLR proxy and intermediate registration?