We converted all of our projects to Visual Studio 2010 a couple of weeks ago, as a first step towards upgrading the production machines to .NET 4.0. I was very pleased at how painless the conversion from Visual Studio 2008 went. There were a few glitches, but in just a day we had all 100+ projects converted and nothing went wrong.
Since then, I’ve been testing the code with .NET 4.0, making sure that programs still talk to each other, that we can still read our custom data format, and that the programs actually work as expected. Call me paranoid, but when the business depends on the software, I try to make absolutely sure that everything’s working before I throw the switch on a major platform change.
All the tests have been successful. I’ve not found anything that breaks under .NET 4.0. I hadn’t expected anything, but I had to test anyway. So this morning my job was to merge my project changes into our source repository and ensure that the automated build works.
The merge was no problem. The automated build failed. It failed because I didn’t check in some files. Which files? I’m so glad you asked.
A convention in .NET is that you can store application-specific configuration information in what’s called an application configuration file that you ship along with the executable. The file, if it exists, is usually named <application name>.config, so if your executable program is hello.exe, then the configuration would be called hello.exe.config. As a convention, it works quite well.
The major point here is that the application configuration file is optional. If you don’t want to store any information there, then you don’t need the file.
In Visual Studio, the tool lets you create a file called App.config to hold the configuration information. When you build the program, Visual Studio copies App.config to the build output directory and renames it. Continuing the above example, App.config would become hello.exe.config.
So far so good. All that still works as expected in Visual Studio 2010. Until, that is, you change the program’s target framework in the build options from .NET 3.5 to .NET 4.0. Then, Visual Studio becomes helpful. It automatically creates an App.config file for you, places it in your source directory, and updates your project settings to reflect the new file. So helpful.
And so broken!
It’s broken because when I subsequently check in the modified project (which I thought I just changed to target .NET 4.0), the project also contains a new and unknown to me reference to the App.config file, which I did not check in. So when my automated build script checks out the code and tries to build the solution, every executable project failed with a missing file.
That Visual Studio added a file and didn’t tell me is merely annoying. What really chaps my hide, though, is that the file it added is extraneous. It contains no required information. Here is the entire contents of the file that Visual Studio so helpfully added:
<?xml version="1.0"?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> </configuration>
My options at this point are: 1) Go through the compiler errors and check in every App.config file that was automatically created; 2) Edit the projects to remove the file references.
I’d like to do #2, but if I do I’ll just run into this same problem again the next time I upgrade Visual Studio.
The final result is that it took me an extra hour to get my build to work, and now every executable program that I deploy has an extraneous file tagging along as useless baggage. It’s extra work to eliminate those files in the deployment process, and in doing so I might eliminate one that I really need. In the past, only programs that really needed the configuration files had them, and I knew that the existence of the file meant that there were settings I could modify. Now that every program has a configuration file, I’ll be forever checking to see if there are settings that change the application’s behavior.
So, to sum up. Visual Studio adds an unnecessary file, modifies the project, doesn’t notify me of the added file, fails to build if the file isn’t checked in, forces me to deploy that unnecessary file or somehow modify my build process to delete it, and the resulting file will lead to uncertainty on the part of the user. Wow. Who could have thought that a single simple feature would cause so much unnecessary work and annoyance?