views:

608

answers:

4

Hey everyone,

I'm writing a class-library (IE BHO) in C# and currently wrangling with the large volume of what I think is junk output coming from REGASM's generated registry keys.

The short version is this: I only want to expose a handful of classes (currently: ONE class) to IE (and the rest of COM). Only one class has the ClassInterfaceAttribute and GUID stuff set, and I can test that the add-on only requires the COM registry keys for this class -- and yet, REGASM generates GUIDs and registry keys for every class in the entire project.

This is annoying and somewhat disturbing as I do not want my class names sitting in users' registry unless they absolutely have to be there.

To be fair, many of those other classes are marked public because I use them in a driver app from another project in the same solution, to work around IE's debugging black hole...

I'm still very green to COM in general (especially relating to .Net) and I was wondering what is the best way to hide all my other classes from regasm? Or, at least, why these classes that -- even though they are marked public -- are showing up when I haven't set any of the COM flags for them?

Thanks!

+4  A: 

Use internal access modifier for stuff that doesn't need to have public modifier. For stuff that really needs public access use ComVisible attribute to partially hide it.

For example:

[ComVisible(false)]
public class ClassToHide {
    //whatever
};

public class ClassToExpose {

     public void MethodToExpose() {}

     [ComVisible(false)]
     public void MethodToHide() {}
};

All public member functions and member variables of all public classes are COM-visible by default. So first think of making them internal and if you really need them public hide them from COM with ComVisible.

sharptooth
Just wanted to let you know this worked like a charm. Thanks :-) I did notice, however, that ComVisible directive seemed to ignore an enum inside the class... was not a major issue but I found it somewhat odd.
Tom the Junglist
+2  A: 

Try using the /regfile switch - this will output a reg file rather than directly writing all your class names to the registry.

When you have the .reg file you can remove any entries you dont want to be added to the target systems registry, and deploy only those values to the target machine. Depending on how you choose to deploy your software, this might be easier and you would not have to change the code for any of your types.

In fact if you dont have access to the sourcecode, this would be the only way to achieve this.

Dan
ComVisible attribute is the solution for that. What you suggest is a workaround for the case when source code in unavailable.
sharptooth
Unfortunately that means manually combing the .reg output with each major build and/or writing something to do that for me. It's kind of what I'm already doing :-/ Thanks though.
Tom the Junglist
@sharptooth: Thanks for pointing that out. Corrected.
Dan
+2  A: 

I wrote a COM component with the same problems.

I separated all the non-COM functions into a separate helper DLL. The COM DLL only contains the code that needs to be registered. Everything else is accessed through the helper DLL.

I found that an easy way to make sure that future code wouldn't accidentally be marked as public rather than internal and show up in the registry.

Chris Thompson
+1  A: 

Set ComVisible attribute to false in AssemblyInfo file and set apply ComVisible for only the desired classes.

Krishna Babu