Can registration free COM be applied to a DLL?
Asked Answered
H

1

6

At the moment I have something like this for a registration-free COM setup:

  • a.exe (depends on b.dll; does not directly depend on c.dll)
  • a.exe.manifest (declares registration-free COM registration for c.dll)
  • b.dll (depends on c.dll. For example, a .NET TMBIMP generated COM wrapper)
  • c.dll (some COM implementation DLL)
  • c.dll.manifest (registration-free COM manifest for c.dll)

Is it possible to change this scheme such that the manifest that is on a.exe is instead placed on b.dll? I'd like other programs to be able to reference b.dll without having to add additional manifests everywhere if possible.

(a.exe.manifest has this content:

  <file name="msdia110.dll">
    <comClass description="Debug Information Accessor" clsid="{761D3BCD-1304-41D5-94E8-EAC54E4AC172}" threadingModel = "Both"/>
  </file>

)

and c.dll.manifest was generated using the manifest tool mt.exe. (and is far too long to include here)

Hyperopia answered 2/4, 2014 at 0:7 Comment(9)
Use activation context API to control which manifests are active at the point of load.Wonacott
Technically, yes. Not without a load of trouble, b.dll is an auto-generated file so you'll have to take control over that and monkey with mt.exe to embed the manifest. Use ID 2. The .NET 4 Embed Interop Types feature is also very troublesome, highly desirable but it makes b.dll disappear.Urnfield
@Hans: In this case b.dll isn't autogenerated. (tlbimp gets quite a lot wrong here and we had to decompile, mess with the IL, and recompile)Hyperopia
@BillyONeal, yes, it's possible. You can even have manifests that only contain dependencies, and manifests that refer to more than one DLL.Gardas
possible duplicate of Move manifest file to dll?Sot
@Martin: That question discusses LoadLibrary, not Registration-Free COM.Hyperopia
That question asks how to embed a manifest for reg free COM into a DLL that is eventually loaded via LoadLibrary. As far as I can tell, whether you link dynamically=LoadLib or statically shouldn't matter.Sot
@Martin: It does matter. In one case you're providing a DLL name to LoadLibrary and asking the loader to respect a manifest setting. In another case you're asking COM to respect a manifest file on the file system. This isn't a loader setting, this is a COM setting.Hyperopia
I'd say it's not a COM setting, it's an Activation Context setting. Anyway. In your case, when you have b/c.dll.manifest who do you think would be responsible for respecting the manifest (file) of the dll? The DLL will be loaded by the "loader" and if that machinery doesn't put the manifest into the applications Activation Context, then it wont be used. And as far as I know, the loader will not do anything about reg-free COM manifest stuff, although it will check the manifest of the DLL for DLL dependencies (like msvcr etc.).Sot
S
0

My experience is that it doesn't work, or rather you need to call into the Activation Context API to make actual use of the manifest in a DLL: See this question: Move manifest file to dll?

My take on this, although maybe not entirely accurate, is this:

  • Registry based COM is "global" per user

  • Regfree manifest COM is "global" per process and should be managed on the executable.

Only the executable manifest is always "in scope", if you're DLLs have a COM side-by-side manifest, you are forced to load this explicitly using the Activation Context API, and the problem with that is that it can only work when you know exactly when it is needed and control the call path to the places in the DLL where it is needed.

Because, as I understand this, what you really do when you have "a.exe.manifest (declares registration-free COM registration for c.dll)" is that you modify the initial/global Activation Context of that process. This (seems to) only works for the executable manifest. Any manifests for the DLLs won't be in use automatically after the DLL is loaded, so you'll have to do it manually when you need the reg-free COM manifest in place, i.e. before CoCreateInstance.

I had a case where I thought that I knew when CoCreateInstance was called and I needed the switch, only to later discover that the DLL spawned some thread(s) that did some CoCreateInstance themselves. (Where I couldn't control the Activation Context of.)

So to sum up I'd say:

  • If you can do at all, include the SxS COM manifest in you executable
  • You can use the Activation Context API if you know fully and can control when to switch the context ("manually"), but this seems so much more hassle compared to just embedding the manifest in the executable.
Sot answered 29/4, 2014 at 10:1 Comment(3)
So, your answer is, "Yes, if the .EXE knows in advance" which defeats the purpose of putting it on the DLL in the first place.Hyperopia
@BillyONeal: I say technically there are cases where the EXE doesn't need to know anything, but as far as I can grasp this whole thing, in practice the only thing that properly works is putting the manifest in the EXE. (But we already discussed this in the comments to the question, no?)Sot
@BillyONeal: But you see, I'm very far from calling me an expert on that whole matter, so I am genuinely interested in finding a definite answer myself. So if we are in disagreement over some basics (as it seems to me from our comment discussion) I'm happy to talk about it some more.Sot

© 2022 - 2024 — McMap. All rights reserved.