Hack 4. Hack the Project and Solution Files

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.
|
1.5.1. 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
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.0The 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 2005This 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",You can see that the syntax of the file is somewhat similar to Visual
"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
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.
|
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:
GlobalThe
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
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) = postSolutionThis section simply specifies that the project identified by its GUID
{1C19F285-69AF-409E-8D5B-A354B68B41FF}.0
= {CBBAD9B0-CB56-44CA-8312-A9258F2061E2}
EndGlobalSection
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) = preSolutionIf the FALSE is switched to TRUE, then the solution node is hidden in
HideSolutionNode = FALSE
EndGlobalSection
the IDE.
1.5.2. 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>This is from a Visual Studio .NET 2003 project file, which is why the
<CSHARP
ProjectType = "Local"
ProductVersion = "7.10.3077"
SchemaVersion = "2.0"
ProjectGuid = "{89EE0E8E-C5C6-4772-A5EE-D347E40FB0E4}"
>
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.
|
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>As you can see, this section includes information like the
<Settings
ApplicationIcon = "
AssemblyKeyContainerName = "
AssemblyName = "HacksLib"
AssemblyOriginatorKeyFile = "
DefaultClientScript = "JScript"
DefaultHTMLPageLayout = "Grid"
DefaultTargetSchema = "IE50"
DelaySign = "false"
OutputType = "Library"
PreBuildEvent = "
PostBuildEvent = "
RootNamespace = "HacksLib"
RunPostBuildEvent = "OnBuildSuccess"
StartupObject = ">
AssemblyName and
OutputType of the project. The
next part of the Build section is for the various
build configurations:
<ConfigThis section includes configuration-specific build settings. The
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"/>
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>The
<Reference
Name = "System"
AssemblyName = "System"
HintPath = "..\..\..\..\..\..\..\..\..\..\WINDOWS\Microsoft.NETFramework\v1.1.4322\System.dll"
</References></Build>
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 executableyou 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
the
Files section of the project file, which can be
seen here:
<Files>This section simply tracks all of the files that are included in this
<Include>
<File
RelPath = "AssemblyInfo.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "Class1.cs"
SubType = "Code"
BuildAction = "Compile"
/>
</Include>
</Files>
</CSHARP>
</VisualStudioProject>
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
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.
1.5.3. 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

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.