3

I have a C# library that was developed in-house to provide an interface to our legacy software. Over the time requirements grew and now here I am to add COM visibility to this interface library so that it can be accessed from something like VBA in the MS Office applications.

Update 3: Added bit more details in the 'Existing Design' text.

Existing Design: Let's call my interface library as Interface.dll. It's a facade pattern which includes some backend /dlls, which are dependencies for this Interface.dll. Let's call them as: MyTypeLib.dll, MyHelper1.dll, MyHelper2.dll and few more helpers. Every .dll mentioned above is a separate library project in my solution.

My approach was:
Develop a new library that has a COM visible class. I did something like:

Update 1,2: Added my interface sample code

[Guid("CE3750B7-DE31-4635-A69C-110B1271B363")]
public interface ICOMVisibleClass
{
   ...
   ...
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("A023101A-D9B3-4A24-AAE4-B3CFEDA04BAF")]
public class MyCOMVisibleClass : ICOMVisibleClass
{
   ...
   ...
}

and selectively call methods from Interface.dll, making these selected methods COM visible. Let's say above class produces MyCOMVisibleClassLib.dll. I used RegAsm.exe to register this library and to produce MyCOMVisibleClassLib.tlb file.

To test this implementation, I decided to use MS Excel 2010. I opened VBA editor and added a reference to MyCOMVisibleClassLib.tlb. In the code, I can now see all the methods in MyCOMVisibleClass so it seems to be working until.....

I ran this code and got "Run-time Error -2146233088 (80131500). Unable to find MyTypeLib.dll" I used Assembly Binding Log Viewer to see more details of this error and found that MS Excel was looking for this (MyTypeLib.dll) everywhere except where actually this file is. If I copy this file into Excel installation folder under Program Files, Excel would compain about next dependency - MyHelper1.dll and so on. After I copied all the dlls to Excel install folder all was good. But this is not the solution I am looking for.

Questions:

  1. Is my approach correct to open up few methods to COM?
  2. I think that MyCOMVisibleClassLib.dll is the only one that needs to be registered. Am I right in thinking so?
  3. How do I make Excel to find all my dependencies (MyTypeLib.dll, MyHelper1.dll, MyHelper2.dll ) without having to copy them in MS Excel install folder?

I also think that I am missing something basic that I should have known before I start this but can't seem to figure it out.

Any help is very much appreciated. Thanks in advance.

silverspoon
  • 1,085
  • 1
  • 11
  • 22
  • sorry @silverspoon, this may be a dumb question but I don't see that you're actually implementing your *Interface*. Can you just confirm that your `MyComVisibleClass` actually implements your *Interface*? Ie. `MyComVisibleClass : Interface`. See [this](http://stackoverflow.com/questions/17615044/early-binding-of-a-c-sharp-com-library-in-vba) as an example. And it would be nice to see how you actually defined the dependencies - can you please elaborate on it? –  Sep 19 '13 at 07:48
  • 1
    The .Net fusion engine loads libraries from: - Temp -> download -> gac -> base path -> probe path. Since you are using Excell as the process owner it will use the 'excell.exe' location as base path & configuration root. One option you have is signing your assemblies and putting them into the GAC. Another is placing .Net configuration in the excell directory specifying a 'probe path' for your assemblies (must be a subdirectory of the excell path). Hope this helps. – Marvin Smit Sep 19 '13 at 07:59
  • @mehow, I have updated the code to show the interface for my COM Visible class. I am not quote sure what do you mean in your 2nd question. My library (Interface.dll) uses few other dlls (MyTypeLib.dll, MyHelper1.dll, MyHelper2.dll and so on) for the type, helper methods, logging etc. that it uses. Is this something you wanting to know? Sorry if I have misunderstood your question. – silverspoon Sep 20 '13 at 00:16
  • 1
    Did you use /codebase parameter on regasm? – Joel Lucsy Sep 20 '13 at 03:02
  • @silverspoon sorry If I was unclear. What I meant to ask was: how did you *attach* the other *.dlls to your project? Are they within the same assembly/project? Are you sure that the compiled library actually includes them? Another idea would be to update your GUIDs as Excel sometimes looks for the old location of a part of assembly. I have had this problem before when some components of my assembly couldn't be found by Excel. –  Sep 20 '13 at 07:12
  • @JoelLucsy, Yes, I have tried using /codebase on regasm. Thanks. – silverspoon Sep 22 '13 at 23:47
  • @mehow, Every .dll mentioned above is a separate library project in my solution. Yes, the interface library references all the dependencies. I will try your suggestion with new GUIDs. Thank you and apologies for not being clear in my description. I will update it now. – silverspoon Sep 22 '13 at 23:49

1 Answers1

4

I finally got around the problem. Here is what I did:

  1. Strong named and signed all the assemblies including the one that needs to be registered.
  2. Used RegAsm to generate .tlb file. There is a catch here - If you are deploying your solution for 64 bit version like in my case - I was going to use this interface for 64-bit MS Excel - you MUST use 64 bit version of RegAsm found under "C:\Windows\Microsoft.NET\Framework64" to create .tlb file. For 32 bit solution use RegAsm from "C:\Windows\Microsoft.NET\Framework" folder.
  3. Created a setup project in VS2010 to include output from MyCOMVisibleClassLib project, all its dependencies and MyCOMVisibleClassLib.tlb file

You can install all these files in GAC except .tlb file. So I chose to install in the application folder (under Program Files)

After running the setup all went well and Excel seem to locate the files correctly now.

silverspoon
  • 1,085
  • 1
  • 11
  • 22