HOWTO: Manipulate a code or form designer file from a Visual Studio add-in

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio .NET 2002
Date: June 2007   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, given a file of a project, how to open it to get or manipulate its code or its controls.

More Information

To manipulate a file (EnvDTE.ProjectItem), you need it to be open to get its EnvDTE.Window. There are several ways to get an EnvDTE.Window:
  • The active window can be retrieved using DTE.ActiveDocument.ActiveWindow (assuming that there is an active document). Notice that DTE.ActiveWindow can not be used, since it could return a toolwindow (if it is the active window) and not a document window.
  • The open windows can be retrieved iteraring DTE.Windows and checking that the Window.Type (hidden) property is vsWindowTypeDocument. You can also iterate DTE.Documents and for each EnvDTE.Document iterate its Document.Windows collection.
  • You can iterate all the files of the projects of a solution as explained in the article HOWTO: Navigate the files of a solution from a Visual Studio .NET macro or add-in. For each ProjectItem, it could be that user already has the file open in a window, or not. Also, a file can be opened in several views. For example, a form file can be opened in a window as a code file and in another window as a form designer. The three important views are code (EnvDTE.Constants.vsext_vk_Code), designer (EnvDTE.Constants.vsext_vk_Designer) and text (EnvDTE.Constants.vsext_vk_Text, for files that contain text that is not code). The logic to follow is:
    • Check if the ProjectItem is already open in the desired view using the ProjectItem.IsOpen(viewKind) and store the boolean result for the last step.
    • Get the window from the ProjectItem in the desired view using ProjectItem.Open(viewKind), which returns an EnvDTE.Window object. If the file was already open in that view, it will return the existing window. Otherwise the file is opened programmatically at this point, but the resulting window is not visible, which is fine because likely you don't want to open visibly all the files of a project while you are processing them. If you want for some reason, you need to set the Window.Visible property to True.
    • Once you have the EnvDTE.Window, you can process it (more on this latter).
    • When done, if the window was open previously by the user you don't need to do anything (it should remain open). If not, you need to close it (although it is invisible) to preserve resources. This is done calling the Window.Close(saveChanges) method, where the parameter allows you to specify whether to save the changes (typically yes if you were modifying it and no if you were just reviewing the file but not changing it). Notice that you can also leave open the documents that you have modified, letting the user review them.

With any of those approaches you have an EnvDTE.Window, and you can manipulate its code or its form designer:

  • To manipulate the form designer of an EnvDTE.Window, see the article HOWTO: Manipulating controls of Windows forms from Visual Studio .NET add-ins.
  • To manipulate its text or code, you need to cast its Window.Document property to EnvDTE.TextDocument. This object allows you to replace text using its ReplacePattern method. It also allows you to get the StartPoint and EndPoint, which are TextPoint objects. You can create EditPoint objects using the TextPoint.CreateEditPoint method, and the EnvDTE.EditPoint class have lots of methods to move through the code, to get, insert, find or replace text, etc.

Related articles

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