Using Visual Studio Utility Project Types


To help you more easily maintain files within a solution, Visual Studio makes available various utility projects. These utility projects allow you to keep track of files that are not part of any other project that is loaded into a solution. Because any file type can be stored within these projects, such as program source files or Microsoft Word documents, these projects can't be compiled into a program. And because utility projects are not associated with any particular programming language, they are available to all users of Visual Studio and don't require Visual Basic, Visual C#, or Visual C++ to be installed.

Miscellaneous Files Project

When you're working with a solution, you might need to open files that are not part of an existing project. When you open such a file, it is automatically added to a project called Miscellaneous Files. A project file isn't created on disk for this project, as with other project types, but you get a convenient way of locating files that are open but are not part of any other project that is open within the solution. You can think of the Miscellaneous Files project as a list of most recently used open documents—when you open a file, an item for that file is added to the project, and when you close the file, it is removed. By default, the Miscellaneous Files project and the files it contains don't appear in the Solution Explorer tree hierarchy, but you can easily make them visible by opening the Tools Options dialog box, selecting the Environment | Documents node, and selecting the Show Miscellaneous Files In Solution Explorer check box.

The Miscellaneous Files project has a unique name associated with it that, unlike with other projects, doesn't change over time. This name, <MiscFiles>, is defined by the constant vsMiscFilesProjectUniqueName. The following macro retrieves the Project object for the Miscellaneous Files project:

 Sub FindMiscFilesProject()     Dim project As EnvDTE.Project     Dim projects As EnvDTE.Projects     projects = DTE.Solution.Projects     project = projects.Item(EnvDTE.Constants.vsMiscFilesProjectUniqueName) End Sub 

When the first file is opened within the Miscellaneous Files project, an item is added to the Solution.Projects collection that implements the Project interface. It works just as the Project interface implemented by projects such as Visual Basic or Visual C#, except that a few of the properties will return null or Nothing or throw a System.NotImplementedException when called. Table 8-1 lists the methods and properties of the Project object that return a meaningful value for the Miscellaneous Files project and the ProjectItem and ProjectItems objects contained within this project.

Table 8-1: Methods and Properties of the Project, ProjectItems, and ProjectItem Objects

Project

ProjectItems

ProjectItem

DTE

DTE

DTE

ProjectItems

Parent

Collection

Name (read-only)

Item

Name (read-only)

UniqueName

GetEnumerator / _NewEnum

FileCount

Kind

Kind

Kind

FullName

Count

FileNames

 

ContainingProject

SaveAs

  

Save

  

IsOpen

  

Open

  

Delete

  

Remove

  

ExpandView

  

ContainingProject

  

IsDirty

You can add new files to the Miscellaneous Files project by using the ItemOperations.NewFile method, which has the following method signature:

 public EnvDTE.Window NewFile(string Item = "General\Text File",     string Name = "", string ViewKind =     "{}") 

By applying the techniques we used earlier to calculate the first parameter for the ItemOperations.AddNewItem method, we can find the value that should be passed to the NewFile method. The second parameter also has the same meaning as the second parameter of the ItemOperations.AddNewItem method—the name of the file (with extension) that is to be added—and if the empty string is passed, a default name is calculated. The last argument specifies which view the file should be opened in when it is added. These values can be found within the EnvDTE.Constants class and begin with the name vsViewKind.

Solution Folders

The Miscellaneous Files project lists files that are temporarily open in an editor, and when those files are closed, they are removed from that project. But what if you want to associate a file with a solution, not have that file built as part of a project, and have that file stay within your solution when the editor window for that file has been closed? Solution folders provide a way for you to satisfy these requirements and more. Solution folders can be created by right-clicking on the solution node within the Solution Explorer tool window, and choosing Add | New Solution Folder. Solution folders can also be created within existing solution folders by right-clicking on a solution folder and selecting Add | New Solution Folder. Because solution folders can be nested within one another, you can create a hierarchy of folders, each containing files on disk. Often I need to add a bunch of files to a solution that are not part of a project, and, to keep those files organized, I like to mirror the folder structure on disk with solution folders. Not only can you organize files on disk with solution folders, but you can also use them to organize projects. If your solution contains many projects, you can create a solution folder that contains, for example, all the Web applications in your project, one solution folder for all class libraries, etc. New or existing projects can be added to a solution folder from the context menu for a solution folder, or if the project you want to move is located under the solution node in the Solution Explorer tool window, you can just drag the project into the appropriate solution folder.

A Solution Folder also has a programmatic interface to this functionality. To create a solution folder within a solution, simply call the Solution2.AddSolutionFolder method, supplying a name for the new folder:

  Sub CreateSolutionFolder()      Dim solution2 As EnvDTE80.Solution2      solution2 = CType(DTE.Solution, EnvDTE80.Solution2)      solution2.AddSolutionFolder("My Folder") End Sub 

The AddSolutionFolder method returns an EnvDTE.Project object, which works as any other Project object, such as that available from Visual C# or Visual Basic projects, except you will find that many methods, such as the Save method, will not work for a solution folder because it has no meaning for that project type. The Object property on the Project interface for a solution folder returns an object that you can then cast into the interface EnvDTE80. SolutionFolder. The SolutionFolder interface also has a method named AddSolutionFolder, which will allow you to create a nested folder. This macro is a modified version of the one to add a folder to the solution, but it will also create a nested folder:

  Sub CreateSolutionFolder()      Dim solution2 As EnvDTE80.Solution2      Dim project As EnvDTE.Project      Dim solutionFolder As EnvDTE80.SolutionFolder      solution2 = CType(DTE.Solution, EnvDTE80.Solution2)      project = solution2.AddSolutionFolder("MyFolder")      solutionFolder = CType(project.Object, EnvDTE80.SolutionFolder)      solutionFolder.AddSolutionFolder("My Other Folder") End Sub 

The SolutionFolder interface will also allow you to programmatically add projects or files. The method AddFromFile will take the path to an existing project file (a file with an extension such as .csproj, .vbproj, or .vcproj), and add it to a solution folder. Here is an example of the use of this method, which will first create a solution folder named MyFolder and then will add an existing Visual C# project named ConsoleApplication to that solution folder:

  Sub ProjectAdd()      Dim project As EnvDTE.Project      Dim solutionFolder As EnvDTE80.SolutionFolder      Dim solution2 As EnvDTE80.Solution2      solution2 = CType(DTE.Solution, EnvDTE80.Solution2)      project = solution2.AddSolutionFolder("MyFolder")      solutionFolder = project.Object      solutionFolder.AddFromFile("C:\Project\ConsoleApplication1.csproj") End Sub 

The AddFromTemplate method takes a path to a .vstemplate file, a .vsz file, or an existing project to clone; a path to store the project in; and a name of the new project to create. AddFromTemplate then generates a new project based upon the wizard or the existing project. This macro uses the GetProjectTemplate method of the Solution2 interface to find the path to the Visual C# Console Application template, and then creates a project based upon this template within a new solution folder.

     Sub NewProjectAdd()         Dim project As EnvDTE.Project         Dim solutionFolder As EnvDTE80.SolutionFolder         Dim solution2 As EnvDTE80.Solution2         Dim CSConsoleTemplatePath As String         solution2 = CType(DTE.Solution, EnvDTE80.Solution2)         project = solution2.AddSolutionFolder("MyFolder")         solutionFolder = project.Object         CSConsoleTemplatePath = solution2.GetProjectTemplate _                ("ConsoleApplication.zip", "CSharp")         solutionFolder.AddFromTemplate(CSConsoleTemplatePath, _                "C:\Projects\TestProject", "NewProject")     End Sub 

Adding an existing or new file to a solution folder is done within the Project object by using the AddFrom methods, just as you would add an item to a Visual C# or Visual J# project.

Once you have a solution folder with items located within that folder, you can use the folder as a Project object to locate an item contained within it. For example, suppose you have a solution folder with a project loaded into it. The following macro finds the Project for the solution folder and then obtains the collection of ProjectItems for the solution folder. Even though a project within a solution folder is a project, it is still an item, and so the solution folder allows you to get to a list of ProjectItem objects by using the ProjectItems property. Once you have this ProjectItem object, you can call the Object property to retrieve the object specific to that project item node, which is a project.

 Sub FindProjectInSolutionFolder()         Dim slnFolderProject As Project         Dim containedProject As Project         Dim projectAsAProjectItem As ProjectItem         'Find the solution folder. This code expects one folder and         '  no other items within the solution         slnFolderProject = DTE.Solution.Projects.Item(1)         'Find the project item for the project in the folder         projectAsAProjectItem = slnFolderProject.ProjectItems.Item(1)         'Convert the project item into a Project         containedProject = projectAsAProjectItem.Object         MsgBox(containedProject.Name) End Sub 

This is the only way that you can get to a Project object for a project that is located within a solution folder. The Solution.Projects.Item method will not return a project's object for a project in a solution folder because the Projects.Item method looks only at the projects directly underneath the solution node in Solution Explorer.

If you have a reference to a Project object, either a project such as a Visual J# project or a Project object for a solution folder, and that project is contained within a solution folder, you can find the ProjectItem object of that project within the solution folder by using the ParentProjectItem property. This macro will find a Project object within a solution folder and then walk back up the hierarchy to find the solution folder that contains it.

 Sub FindParentProject()     'First, find the project nested in the solution folder:     Dim nestedProject As Project     Dim solutionFolder As Project     solutionFolder = DTE.Solution.Projects.Item(1)     nestedProject = solutionFolder.ProjectItems.Item(1).Object     'Now, find the solution folder parent of the nested project     Dim parentProjectItem As ProjectItem     Dim parentProject As Project     parentProjectItem = nestedProject.ParentProjectItem     parentProject = parentProjectItem.ContainingProject     'Make sure the parent project and the solution folder are the same     MsgBox(parentProject.UniqueName = solutionFolder.UniqueName) End Sub 

Unmodeled Projects

All the project types we've discussed so far have implemented a Project object that can be used by a macro or an add-in. However, a few project types, such as a database project or a project that has been unloaded by using the Project | Unload Project command, don't implement the Project object themselves. To allow some programmability for these project types, Visual Studio supports the unmodeled project type. An unmodeled project provides an implementation of the Project object that supports only the properties common among all project types, which are DTE, Kind, and Name. All other properties and methods on this implementation of the Project object return values that have no useful meaning or generate an exception when called and shouldn't be used by a macro or an add-in. You can distinguish an unmodeled project from other project types by checking the Project.Kind property, which returns the constant EnvDTE.Constants.vsProjectKindUnmodeled if the project is an unmodeled project. The following macro enumerates all the projects loaded into a solution and determines which ones are unmodeled:

 Sub FindUnmodeledProjects()        Dim project As EnvDTE.Project        For Each project In DTE.Solution.Projects            If (project.Kind = EnvDTE.Constants.vsProjectKindUnmodeled) Then               MsgBox(project.Name + " is unmodeled")            End If        Next End Sub 




Working with Microsoft Visual Studio 2005
Working with Microsoft Visual Studio 2005
ISBN: 0735623155
EAN: 2147483647
Year: 2006
Pages: 100

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net