How to use embedded registration-free manifest for ActiveX component from managed code like C#?
Asked Answered
E

2

2

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.

Eimile answered 21/2, 2014 at 2:42 Comment(0)
Y
2

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.

Yerga answered 21/2, 2014 at 22:41 Comment(3)
comClass entries are embedded into a manifest in OCX resource. It is enough to have a dependency only in manifest for C++ client. It just seems a bit odd to place a manifest with TLB stuff in EXE. Will try, but I guess should work. I'm a bit lost though about 2nd and 3rd paragraphs. If OCX is registered, why would I care about Isolated? And if I set Isolated, why would I copy a manifest with TLB stuff from OCX into CLR EXE. I don't mind registering on development machine, but not on deployment one.Eimile
You care about Isolated when it is not registered. On the deployment machine. It just needs to be registered on your dev machine so that the manifest entries can be determined automatically. Just like you did with mt.exeYerga
Do I just add produced manifest file to a project so it gets embedded? Also it is odd that setting Isolated is possible only when OCX itself is added as a reference. This way one can't pass options like those of tlbimp, e.g., namespace.Eimile
E
0

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?

Eimile answered 21/2, 2014 at 3:0 Comment(2)
Did you ever get this working? I'm trying to do the same and also with MapWinGIS.Frae
Paul, it was forever ago. I see some MW GIS TestApp in my OSGeo4W bin folder and it starts from there, so it worked as Hans suggested since Isolated is set to true and VS complains it is not registered. I think that approach works if one does not mind registering OCX on developer's machine. I did not try per-user registration though. However my initial idea was to use CMake for silent builds as unprivileged user. In case it gets too specific for MW, here is phorum thread for that stuff.Eimile

© 2022 - 2024 — McMap. All rights reserved.