开发者

How to get registration-free COM working in managed/unmanaged interop

开发者 https://www.devze.com 2023-02-19 11:50 出处:网络
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 th

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 acti开发者_如何转开发vation 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?


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:

  • CreateActCtx
  • ActivateActCtx
  • DeactivateActCtx
  • ReleaseActCtx

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

0

精彩评论

暂无评论...
验证码 换一张
取 消