Michiel de Wolde
Michiel de Wolde

Reputation: 295

ActCtx + manifest + comhost + .NET 6.0: does it work, does anyone has a working example?

My goal is to expose a .NET 6.0 library to COM, in order to use it from VBA in MS Access. And to use the manifest approach rather than using the registry.

Got article "Exposing .NET Core components to COM" working, using their "COM server sample" example code.

This example however requires that a manifest file is present in the folder containing the executable. When using the COM object from MS Access we do not want to place the manifest file and other files in the MS installation folders.

The suggested solution is to create an Microsoft.Windows.ActCtx object and let that object create my COM object, using the Manifest property of the ActCtx object to specify the manifest file.

This is the part that continues to fail. actCtx.CreateObject("") gives an Invalid Cast exception, even without assignment of the result to a variable, hence it is an internal issue. No additional details, no information in the event log. Tried this in C# and from VBA.

I have a few questions:

  1. Is ActCtx the way to specify the manifest path, or is there a better way to do this from VBA in MS Office?
  2. The example uses a COM host, which seems to be some COM class / object factory, which in turn helps creating my COM object. As opposed to .NET Framework this COM host seems to be introduced for .NET Core; .NET 6.0 in my case. Is the COM host required? Is the simpler direct instantiation possible?

Does anyone has answers to these questions, tips, or even better: a working example?

Upvotes: 0

Views: 512

Answers (2)

lauxjpn
lauxjpn

Reputation: 5254

This is the part that continues to fail. actCtx.CreateObject("") gives an Invalid Cast exception [...]

Your general reg-free COM implementation seems to work fine.

The error you are getting is a result of the client app trying to query for the IDispatch interface, which you have not implemented. In .NET (Core), you need to manually implement IDispatch, since .NET does not provide an implementation for you. For an example implementation (in C++), see Essential COM by Don Bon, p. 350, "Dynamic versus Static Invocation".

You then also need to add a line to the .manifest file to reference your TypeLib.

Upvotes: 0

Michiel de Wolde
Michiel de Wolde

Reputation: 295

Some progress but I am still not happy. Abandoned the ActCtx approach for a while and tried to create the COM server object of the sample directly in MS Access VBA. Added a reference to the com host, say COMServer.comhost.dll, as opposed to the implementation COMServer.dll. Created the object, simply with New. Error: class not registered. Performed a regsvr32 COMServer.comhost.dll and the sample works.

Although the sample works there are now again registry entries: the guid of the server class has been added to the registry. Regfree COM not achieved.

This is despite COMServer.comhost.dll looking promising. A tlb type library built separately and embedded in the .dll is seen by VBA: intellisense works and the object browser works. The manifest seems to be correctly embedded in the .dll too, and takes precedence over the manifest on disk.

The question remains how to avoid the regsvr32 step and make the solution working by just adding the reference to COMServer.comhost.dll, in MS Access VBA.

Upvotes: 0

Related Questions