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">
<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:
- All my *.csproj files are in the Subversion repository; *.csproj.user ones are not.
- 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.