views:

382

answers:

3

I'm not talking about calling a VBA COM from C#... the other way around!

What I would like to do is call a C# library using VBA in MS Access without registering the DLL. I've been playing around with side-by-side interop for a while without success and it has finally occurred to me that a mdb.manifest is probably not an acceptable replacement for an exe.manifest (probably obvious, I know, but I was trying to be optimistic).

My question: Is it possible to get VBA to load a side-by-side COM component?

Or, is there another way to use an unregistered C# library in Access?

(Before you ask, my reasons are: there is absolutely no way I will be granted access to my client's Windows registry -- that's why it was written in Access in the first place. And, I will need to implement the same functionality in a C# application soon and rather not do it twice).

A: 

C# libraries are not regular DLLs. They're more similar to COM libraries which need to be registered (just like ActiveX controls) before being used; especially when called from non-.NET code.

(Unless, of course, things have changed...)

Ioan
My impression that C# DLLs could be used unregistered came from here: http://msdn.microsoft.com/en-us/library/ms973915.aspx where there's a C# .NET server and a non-.NET client. I believe that's basically equivalent to what I want to do other than the fact that the client is a VB6 executable instead of a VBA application. Is there something else that I'm missing?Thanks!
Jelly
You might get stuck on the part where you need to create a manifest file for the client, since VBA isn't a standalone program for which you could generate one. The manifest looks simple enough, but I couldn't say for sure how to associate it correctly. Maybe you could get the VBA to execute a standalone client that does what you need?
Ioan
A: 

The problem is that to use SxS, you need to own the exe to set up the config to load the SxS assembly. You don't "own" Access, and while you could drop the right config in to cause it to load your .NET COM stuff sans registration, it wouldn't be a "good citizen" move.

If you get tricky with shimming, you can set up an unmanaged DLL (or a hacked C# class library with a dllexport, see this, for example) with an export that will load the .NET framework, create an instance of a COMVisible DispInterface managed type and return it (the method should return IDispatch). Then write a VBA declare to your DLL export function (declared as returning Object). If this doesn't make sense, you probably oughtn't try it... :) I've done this before in a similar situation, and it does work, but I don't have a sample to point you at.

nitzmahone
That's very clever and it does actually make sense. I hadn't found anything when I was searching before about hacking the IL to force C# to export a method. I got that part to work and I don't think it should be too much more difficult to get it to make an entry point to return an object too. Thanks for the suggestion!
Jelly
A: 

You don't have to own the exe to use SxS, SxS is another word for Activation Context. If you can import the relevant win32 calls into vba (and you can), then you can use the activation context api to load your manifest file.

More on the subject and some examples can be found here.

Alex Shnayder
I looked into using that API. Ironically though, Microsoft created a package to avoid registration that requires registration itself and leaves the same question I had before - how to get it on my client's machine? Although Microsoft.Windows.Actctx is available for Windows 2K3+ it is only included in Server installs. There's another SO question complaining about that here: http://stackoverflow.com/questions/979567/microsoft-windows-actctx-on-windows-xp. And MSDN backs it up here: http://msdn.microsoft.com/en-us/library/aa375644(VS.85).aspx.
Jelly
From what I know Activation Context API are part of Kernel32.lib, which means that you don't have to have any thing installed, and it's included in any operating system which has support for SxS which is WinXP SP2 and higher.I have done it my self on WinXP SP3 and it worked with no special installs.I don't know about Microsoft.Windows.Actctx, but I'm 100% sure you can invoke the API directly by importing the relevant functions from Kernel32.lib and invoking them directly. Like it's presented at this sample code http://www.mazecomputer.com/sxs/help/sxsapi3.htm
Alex Shnayder
Oh I see. All the examples on the web I had seen of doing this in VBA use the Actctx object instead of the API which is the only reason I originally concluded that it couldn't be done in code. Apparently, it's implemented both ways (and called the same thing) just to confuse me. I shouldn't have too much trouble getting this up and running - and it should be a more stable solution than hacking the IL - so I'll move the accepted solution flag when I get there. Thanks for the help!
Jelly
Happy to help. I know that it's very confusing, the only reason I know this is because I'm doing pretty much the same right now and I had to dig pretty deep before I got the terminology.
Alex Shnayder