views:

343

answers:

0

I have a C# project in Visual Studion 2008, for which I'd like to specify a custom program to run on a debugging session. When you set it in Project Properties -> Debug -> Start Action, VS creates a *.csproj.user file with a content like the following:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
        <StartAction>Program</StartAction>
        <StartProgram>C:\...\Rhino.ServiceBus.Host.exe</StartProgram>
        <StartArguments>/Name:Tester /Action:Debug /asm:"C:\...\SomeFile.exe"</StartArguments>
  </PropertyGroup>
</Project>

There's nothing but MSBuild property definitions in this file, so I moved them into my main *.csproj file for two reasons:

  1. All my *.csproj files are in the Subversion repository; *.csproj.user ones are not.
  2. I wanted to get rid of absolute paths and replace them with property references.

Now the last lines of my project file look like that:

  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <StartAction>Program</StartAction>
    <StartProgram>$(SolutionDir)\Libs\Rhino.ServiceBus.Host.exe</StartProgram>
    <StartArguments>/Name:Tester /Action:Debug /asm:"$(TargetPath)"</StartArguments>
  </PropertyGroup>

$(TargetPath) is a property defined in Microsoft.Common.Targets:

<ItemGroup>
    <!-- Create the output path as an item so that we can use %(FullPath) on it. -->
    <_OutputPathItem Include="$(OutDir)"/>
</ItemGroup>
<PropertyGroup>
    <!-- Example, c:\MyProjects\MyProject\bin\debug\MyAssembly.dll -->
    <TargetPath Condition=" '$(TargetPath)' == '' ">@(_OutputPathItem->'%(FullPath)$(TargetFileName)')</TargetPath>
</PropertyGroup>

And here's where the things go wrong. For some reason, msbuild transform in $(TargetPath) won't expand, and instead of the full path to my binary, I end up with "@(_OutputPathItem->'%(FullPath)MyBinaryFileName.exe')" (note that the property reference is being expanded). When I try to run or debug my project, VS passes this half-baked value as a command-line argument, and, sure enough, nothing works as expected.

What's more interesting is that when I use the value of StartArguments property in any other way, for example, in Text parameter of built-in Message task, items reference is expanded properly, and the full path to my executable is printed to the console.

As a temporary workaround, I've replaced $(TargetPath) to $(ProjectDir)$(OutDir)$(TargetFileName). But I still would like to know what's the problem with items reference here, so as to ensure I don't run into it in the future.