VC++ Directories

The goal of this post is to quickly explain what VC++ Directories are, what happened to them in VS 2010 and why the change was made.

Life in VS 2008

To start with, let’s take a look at the VS 2008 feature of VC++ Directories. If you were to go to the Tools->Options menu, you would see the following under the Project and Solutions settings

These are the IDE equivalents to the command line environment variables of PATH, INCLUDE, etc. However, these values only apply within the IDE or vcbuild.exe – they don’t apply when executing cl.exe, for example, directly from the command line. Additionally, as you can see from the Platform dropdown at the top of the dialog, you can customize these settings for each platform.

The implementation for these settings is to store the values in the VCComponents.dat file stored in %LOCALAPPDATA%\Microsoft\VisualStudio\9.0. Looking at the file, you’ll notice two things. First, it is in the LocalAppData directory, which means the settings are per-user, per-machine. The second thing you’ll notice is that the file is in an INI format, not the XML of a .vcproj file. This shows that the importing of the .dat file is some custom code of vcbuild.exe and the IDE.

Changes in VS 2010

The first thing you’ll notice in VS 2010 when working with VC++ Directories is that they appear to have disappeared. When you go to the Tools->Options window and look in Project and Solutions, you’ll see the window looks very similar to the screenshot above – only VC++ Directories is gone. However, if you bring up a VC++ project in the IDE and open the project properties window (right-click on the project node and select Properties), you will notice a Rule called VC++ Directories (Rules are the tree of selections on the left pane of the property page window) and that the values you see are the same defaults that you would get from VS 2008. Additionally, you can edit these properties in the same way as any other project property (including using the macro editor as shown – something not possible in VS 2008).

Of course, any edits you make right here are applied directly to the project you are working on – and directly to the project file itself. This means that the edits are NOT per-user, per-machine as they were in VS 2008. However, that option still exists in the form of a property sheet (If you don’t know about property sheets or how they work in VS 2010, I recommend reading my previous post about them here).

If you open up the Property Manager view to see the property sheets associated with your project, you’ll see that one of the property sheets is named Microsoft.Cpp.Win32.User. This property sheet is actually stored in LocalAppData, just as VCComponents.dat file was, in the directory %LocalAppData%\Microsoft\VisualStudio\10.0. Using the property editor on the property sheet (just right-click on this property sheet node and select Properties…), you can see that you are able to make edits directly to this file. Since all projects, by default, import this property sheet, you are effectively editing the VC++ directories in the same way you were able to do before.

Additionally, you can also delete the reference to this per-user, per-machine property sheet and create your own set of property sheets that set these values. Deleting the reference to this property sheet makes your project operate independently of any per-user, per-machine settings – and important step when trying to ensure correct behavior in a SCC (source code control) environment.

Why the Changes?

A reasonable question would be to ask why these changes were done. There are several reasons.

  1. VS 2008 VC++ Directories were applied to all projects loaded on that machine and could not be stopped.
    This is probably the biggest reason for the change. We’ve had many customers complain that they had different projects with very different setups. As you are probably well aware, the order that directories are listed for things like PATH and INCLUDE can have dramatic effects on the results of builds and being unable to customize these values easily on per-project (or groups of projects) basis required many unfortunate hacks by our customers.
  2. VS 2008 VC++ Directories were per-user, per-machine and made SCC enlistments fragile.
    Imagine that you want to be able to check in your entire project system – not just the source files and project files, but the entire build system as well. If you could do that, then you could go up to any machine with only the SCC system installed, check out the project system and build. However, if your build was dependent on settings that were per-machine, as in the case of VCComponents.dat, that was impossible. Instead, by deleting the reference to the per-user property sheet, a VS 2010-based build system can be made fully enlistment-based – a key feature we wanted to provide in VS 2010.
  3. VC 2008 VC++ Directories were inconsistent with the rest of the build technology.
    This is a minor, but satisfying, improvement. The VCComponents.dat was an INI based file that was hard-wired into the vcbuild engine, whereas the property sheet is a standard MSBuild file that uses the build-in rules of any MSBuild import – learning the one MSBuild language is all that is required. As a side benefit, the editing experience of the VC++ directories is also made consistent by moving the editor into the property editor.

A Note About Import/Export Settings

As part of moving the VC++ Directories out of the Tools->Options and into property sheets, I should also note that this means they are no longer considered part of VC++ Settings in Visual Studio. The settings are meant for IDE specific configuration settings, and VC++ Directories are now built-in directly to the build process and are found via standard property sheet mechanisms. Therefore there is no longer any need to have these participate in import/export – they are put into a single property sheet file (by default) that can be shared between different versions of VS – and work the same both inside and outside of the IDE.

The one exception to this is migration – if you migrate your settings from VS2008, the VC++ directories from the earlier version will be migrated up and into the per-user property sheet file for you.

For SDK Authors

As a closing remark for those of you out there that would edit the VC++ Directories as part of your SDK installation. That scenario is still supported – either via the VCProjectEngine APIs or by directly editing the new property sheet (see the MSBuild APIs for simply editing access). However, I would also urge you to think anew about what it means to install your SDK.

The VC++ Directories approach does provide a way to install your SDK into the user’s build system, but it has a few major drawbacks.

  1. You can’t uninstall – at least not easily – given the other changes that the user may have done since the install.
  2. You are automatically applied to all projects, whether they want to use your SDK or not.
  3. In VS 2010, you are no longer necessarily applied to all projects because the per-user property sheet link may have been removed.

Instead, think about how you can provide the options for customers to enable you in their projects. For example, if you provide your own property sheets than can be added into the customers projects on demand, then the user has control over their environment – and you can also be checked into the SCC enlistment, enabling the enlistment scenario described earlier.

The downside of this approach, of course, is that the SDK isn’t immediately available after installation. This is an opt-in model. But using the tool extensibility, controlled by switches, you can also create a system that is an opt-out as well. Basically, the new directories design combined with the new extensibility model provides a lot of flexibility. We’d love to work with all the SDK providers to try to come up with some best practices and patterns – so drop us a line!