A while ago, I blew quite a few Visual Studio Solution and Project builds because I was experimenting in a suite of solutions with the Configuration Manager adding other Solution Configurations than Release and Debug, and mixing x86/AnyCPU platforms to facilitate Debug & Continue.
Lesson learned: don’t do that!
Keep it simple:
- Keep your Solution Configurations at Release and Debug,
- Perform conditional defines in your automated build server,
- Limit the mixing your platforms to a minimum.
We noted the anomalies a little late in the process (in retrospect, when taking over the solution suite, we should have started with setting up and Build Automation right at the beginning, then fix all the solutions that came from Visual Source Shredder, but alas: you are never too old to learn from your mistakes).
The anomalies were spurious (and hard to reproduce) build failures at developer workstations, wrong builds of assemblies ending up on the final build directories and more. And best of all: Visual Studio not failing, warning or hinting upon most issues.
Fixing projects and solutions from wrong Solution Configurations
The history in the version control system was not helpful enough to assist in fixing it, so the fix was this:
- Manually edit the .csproj files, and remove the PropertyGroup elements other than “Debug|AnyCPU” and “Release”AnyCPU”.
This is easy to do inside Visual Studio and with automatic checkout from TFS of the project files:
- In the Solution Explorer, select all the projects
- Right click on a project
- Choose “Unload Project”
(because you selected all the projects, it is the second menu item from the bottom, and way easier to find when you do this per project)
- For each project
- Right click the project
- Choose “Edit ….”
- Remove the PropertyGroup elemts you don’t need
- Save and close the file
- Right click the project
- Choose “Reload Project”
- Fix the solution files
The last step is a lot more complex, because of a couple of reasons:
My workaround was as follows:
- Start with an empty solution in the same directory as the original solution
- Add all the Solution Folders, Solution Items, and projects to it that were in the original solution
(having two copies of Visual Studio next to each other on a dual monitor setup is of great help)
- Compare the .sln files to each other
- Check out the original .sln file
- Merge any changes into the original .sln file
- Build it
- Check in
- Run a build on the CruiseControl.net automated build server
- Fix build errors
- Delete the temporary local .sln file
Creating an empty solution in a directory
Finally, I get to the title of this blog entry: Visual Studio will always generate a directory when creating a Blank Solution, and does not support creating an Empty Solution in a directory.
There are many posts describing how to workaround this, but the actual downloads are usually gone because of link rot (Jakob Nielsen’s alert from 1998 still is totally right about it). Thanks to they webarchive.org WayBackMachine though for keeping some of them alive.
So I went with Peter Provost’s solution, and amended it from Visual Studio 2005 to all Visual Studio versions that support .NET that I have used or still use: 2002, 2003, 2005, 2008, 2010 and 2012 a.k.a. VS11.
All files are in Change set 89386 on BeSharp.CodePlex.com.
His solution uses the ShellNew command for .sln file extensions that is stored in the registry:
- Create an empty solution file for the Visual Studio version you are using
- Copy that as a template file to %Windir%\ShellNew
(you need to be administrator for that)
- Import a small .reg file binding that template file to the ShellNew command for .sln files
ShellNew is versatile, so you can also embed the fresh solution file into the .reg file, see this ShellNew article for a few nice examples.
Note that generating a new ShellNew verb for .sln is something other than loading a .sln (loading a .sln is done through VisualStudioLauncher).
Back to the .sln file: this one is different for any version of Visual Studio. Historically, the basic format is the same though (and I think this – in combination with VisualStudioLauncher – is the main reason it is not XML).
An empty solution file looks like this (note the empty line at the beginning), as described in Hack the Project and Solution Files:
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 11
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
The accompanying .reg file like this:
Windows Registry Editor Version 5.00
"FileName"="Visual Studio Solution - VS11.sln"
When you look at the Format Version inside the .sln version, you see that it (12) is one bigger than the internal Visual Studio Version (11).
That is because Microsoft stepped up the internal version from Visual Studio .NET (2002) and Visual Studio 2003 from 7.0 to 7.1, but the solution file format version from 7.00 to 8.00 as the table below shows.
Note that the .NET 1.x versions of Visual Studio (2002 for .NET 1.0, 2003 for .NET 1.1) don’t have the
GlobalSection/HideSolutionNode/EndGlobalSection part and the
# Visual Studio xx line.
With a little bit of querying, I got at this table:
|Visual Studio version
||Solution file format version
|Visual Studio .NET (2002)
||Microsoft Visual Studio Solution File, Format Version 7.00
|Visual Studio 2003
||Microsoft Visual Studio Solution File, Format Version 8.00
|Visual Studio 2005
||Microsoft Visual Studio Solution File, Format Version 9.00
|Visual Studio 2008
||Microsoft Visual Studio Solution File, Format Version 10.00
|Visual Studio 2010
||Microsoft Visual Studio Solution File, Format Version 11.00
|Visual Studio 2012 (a.k.a. VS11)
||Microsoft Visual Studio Solution File, Format Version 12.00
All files to get you going are in Change set 89386 on BeSharp.CodePlex.com.
It was a bit hard to get all those version numbers, so here are the sources I used: