Hi There,
I've got a C# assembly that's marked for COM Interop Registration. It contans a dataset definition. When I look at the TLB file generated for the assembly, the object is included. (for example, if the dataset is called AlphaDS, there's a default interface generated for the dataset called _AlphaDS, and a coclass entry for AlphaDS)
I'd like to mark the Dataset as COMVisible(false) so it doesn't show up in the TLB. I could mark the generated .cs file for the dataset with this attribute, but this file is auto-generated and the changes are lost each time I re-build the assembly.
Anyone have any ideas
Thanks

Making dataset instances invisible to COM
tijjj
Now that you've disabled COM registration for all types you'll need to enable COM visibility on the types and interfaces you want exposed. At a minimum you'll need to expose a public class and one of the interfaces on the public class using ComVisible(true) (and the additional attributes). If you set a class COM visible but it does not implement any COM-visible interfaces then I don't think it'll get exposed. The error you're seeing from regasm is the one I was telling you about where regasm doesn't support registering an assembly containing only COM interfaces.
[ComVisible(true)]
[Guid(...)]
public interface IMyCOMInterface
{
//Members here
}
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
[Guid(...)]
public class MyCOMClass : IMyCOMInterface
{
}
Note that in VS2003 the first COM visible interface was considered to be the default interface for the class. In VS2005 you can use a new attribute to specify the interface that COM will use by default. For classes with only one interface this attribute is unneeded.
Michael Taylor - 6/22/06
Alex O
Yes it has always been available. I don't believe it was automatically added in VS2003 but it is now generated for new projects in VS2005.
Michael Taylor - 6/22/06
Muhammad Aamir Iqbal
Shaun Michael
The generated class is already partial so you could add the attribute in another file in the same project (assembly):
namespace TheNamespaceOfTheDatasetAlphaDS
{
[ComVisible(
false)] partial class AlphaDS{
}
}
jhudson
Ahh, explictly marking the classes/interfaces as COMVisible(true) is the trick once you've marked the assembly as COMVisible(false). Since before marking the assembly, the default was to have COMVisible turned on.
So in summary, to hide the dataset objects from being exposed to COM:
VS2003 - mark the assembly as COMVisible(false) and explictly expose the classes/interfaces to COM
VS2005 - potentially use partial classes to mark the dataset objects as COMVisible(false)
Thanks for all your help.
Sun Haiwei
Your understanding is correct. We added the dataset definition to the project by selecting Add New Item and picking the Data Set template, which created a .xsd file which has the XML schema for Dataset classes.
Thanks
Igor Deck
Is it possible to register an assembly and have some interfaces/classes marked COMVisible(true) without the assembly marked as 'Register for COM Interop' I've tried this before and found that the expected objects weren't visible in COM (hence, turning on the 'Register for COM Interop' setting.)
We've actually gone and marked all the public objects with GUID/ClassInterface attributes as you described to address the very issues you raised. <grin>
Thanks
Larry OBrien
Sorry, forgot to mention I'm using Visual Studio .NET 2003.
It looks like this Is something new in .NET v2.0
Thanks.
Sorex
Then I believe you are stuck. The data set generator accepts no options. I think the fundamental problem however is that you have set your assembly as COM visible.
Begin SoapBox {
It is my personal belief that the ONLY time you should set an entire assembly as COM visible is when you are creating a primary interop for an existing COM object (such as when running tlbimp). In all other cases you should never mark an assembly as COM visible. Instead you should mark only those classes and interfaces within an assembly that need to be visible to COM as COM visible. This explicitly identifies to you and others the types that are visible to COM. Marking an entire assembly as COM visible means every public type is visible to COM. This is rarely the case as you'll have helper types that you use internally but your COM clients won't ever use.
Another problem with marking everything as COM visible is the auto-generated code. For each interface you need to add the Guid attribute to it. For each type you need to add the Guid attribute and the ClassInterface attribute. Furthermore the assembly itself needs a Guid attribute. If you don't do this then each time you compile a new Guid/ClassInterface is autogenerated for you. The problem with this is that each time you compile yet more registry entries are added to your machine. Over time if you don't clean this up (which is actually not that easy) then you'll run out of registry space. Note that if you build from within VS then generally it tries to unregister COM components first so it isn't as bad but on your automated build servers or if you wipe the binaries first then you just wasted registry space.
Another problem with not defining Guids is that you lose some modularity. Imagine that COM component Com1 and Com2 are built. Com2 relies on Com1. You then create your COM client Client1. If you find a bug in Com1 then you have to rebuild your entire solution even if the public interface didn't change because the Guids would. This is especially hard to track down when the registry wasn't properly cleaned first. You really need to specify Guids for each COM visible object. Now if the entire assembly is COM visible you have to go through and mark every public type with a GUID (and oh by the way there is no tool to autogenerate GUIDs other than GuidGen which doesn't create one in the correct form for GuidAttribute).
Therefore, as I mentioned earlier, you should probably just modify your assembly to not be COM visible, create an assembly Guid and then mark only those types as COM visible (with GuidAttribute and ClassInterfaceAttribute) that you want to expose. In your case your AlphaDS would not be COM visible and therefore would not be exposed.
} End SoapBox
Michael Taylor - 6/22/06
BurtonJ
One further clarification - is the making the entire assembly COM-visible only available in VS2005 Can this be controlled via an assembly attribute in VS2003
Thanks
E Man
I added the following attribute to the assembly so that it's not visible to COM. (code added to AssemblyInfo.cs)
[assembly:ComVisible(
false)]With the 'Register for COM Interop' turned on, I got compiler errors
COM Interop registration failed. There are no registrable types in the built assembly.
With the 'Register for COM Interop' turned off, it compiled properly. I used regasm to generate the tlb file from the compiled assembly, and got the following warning:
RegAsm warning: No types were registered
When I look at the generated tlb, it's empty.
The assembly attribute is the only change made. The code still has classes and interfaces marked for COM visiblity. Am I setting things correctly to mark the assembly COMVisible false with VS2003
Thanks
Powermax
I don't quite follow what your situation is. Is AlphaDS an instance of a DataSet (or derived) type or is it a type that derives from DataSet You said it is auto-generated, from what
Michael Taylor - 6/21/06
Nick Christian
Yes it is possible. Like I said that is how I do it. When you mark an entire assembly as COM visible it simply causes all the types to be marked as COM visible. There is however a feature/glitch in regasm. If an assembly does not contain any COM classes (ie. it only exposes COM interfaces) then regasm will not register it. I think this is a problem whether you mark the entire assembly as COM visible or not but honestly I've never tried it. Nevertheless in this specific case you have to create a dummy type that is exposed to COM so regasm will work.
As for "Register for COM interop" this is not some assembly setting, it is a post-build action that takes place after you build your assembly. This option causes VS to automatically invoke regasm to register your assembly. Technically you only need to use this option if you are going to build other components that rely on the COM component you are building. This is necessary only so that the necessary registry information is on the build machine before the dependent build occurs. The COM visible setting for the assembly is controlled by an attribute in the assembly information file or through the Application -> Assembly Information -> Make assembly COM-visible checkbox (in VS2005).
Michael Taylor - 6/22/06