Mark Needham

Thoughts on Software Development

msbuild – Use OutputPath instead of OutDir

with 9 comments

We’ve been using msbuild to build our project files on my current project and a colleague and I noticed some strange behaviour when trying to set the directory that the output should be built to.

The problem was whenever we tried to set the output directory (using OutDir) to somewhere where there was a space in the directory name it would just fail catastrophically. We spent ages searching for the command line documentation before finding it here.

According to this though:

“OutputPath: This property is typically specified in the project file and resembles OutDir. OutputPath has been deprecated and OutDir should be used instead whenever possible. ”

We decided to try changing OutDir to OutputPath and it started working again! The code is simple, but for those wondering:

1
2
3
4
<exec program="\path\to\msbuild35">
  <arg value="${projectfile}" />
  <arg value="/p:OutputPath=${build.dir}\${project.name}\" />
</exec>

I can’t decide whether the documentation is just wrong or if it’s now a convention that you can’t have spaces in your build output path. Surely the former?

Be Sociable, Share!

Written by Mark Needham

August 14th, 2008 at 7:54 pm

Posted in Build

Tagged with ,

  • Mark,

    This colleague of yours sounds like a smart guy???

  • He’s alright 😀

  • Without giving it a huge amount of thought, or testing (I don’t have a project to test with at the moment), if you have a space in the name, you’d have to surround the name with quotes. The problem you’re probably facing with the errors (you don’t show us what they are) is that you’re feeding it a space to the command, so msbuild sees this:

    /p:OutputPath=c:\some path

    msbuild is going to see that as 2 arguments… Have you tried doing:

  • Johannes Rudolph

    Hi,

    you actually can use OutDir on a path containing spaces. All you need to do is wrap the path in quotes and suffix it with an extra backslash (\)

    msbuild foo.sln /p:OutDir=”C:\bar\bar x\\”

  • g

    Johannes Rudolph — Thanks for the tip!

    I was going mad trying to resolve an error ‘illegal characters in path’ when using the msbuild task in nantcontrib. But there were no illegal characters (or spaces). Adding an extra backslash to the end did the trick though!

  • spooner

    The only time I’ve automated msbuild was from CruiseControl.NET and we ran into the same issue.

    How we resolved it was to replace ” ” with %20, which sorted it out. Not sure if this a CruiseControl issue or msbuild. Have you also tried putting the path in a string i.e. /p:OutDir=”c:\Output Folder”?

  • Keith Patrick

    I also noticed a quirk with OutDir where my continuous integration was failing due to it using an absolute path on the server (but not on the workstation). Changing it to OutputPath went back to relative, and things are working correctly now, but it is kind of strange and seems to be counter to the documentation, which says it is a relative path.

  • Peter

    Johannes, thank you from the future! I took your horribly accurate workaround with OutDir and put some PowerShell logic to encapsulate all the horrible-ness.

    Note this isn’t a perfect MSBuild helper function, but then again, what is.

    Also if you’re calling this from PSake, then wrap the final “& msbuild” line in an Exec { } block, which will help you with error-handling.

    I should probably clean it up and blog this:

    $msbuildPath = ‘C:windowsMicrosoft.NE
    TFrameworkv4.0.30319msbuild.exe’
    function Run-MSBuild($project, $targets, $configuration, $outdir) {
      if (-not ($outdir.EndsWith(“”))) {
        $outdir += ” #MSBuild requires OutDir end with a trailing slash #awesome
      }
     
      if ($outdir.Contains(” “)) {
        $outdir=”””$($outdir)””” #read comment from Johannes Rudolph here : http://www.markhneedham.com/blog/2008/08/14/msbuild-use-outputpath-instead-of-outdir/
      }
     
      & $msBuildPath “””$project”” /t:$($targets) /p:Configuration=$configuration /p:OutDir=$outdir”
    }

  • James

    and 5 years later you get the reason for the double slash.
    The argument parser allows you to put double quotes in the property value (/p:= creates msbuild properties) but if the value is quoted because it contains spaces, then the double quotes in the value must be escaped. The double slash says that it is a slash, not an escaped double quote. And the reason the build can’t fix it itself is because properties assigned on the command line cannot be overridden inside the build.