HOWTO: Navigate the code elements of a file from a Visual Studio .NET macro or add-in

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio .NET 2002
Date: January 2006   Microsoft Visual Studio .NET 2003
Updated: March 2013   Microsoft Visual Studio 2005
      Microsoft Visual Studio 2008
      Microsoft Visual Studio 2010
      Microsoft Visual Studio 2012

This article explains how to retrieve information from the several code elements (namespaces, classes, interfaces, methods, etc.) of a code file.

More Information

The extensibility model of Visual Studio provides the EnvDTE.ProjectItem class to represent a file. You can get a ProjectItem by several ways such as:

Once you have a ProjectItem, its ProjectItem.FileCodeModel property gives you access to the code model. The FileCodeModel class has several methods to add new code elements to the file, but to retrieve information it only has two properties: the Language property, which returns the unique GUID identifying the .NET language of the file, and the FileCodeModel.CodeElements property, which allows you to retrieve the code elements of the file. Each code element is represented by the EnvDTE.CodeElement class, which has several properties such as the Name, FullName, etc. There are a couple of things to notice about the CodeElement class:

  • The EnvDTE.CodeElement class, being a general class, can not provide information specific to only some kind of elements. For this purpose, the extensibility model provides specific classes such as EnvDTE.CodeNamespace, EnvDTE.CodeClass, EnvDTE.CodeInterface, etc. All code elements that are types are represented also by a general class named EnvDTE.CodeType. In Visual Studio 2005, Microsoft added new classes in the EnvDTE80 assembly to provide new properties and methods. These classes are EnvDTE80.CodeClass2, EnvDTE80.CodeFunction2, etc. To get a specific code element class from the general EnvDTE.CodeElement class, just cast to the appropriate specific class.
  • Although the EnvDTE.CodeElement class provides a CodeElement.Children property, this property does not work to retrieve the children code elements recursively as you might think. That property only seems to work for C++, if any. Instead, the proper way of retrieving the children code elements is using the Members property of the specific classes (EnvDTE.CodeNamespace, EnvDTE.CodeType, EnvDTE.CodeClass, etc.).
The following macro illustrates these concepts:
Sub ShowFileCodeModel()

   Catch ex As System.Exception
   End Try

End Sub

Private Sub ShowCodeElements(ByVal colCodeElements As CodeElements)

   Dim objCodeElement As EnvDTE.CodeElement

   If Not (colCodeElements Is Nothing) Then

      For Each objCodeElement In colCodeElements


   End If

End Sub

Private Sub ShowCodeElement(ByVal objCodeElement As CodeElement)

   Dim objCodeNamespace As EnvDTE.CodeNamespace
   Dim objCodeType As EnvDTE.CodeType
   Dim objCodeFunction As EnvDTE.CodeFunction

      MessageBox.Show(objCodeElement.FullName & " (Kind: " & objCodeElement.Kind.ToString & ")")
   Catch ex As System.Exception
      ' Ignore
   End Try

   If TypeOf objCodeElement Is EnvDTE.CodeNamespace Then

      objCodeNamespace = CType(objCodeElement, EnvDTE.CodeNamespace)

   ElseIf TypeOf objCodeElement Is EnvDTE.CodeType Then

      objCodeType = CType(objCodeElement, EnvDTE.CodeType)

   ElseIf TypeOf objCodeElement Is EnvDTE.CodeFunction Then

      objCodeFunction = DirectCast(objCodeElement, EnvDTE.CodeFunction)
      ShowCodeElements(CType(objCodeElement, CodeFunction).Parameters)

   End If

End Sub

Go to the 'Visual Studio Extensibility (VSX)' web site for more articles like this (Articles section)