WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

Hacking Visual Studio
Pages: 1, 2, 3, 4, 5

Hack the Project and Solution Files

Discover the format of these two Visual Studio files and learn about a tool to convert these files between versions of Visual Studio.

Solution and project files are an essential part of working with Visual Studio. You will almost always work with the solution and project files through the IDE, whether adding projects to your solution or configuring your project. The purpose of this hack is to describe the format of these files for two reasons. If your project or solution files become corrupted, knowing the structure of these files might help you fix the file without having to re-create the entire project or solution. Also, knowing the structure of these files will help you if you want to convert these files or write a tool that works directly with these files.

WARNING You must edit these files with extreme care. The format of these files is not published or documented and could change drastically in future versions. You should normally need to work with these files only through the IDE, and unless you find a compelling reason to, I would not directly edit these files. If you are interested only in converting the version of these files, then you may want to look toward the end of this hack under Section 1.5.3 to read about a tool that will do the conversion for you.

Solution Files

Visual Studio creates two separate files when you create a new solution in Visual Studio. The first file is the .suo (solution user options) file, which stores user settings such as the location of your breakpoints. This file is stored in binary format, which does not lend itself to easy editing. Since there are no compelling reasons to edit this file, I am not going to document the format of it here. If you think that this file is preventing your solution from opening, you can actually delete the file and Visual Studio will create a new one when you open the solution and save it when you close the IDE. By deleting the file, you will lose any of your user-specific settings like breakpoints, but this is a small price to pay for saving your solution. The .suo file is a hidden file, so you will need to make sure Windows Explorer is configured to show hidden files (this can be set through Tools → Folder Options → View in any Explorer window).

The second file that Visual Studio creates is the .sln file. This file stores information about the projects that make up this solution, source control settings, and other global settings that apply to all of the projects in the solution.

The first line of the solution file contains a declaration including the version of Visual Studio that this solution is built for:

Microsoft Visual Studio Solution File, Format Version 8.0

The version number used in the solution file is a little different than the version number you are used to seeing in the Visual Studio product name. Visual Studio .NET 2002 solution files have a version number of 7.0. Visual Studio .NET 2003 solution files have a version number of 8.0 (as opposed to the 7.1 number you are used to), and Visual Studio 2005 solutions files have a version number of 9.0. Visual Studio 2005 Beta 1 contains an additional line under this first line, which contains just the following:

# Visual Studio 2005

This line causes the icon of the file to be changed to a Visual Studio 2005-specific icon, and if removed, will prevent Visual Studio from opening this file when you double-click on it.

The next portion of the solution file contains a section for each of the projects that are contained in this solution:

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HacksWinApp", 
"HacksWinApp\HacksWinApp.csproj", 

"{75B7D1AE-1896-409D-B717-64D9AFCF0F59}"
    ProjectSection(ProjectDependencies) = postProject
        {89EE0E8E-C5C6-4772-A5EE-D347E40FB0E4} = 
        {89EE0E8E-C5C6-4772-A5EE-D347E40FB0E4}
    EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HacksLib", 
"HacksLib\HacksLib.csproj", "{89EE0E8E-C5C6-4772-A5EE-D347E40FB0E4}"
    ProjectSection(ProjectDependencies) = postProject
    EndProjectSection
EndProject

You can see that the syntax of the file is somewhat similar to Visual Basic. Each project has a Project and EndProject tag as well as a ProjectSection tag to track the dependencies for the project. The first GUID in the project tag is used to identify what type of project this is. In this instance, the GUIDs for both a C# Windows Forms project and a C# library project are the same, since these project types are really the same except for the output type setting. The strings on the right side of the equals sign include the name of the project, its path relative to the solution root, and the unique GUID for this project. This GUID is used for a number of things including tracking dependencies.

TIP: You can view a list of all the project GUIDS by opening regedit (Start → Run, then type regedit) and navigating to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.1\Projects.

Under this key are all the GUIDs for the project available on your machine; the name and the extension of the project are listed as well.

In Visual Studio .NET 2003 and Visual Studio 2005, project dependencies are also tracked here. These are not the implicit dependences that are created by project references. When Project A references Project B, there is an implicit dependency. Project B must be built before Project A since it references the other project's output. Since this type of dependency is project-specific information, it is stored in the project file. (In this example, it would be stored in Project A's project file since it is referencing Project B, rather than the solution file we are looking at here.) Project files and dependencies are described in the next section.

The dependences stored in the ProjectSection tag are configured at the solution level. They define when a project must be built before another project, but they may not directly reference each other. This is stored in the ProjectSection tag of the project that is dependent on the other project. In this example, the HacksWinApp project is dependent on the HacksLib project and thus includes a reference to the GUID of the other project. This dependency is normally configured by right-clicking on the solution file, selecting Properties from the context menu, and navigating to Project Dependencies in the property page that appears.

Visual Studio .NET 2003 includes a ProjectSection tag even if there is no dependency (you can see this in the HacksLib project tag). Visual Studio 2005 completely omits the ProjectSection tag if there are no dependencies for the project. Visual Studio .NET 2002 stores the dependency information in a completely different section of the solution file, which we will cover next.

The next section in the solution file is the Global section, which begins with a Global tag and ends with an EndGlobal tag. Inside these tags are a number of GlobalSection tags that store an array of different pieces of information, including the configuration settings for various projects as well as source control information. Here is a look at the Global section of this example solution file from Visual Studio .NET 2003:

Global
    GlobalSection(SolutionConfiguration) = preSolution
        Debug = Debug
        Release = Release
    EndGlobalSection
    GlobalSection(ProjectConfiguration) = postSolution
        {75B7D1AE-1896-409D-B717-64D9AFCF0F59}.Debug.ActiveCfg 
         = Debug|.NET
        {75B7D1AE-1896-409D-B717-64D9AFCF0F59}.Debug.Build.0 
         = Debug|.NET
        {75B7D1AE-1896-409D-B717-64D9AFCF0F59}.Release.ActiveCfg 
         = Release|.NET
        {75B7D1AE-1896-409D-B717-64D9AFCF0F59}.Release.Build.0 
         = Release|.NET
        {89EE0E8E-C5C6-4772-A5EE-D347E40FB0E4}.Debug.ActiveCfg 
         = Debug|.NET
        {89EE0E8E-C5C6-4772-A5EE-D347E40FB0E4}.Debug.Build.0 
         = Debug|.NET
        {89EE0E8E-C5C6-4772-A5EE-D347E40FB0E4}.Release.ActiveCfg 
         = Release|.NET
        {89EE0E8E-C5C6-4772-A5EE-D347E40FB0E4}.Release.Build.0 
         = Release|.NET
    EndGlobalSection
    GlobalSection(ExtensibilityGlobals) = postSolution
    EndGlobalSection
    GlobalSection(ExtensibilityAddIns) = postSolution
    EndGlobalSection
EndGlobal

The SolutionConfiguration and ProjectConfiguration sections contain the build configuration settings for the solution and its projects. The ExtensibilityGlobals and ExtensibilityAddIns sections are included for the benefit of add-in authors. The ExtensibilityGlobals section can be used to store global information about the solution, and the ExtensibilityAddIns section lists all the add-ins that are used in this solution.

Visual Studio .NET 2002 also uses the Global section to store information about project dependences. Here is an example of that configuration section:

GlobalSection(ProjectDependencies) = postSolution
        {1C19F285-69AF-409E-8D5B-A354B68B41FF}.0 
        = {CBBAD9B0-CB56-44CA-8312-A9258F2061E2}
EndGlobalSection

This section simply specifies that the project identified by its GUID on the left of the equals sign depends on the project identified by its GUID on the right side of the equals sign.

Visual Studio 2005 includes an additional section that is not present in any of the older versions of Visual Studio; it's shown here:

    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection

If the FALSE is switched to TRUE, then the solution node is hidden in the IDE.

Project Files

Each project creates a number of files to store information about itself. This includes a project file and a user settings file. The extension for the project file is based on the language type; for example, a C# Project is saved with the extension .csproj and a VB.NET Project is stored with the extension .vbproj. Thankfully, the internal formats of these various files are based on the same XML schema. The beginning of each project file includes some basic information about the project, including the version of Visual Studio that it was created for as well as the GUID for this project. Here is an example of this section:

<VisualStudioProject>
<CSHARP
        ProjectType = "Local"
        ProductVersion = "7.10.3077"
        SchemaVersion = "2.0"
        ProjectGuid = "{89EE0E8E-C5C6-4772-A5EE-D347E40FB0E4}"

    >

This is from a Visual Studio .NET 2003 project file, which is why the ProductVersion is set to 7.1 and the SchemaVersion is set to 2.0. In Visual Studio .NET 2002, the ProductVersion would be 7.0 and the SchemaVersion would be 1.0. These settings are no longer relevant in Visual Studio 2005 as project files are now MSBuild files.

TIP: Notice that the version number used for Visual Studio .NET 2003 is 7.1 in the project file and 8.0 in the Solution file.

The next section of the project file is the Build section, which includes build settings and configuration settings as well as references information. Here is the Build settings section:

<Build>

    <Settings
         ApplicationIcon = ""
         AssemblyKeyContainerName = ""
         AssemblyName = "HacksLib"
         AssemblyOriginatorKeyFile = ""
         DefaultClientScript = "JScript"

         DefaultHTMLPageLayout = "Grid"
         DefaultTargetSchema = "IE50"
         DelaySign = "false"
         OutputType = "Library"
         PreBuildEvent = ""

         PostBuildEvent = ""
         RootNamespace = "HacksLib"
         RunPostBuildEvent = "OnBuildSuccess"
         StartupObject = "">

As you can see, this section includes information like the AssemblyName and OutputType of the project. The next part of the Build section is for the various build configurations:

<Config
    Name = "Debug"
    AllowUnsafeBlocks = "false"
    BaseAddress = "285212672"

    CheckForOverflowUnderflow = "false"
    ConfigurationOverrideFile = ""
    DefineConstants = "DEBUG;TRACE"
    DocumentationFile = ""
    DebugSymbols = "true"

    FileAlignment = "4096"
    IncrementalBuild = "false"
    NoStdLib = "false"
    NoWarn = ""
    Optimize = "false"

    OutputPath = "bin\Debug\"
    RegisterForComInterop = "false"
    RemoveIntegerChecks = "false"
    TreatWarningsAsErrors = "false"
    WarningLevel = "4"/>

This section includes configuration-specific build settings. The project file will usually contain at least a Debug and Release section. The next part of the Build section contains all of the references for this project. Here is an abbreviated example of this section:

<References>
    <Reference
     Name = "System"

     AssemblyName = "System"
     HintPath = "..\..\..\..\..\..\..\..\..\..\WINDOWS\Microsoft.NET\
                 Framework\v1.1.4322\System.dll"
</References></Build>

The References section contains a reference tag for each assembly referenced by the project. Starting with Visual Studio 2005, you can create a reference to either an assembly or an executable, which comes in very handy when you are trying to unit-test a Windows application, since this lets you directly reference your application. To get this same functionality in Visual Studio .NET 2003, you can actually hack the project file to create a reference to an executable—you simply need to manually enter a reference tag in the references element pointing to your executable. Your new reference tag would look exactly like this example, except it would be pointed to an .exe file instead of a .dll file.

After the Build section is theFiles section of the project file, which can be seen here:

<Files>
            <Include>

                <File
                    RelPath = "AssemblyInfo.cs"
                    SubType = "Code"
                    BuildAction = "Compile"
                />
                <File
                    RelPath = "Class1.cs"

                    SubType = "Code"
                    BuildAction = "Compile"
                />
            </Include>
        </Files>

    </CSHARP>
</VisualStudioProject>

This section simply tracks all of the files that are included in this project. The schema of the project file is pretty straightforward in case you need to edit it directly.

Visual Studio also creates a user-specific project file much like the .suo file created for the solution file except with an extension of <projectextension>.user, so if you were using VB.NET, it would be vbproj.user. Similarly, this user-specific file does not contain anything pertinent enough to cover here, and is also hidden by default, so you will need configure Windows Explorer to show hidden files through Tools → Folder Options → View.

Visual Studio 2005 has not been mentioned up until this point because the project files in Visual Studio 2005 are completely different than the project files in Visual Studio .NET 2002 and 2003. The project files in Visual Studio 2005 are MSBuild XML files. MSBuild is the new build tool used in Visual Studio 2005 and is a completely different, complex topic that is not going to be covered here. It is similar to NAnt in that is uses XML files to describe how the project should be built.

Project and Solution File Conversion

Visual Studio does an excellent job of converting files from older versions to newer versions. For instance, if you open a Visual Studio .NET 2002 solution in Visual Studio .NET 2003, it will first ask if you want to convert the solution. After you say yes, it will convert all of your solution and project files to the new version of Visual Studio .NET. Now what if you accidentally converted those files and didn't have a backup? Or perhaps you are writing a solution in Visual Studio .NET 2003 and find out that your client has only Visual Studio .NET 2002? One method would be to create a new solution in the old version, create an identical project structure, and then copy all the files over and add them to their respective projects. Thankfully, there is a better solution. There is a tool available that will automatically convert the project and solution files for you as well as the .resx files if you are using Windows Forms.

The tool is called Visual Studio Converter 2.0 and can be downloaded from http://www.codeproject.com/macro/vsconvert.asp.

This tool is simple to use. Figure 1-15 shows an example of this conversion tool's user interface.


Figure 1-15. Visual Studio Converter 2.0

To convert files, you first need to click the Add Files button and select all the solution, projects, and .resx files for your solution. For a simple, one-form C# Windows Forms application, you would need to include the .sln, .csproj, .csproj.user, and Form1.resx. You will have an additional .resx file for each form in your application. Next, you need to click one of the two conversion buttons to convert the files to either Visual Studio 7.0 (2002) or Visual Studio 7.1 (2003). When initially converting a 2002 project to the 2003 format, it is best to use the Visual Studio conversion process. After this initial process, this tool is a great way to convert the files back and forth as needed.

Currently, it converts only between Visual Studio .NET 2002 and Visual Studio .NET 2003.

Pages: 1, 2, 3, 4, 5

Next Pagearrow