If you use XNA Game Studio 3.1 with Visual C# Express, you can’t use the VS add-in I wrote which makes content pipeline debugging 400% more awesome. Instead, you’re probably feeling sorry for yourself that the best suggestion you’ve heard so far requires you to install a bunch of extra stuff and rebuild your project each time you want to set a breakpoint. Well, start feeling better because I’m going to explain how to easily debug the content pipeline using VC# Express Edition. This method is harder to explain and takes a tiny bit of setup, but it’s easier to use, and you’ll save yourself time each time you debug. In the long run, understanding how to get the most out of your tools will be well worth it, so read on!
Start External Program – The Basics
In Visual Studio, the Debug property page provides the option of starting a program of your choosing when you use the “Start Debugging” command (or F5). That’s incredibly useful, because the content in your game project is stored in an MSBuild project file, and the VS IDE uses MSBuild to build it. So to debug the content pipeline, all you need to do is set the external program to MSBuild.exe, and supply the content project file name as a command-line argument (see example below).
After setting up your project this way, you will debug MSBuild.exe when you press F5 instead of your game project, and that means you’ll hit breakpoints in your content pipeline extensions when they execute.
NOTE: Although a console window will appear for MSBuild.exe when you start debugging, the IDE will redirect ALL of its output to the Debug pane of the Output Window. As a result, the console window will remain empty.
In VC# Express, the Debug page doesn’t expose this option. HOWEVER, it still has the ability to launch an external program. That means you can use it, even though there are no controls in the IDE which will enable it. Keep reading to find out how.
In Visual Studio, if you edit the properties in the Debug page and start debugging, a careful observer will notice the IDE saves these settings in a new file in the project directory. The file name matches the project name, except is has “.user” tacked onto the end. So, if the project is named “ABCGame.csproj”, then the file with the debug settings will be “ABCGame.csproj.user”.
Referring to the example screen shot above, here’s the exact contents of the .user file created for me:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" ‘$(Configuration)|$(Platform)’ == ‘Debug|x86′ ">
<StartAction>Program</StartAction>
<StartProgram>C:\Windows\Microsoft.NET\Framework\v3.5\MSBuild.exe</StartProgram>
<StartArguments>Content\content.contentproj</StartArguments>
<StartWorkingDirectory>C:\Users\Stephen\Documents\Visual Studio 2008\Projects\XNA Samples\SkinnedModelExtensions\SkinnedModelExtensions\SkinningSample\</StartWorkingDirectory>
</PropertyGroup>
</Project>
Even though VC# Express doesn’t provide a way to edit this file’s “Start*” properties in the IDE, VC# Express will use them if they exist. That means all you need to do is copy-paste the text above into a new file, and name it “ABCGame.csproj.user” (where ABCGame is replaced with your project’s name).
NOTE: You have more than one version of msbuild.exe on your machine. The version you want for VC# 2008 is version 3.5. If you have a 64-bit version of Windows, you also want the 32-bit version of msbuild.exe (ie, don’t select msbuild.exe from the Framework64 directory).
Stuff You Need to Consider
The example above will start msbuild.exe when you press F5 and let you debug it as it builds your content project with the default settings. By default, builds are incremental. That means your pipeline extensions won’t execute unless something changes, and that means you might not hit your breakpoints because your code won’t be executed. Since the point of debugging the content pipeline is probably to hit breakpoints in your code and see what’s going on, you really want to tell msbuild to build the project every time you debug, and not just the first time.
Another thing you might want to do is debug the way your content builds for another platform. Or, maybe you want to specifically debug the non-debug build.
The following table of command-line options can be appended to the StartArguments property to control different aspects of the build:
| Argument | Description |
| /t:Rebuild | Tells MSBuild to rebuild the project every time you debug. This ensures your custom processors will run, instead of skipping over them if you’ve already built the content once before. Also, when you stop debugging without completing a build, you are almost guaranteed to mess up the intermediate files, and this option forces them to be discarded. |
| /p:XNAContentPipelineTargetPlatform=Xbox360 | Tells the content pipeline build task to build content for Xbox 360. Valid values are Windows, Xbox360, and Zune. Since a lot of people first run into problems when trying to build content for Xbox 360, this is a good one to know about.
NOTE: “Xbox360” should be specified without a space. |
| /v:Normal | Configures MSBuild logging verbosity. The default setting is minimal, which doesn’t help much when you’re debugging. Interesting values are Normal, Detailed, and Diagnostic.
NOTE: Diagnostic output makes the build very, very slow. This is because diagnostic logging produces tremendous amounts of output, and all that output is being redirected across processes to the Output Window in the IDE. |
| /p:Configuration=Debug | Specifies which project configuration to build when resolving project dependencies (eg, the pipeline extension library you want to debug). |
| "/p:Platform=Xbox 360" | Specifies which project platform to build when resolving project dependencies (eg, the pipeline extension library you want to debug).
NOTE: The entire expression needs to be enclosed in quotes to preserve spaces. This is important when trying to build for Xbox 360. |
Configuring the IDE for Faster Pipeline Debugging
When you use the Start Debugging command (F5), the typical behavior for VS or VC# Express is to save all files and then build the solution’s active configuration before launching the debugger. If you’re more advanced (esp. if you read my blog), you might have configured the IDE to build only the startup project and its dependencies instead of the entire solution. Well, in this case you don’t really want to build anything before you debug the build.
Building before you debug the build won’t do anything but slow you down. I recommend you create a new Solution Configuration so you can tell the IDE not to build anything when you don’t really care. Here’s how to create a DebugPipeline configuration:
- Select Build->Configuration Manager… from the main menu.
- Expand the combobox labeled “Active solution configuration” and choose “<New…>”.
- Name the configuration “DebugPipeline”, choose to copy settings from “<Empty>”, uncheck the box that says to create project configurations, and then press OK.
- Expand the combobox in the Configuration column of the game project which contains the content project you want to debug, and select “New…”.
- Name the configuration “DebugPipeline”, choose to copy settings from “<Empty>”, uncheck the box that says to create solution configurations, and then press OK.
- Now, in the Configuration Manager dialog, uncheck ALL the boxes in the Build column. If you see a Deploy column, uncheck all the boxes there, too.
- Press Close.
This is an example of what you should see in step 3.
This is an example of what you should see in step 4.
What you just did is create a Solution Configuration which will skip building and deploying before you start debugging. You also created a Project Configuration for the startup project. Now, you can easily switch between a Debug or Release configuration and the DebugPipeline configuration, just by using the Solution Configuration combobox on the Standard Toolbar (see example below).
There’s just one last thing to do: edit the .user file so that the customized Start arguments are only set in the DebugPipeline configuration.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" ‘$(Configuration)|$(Platform)’ == ‘DebugPipeline|x86′ ">
<StartAction>Program</StartAction>
<StartProgram>C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe</StartProgram>
<StartArguments>Content\content.contentproj /v:normal /t:rebuild /p:Configuration=Debug /p:Platform=x86</StartArguments>
<StartWorkingDirectory>C:\Users\Stephen\Documents\Visual Studio 2008\Projects\XNA Samples\SkinnedModelExtensions\SkinnedModelExtensions\SkinningSample\</StartWorkingDirectory>
</PropertyGroup>
</Project>
Because the PropertyGroup condition corresponds to the "DebugPipeline” configuration, these debugging options will only apply when the active project configuration is DebugPipeline. And because you created a special solution configuration where this project configuration is active, you can now switch between debugging your game code and debugging your content pipeline just by selecting DebugPipeline from a dropdown.
To debug an Xbox 360 game project, you should modify the PropertyGroup condition and the StartArguments as follows:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" ‘$(Configuration)|$(Platform)’ == ‘DebugPipeline|Xbox 360′ ">
<StartAction>Program</StartAction>
<StartProgram>C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe</StartProgram>
<StartArguments>Content\content.contentproj /v:normal /t:rebuild /p:Configuration=Debug "/p:Platform=Xbox 360" /p:XNAContentPipelineTargetPlatform=Xbox360</StartArguments>
<StartWorkingDirectory>C:\Users\Stephen\Documents\Visual Studio 2008\Projects\XNA Samples\SkinnedModelExtensions\SkinnedModelExtensions\SkinningSample\</StartWorkingDirectory>
</PropertyGroup>
</Project>
NOTE: When setting the Platform property in StartArguments, you need to put quotes around the entire expression. This is to preserve the space in the Xbox 360 value, and because you want MSBuild to see “/p:Platform=Xbox 360” as one command-line argument. Unlike the XNAContentPipelineTargetPlatform property, the Platform property requires a space in the Xbox 360 name.
Making Changes
Normally, the VS IDE creates and controls this .user file. In this case, however, you are editing it yourself without the IDE “knowing” about it. For that reason, you need to gently kick the IDE each time you make changes to it. I don’t mean that literally – I just mean close and reopen the solution. When the project is reloaded, the IDE will notice the changes you made to the .user file.
Summing Up
Visual C# Express includes a pretty powerful bunch of tools. Unfortunately for the budget-constrained developer (and cheapskates!), it doesn’t have all the features of Visual Studio. Sometimes, all that’s missing is a little bit of convenience. By taking the time to understand how things work, and applying a bit of elbow grease, you can unlock hidden conveniences that are unavailable to normal users (and lazy bastards who didn’t bother to read this far!).




hi, can you release DebugPipelineCmd.msi for XNA 4.0 && vs 2010
I have already released a different solution for Game Studio 4.0. Please try this template for debugging the XNA Content Pipeline. Thanks.