We've been having some issues where Visual Studio 2005 crashes when building some of our projects. Nothing graceful here - the IDE just disappears. To make things more fun, it's inconsistent, but for some projects it's happening about 80% of the time. As you can imagine this is wasting a ton of time and is incredibly frustrating.
Today I was working on enhancing our MSBuild scripts to do something more elegant than just building one master solution and I ran into the same problem - only this time I could see an error message:
Target UnmanagedRegistration: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets : warning : Type library exporter warning processing 'Sanborn.ArcEnterprise.Productivity.Query.sbenumQueryStepTypeCollection, ArcEnterprise.Productivity.Query'. Warning: Type library exporter encountered a type that derives from a generic class and is not marked as [ClassInterface(ClassInterfaceType.None)]. Class interfaces cannot be exposed for such types. Consider marking the type with [ClassInterface(ClassInterfaceType.None)] and exposing an explicit interface as the default interface to COM using the ComDefaultInterface attribute.
Shazam! The error message actually tells you what's wrong and how to solve it! Only you can't see this message when building in the IDE if the IDE crashes.
The problem in a nutshell is that there are no COM types which can be mapped to .NET Generics, and when the type exporter tries to export them, it sometimes causes the compiler and Visual Studio to bomb. (For those not using generics, I recommend checking them out - here's an intro)
Since we are doing ArcGIS Development, most of our assemblies are marked to be registered for interop when they build.
By default, the type exporter tries to export all classes in the assembly for COM interop. To avoid this, you just decorate your classes with some attributes which stop the class from being exported.
Specifically, you should decorate any classes which inherit from generics, or have a generic type in a method signature, or implement an interface that has a generic in a method signature. The example below shows the syntax in VB.NET
10 <ComVisible(False), ClassInterface(ClassInterfaceType.None)> _
11 Public Class sbenumQueryStepTypeCollection
12 Inherits ReadOnlyCollection(Of sbenumQueryStepTypeClass)
You'll also need a using/import statement for System.Runtime.InteropServices.
If you have defined interfaces which have generics in the method signature, just use the <ComVisible(False)> attribute.
Imports System.Runtime.InteropServices
<ComVisible(False)> _
Public Interface ICreateViewScriptsPluginView
Once I made these changes, MSBuild was stable, and it seems like builds in Visual Studio are now stable as well.
I'm Dave and this is my blog. I'm usually writing about .NET Software Development, ArcGIS, or Agile Practices, but other stuff does creep in from time to time. I hope you find something of use, and feel free to contact me if you have any questions. You can also check out my profile on LinkedIn
dojo.DTSAgile.com is our technology preview / demo site. As I and my team cook up cool things we post them here.
ArcDeveloper.net is a site that hosts a set of open source projects related to ArcGIS. This includes Tile Cache for .NET (TC4N) and Feature Server for .NET (FS4N). Come over and check it out!
Assembla is a free service that provides Subversion source control, wikis and work Tracking. The ArcDeveloper project is run from here. It rocks. Check them out today.
Agilistas is a LinkedIn group focused on discussing and promoting Agile practices. Everyone is welcome to join in the conversation as we evolve the process of creating software to make it more enjoyable for all involved.