title: When does MSBuild set the $(ProjectName) property?
body: <p>I'm fairly new to MSBuild, and I've done some customization on a WPF project file that I'm building both in Visual&nbsp;Studio&nbsp;2010 and TFS&nbsp;2010. I've customized the output path as follows:</p>
  
  <pre><code>&lt;OutputPath Condition=" '$(TeamBuildOutDir)' == '' "&gt;$(SolutionDir)build\binaries\$(ProjectName)\$(Configuration)\$(Platform)&lt;/OutputPath&gt;
  &lt;OutputPath Condition=" '$(TeamBuildOutDir)' != '' "&gt;$(TeamBuildOutDir)binaries\$(ProjectName)\$(Configuration)\$(Platform)&lt;/OutputPath&gt;
  </code></pre>
  
  <p>This allows me to build to a centralized binaries directory when building on the desktop, and allows TFS to find the binaries when CI builds are running.</p>
  
  <p>However, it seems that in both cases, the $(ProjectDir) property is evaluating to '' at build time, which creates strange results. Doing some debugging, it appears as if $(ProjectName) is set by the time BeforeBuild executes, but that my OutputPath property is evaluating it prior to that point.</p>
  
  <pre><code>&lt;ProjectNameUsedTooEarly Condition=" '$(ProjectName)' == '' "&gt;true&lt;/ProjectNameUsedTooEarly&gt;
  </code></pre>
  
  <p>The preceding property is in the same property group as my OutputPath property. In the BeforeBuild target, $(ProjectNameUsedTooEarly) evaluates to true, but $(ProjectName) evaluates to the project name as normal by that point.</p>
  
  <p>What can I do to ensure that $(ProjectName) has got a value when I use it?</p>
  
  <p>I just used Attrice's MSBuild Sidekick to debug through my build file, and in the very first target available for breakpoint (_CheckForInvalidConfigurationAndPlatform) all the properties seem to be set already. ProjectName is already set correctly, but my OutputPath property has already been set using the blank value of ProjectName.</p>