Question

I have a unmanaged C++/ATL in-process COM object (in Unmanaged.dll) that I'm trying to use from a managed C# DLL (Managed.dll). However, I want I want to use registration free COM. I have it down to these steps:

  • Register the COM object on the development machine. The in-process server must have a properly registered type library.
  • Add a reference to the COM object within the C# project, and then set the Reference Properties to Isolated = True.

This produces Unmanaged.dll, Managed.dll, and Native.Managed.manifest. Opening the manifest, it's pretty clear how the system uses it to load the COM object in a registration-free way.

Here's the rub. I have a managed EXE (Managed.exe) which dynamically loads Managed.dll to access public types. What I mean by "dynamically" is, it uses Assembly.LoadFrom("Managed.dll"). When the code inside Managed.dll tries to create the COM object, it gets a "class not registered" exception. It appears the activation context doesn't get setup correctly when Managed.dll gets loaded.

Is there a way to get registration free COM to work in this scenario?

Was it helpful?

Solution

Two days without an answer, so here's what I've come up with in that time...

It does indeed look like the activation context is setup by the OS at process launch based on the manifest associated with the main EXE. That means all registration-free COM related elements must be in the Main.exe.manifest at the time the process is started. This breaks the isolation between EXE and DLLs. If a DLL is responsible for creating COM objects, you wouldn't expect the EXE manifest to have to contain the reg-free COM information. You might have expected the manifest associated with the DLL to be merged into the process activation context at the time the DLL gets loaded, but it does not.

To work around this, the DLL must configure a new activation context before creating the COM object. To make things worse, there is currently (as of .NET 4.0) no managed way to do this. So, the DLL will have to PInvoke the following Win32 functions:

I wrapped these calls with a managed class that calls CreateActCtx and ActivationActCtx in the constructor and DeativateActCtx and ReleaseActCtx in IDisposable::Dispose.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top