views:

366

answers:

3

I have a C++ console application to which I want to a Windows Form. I don’t want to use MFC because I don’t know how. Instead, I am using a C# to create the COM dll (Class Library). When I distribute the application and the dll to the target computer, I need to register the dll such that the application can see the COM interface and use the class I created in the dll.

I know there are a few methods to do this:

  1. Have my application’s installer use regasm – I don’t want to use this because of two things: A. I don’t know its location on the target PC (and even if it exists somewhere, I will like not to hard-code the path to it) and B. I could redistribute regasm with the installer but I’m not sure if Microsoft allows this freely.

  2. Have my application’s installer use gacutil – same as above.

  3. Use regasm on the development computer to create a .reg file and then have the application’s installer execute the .reg file – there are two issues with this: A. I cannot unregister the dll in the event of an uninstallation and B. executing .reg calls the regedit which asks the user if he/she is sure if he/she wants to add the information to the registry – I would like this to be a silent “yes” and not let the user decide. regedit doesn’t have /silent argument so I gave up on using this.

  4. Use Inno Setup installer and register the .tlb file (regtypelib flag) of the COM library – tried and the registration works but the application still cannot create an instance of the class.

  5. Use ClickOnce to deploy the application – this is not an option because I would like my application to reside in a certain folder on the disk, not under the user’s Documents and Settings folder. To be mentioned that I’m using Express editions for the C++ and C# Visual Studio 9.0. Are there any other ways to register a COM library on a Windows XP computer.

A: 

You should use registration-free com instead. This will avoid every one of the issues you mention, but will also, if used exclusively, prevent your program from working on pre-winxp machines...which shouldn't matter in your case.

Brian
A: 

In your scenarios where you are handling the interop assembly, you are neglecting the fact that you have to still install the COM component correctly.

If you want to do this through code, then you need to call the LoadTypeLib API function through the P/Invoke layer.

However, I think that the best solution would be registration-free COM. There is a good article on it here:

http://msdn.microsoft.com/en-us/magazine/cc188708.aspx

casperOne
A: 

I tried the registration-free COM guiding myself from the example from here http://msdn.microsoft.com/en-us/library/ms973915.aspx . Leaving aside the problems I had with the manifest, I finally got the application to "see" the COM dll (registration-free). Manifests are now working. Unfortunately, the call to CoCreateInstance() now returns E_OUTOFMEMORY (0x8007000E). To be mentioned that the COM dll has two classes but only for one I create a COM-visible interface (the other one is the class for the Form and I want it to be private). Could this be the issue? Here is some code:

#import "MyGUI_DLL.tlb" raw_interfaces_only named_guids
[…]
static MyGUI_DLL::MyGUI * g = NULL;
r = CoInitializeEx(NULL, COINIT_MULTITHREADED);
// r is S_OK here
r = CoCreateInstance(MyGUI_DLL::CLSID_MyGUIClass, NULL, CLSCTX_INPROC_SERVER, MyGUI_DLL::IID_MyGUI, reinterpret_cast<void**>(&g));
// r returns E_OUTOFMEMORY

Thanks for the help.