Using Msbuild variables in Project Extensions

Viewed 704

I currently have a solution with a web.api project that I want to deploy to different virtual directories in my local IIS. Currently I am doing the following in the .csproj of the api:

<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)' == 'CustomerOne.Debug'">
    <CustomerName>CustomerOne</CustomerName>
    ....
</PropertyGroup>
...

These variables are used extenisvely further on for web.config transforms, copying to different locations, etc., by referencing them like $(CustomerName).

The only place where it does not work is in the definition of the virtual directory, i.e., I'd like to connect the build configuration to the IISUrl below, which you can hardcode:

<ProjectExtensions>
  <VisualStudio>
    <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
      <WebProjectProperties>
        ...
        <IISUrl>http://localhost/api/something</IISUrl>
        ...
      </WebProjectProperties>
    </FlavorProperties>
  </VisualStudio>
</ProjectExtensions>

Replacing this by <IISUrl>http://localhost/api/$(CustomerName)</IISUrl> does not work. Ideas?

2 Answers

Replacing this by http://localhost/api/$(CustomerName) does not work. Ideas?

That because Anything inside of a ProjectExtensions element will be ignored by MSBuild.

You can get the detailed info from this document ProjectExtensions Element (MSBuild):

Allows MSBuild project files to contain non-MSBuild information. Anything inside of a ProjectExtensions element will be ignored by MSBuild.

That is the reason why the Msbuild variables not work in Project Extensions.

Hope this helps.

You could update the underlying project file. A Target like this in your project file would do it.

  <Target Name="AfterBuild">
    <PropertyGroup>
      <NewUrl>http://localhost/api/$(CustomerName)</NewUrl>
    </PropertyGroup>
    <Message Text="Updating IISUrl: $(NewUrl) in $(MSBuildProjectFile)" />
    <XmlPeek Namespaces="&lt;Namespace Prefix='msb' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/&gt;" XmlInputPath="$(MSBuildProjectFile)" Query="/msb:Project/msb:ProjectExtensions/msb:VisualStudio/msb:FlavorProperties/msb:WebProjectProperties/msb:IISUrl/text()">
      <Output TaskParameter="Result" ItemName="Peeked" />
    </XmlPeek>
    <Message Text="Current Url: @(Peeked)" />
    <!-- Only update the IISUrl if its changed -->
    <XmlPoke Condition=" '@(Peeked)'!='$(NewUrl)' " XmlInputPath="$(MSBuildProjectFile)" Namespaces="&lt;Namespace Prefix='msb' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/&gt;" Query="/msb:Project/msb:ProjectExtensions/msb:VisualStudio/msb:FlavorProperties/msb:WebProjectProperties/msb:IISUrl" Value="$(NewUrl)" />
  </Target>

However it does have side affects. Changing the underlying project file means Visual Studio decides it should reload the project.

To use it you cannot go directly into Debug. Instead build, reload the project and then go into debug. If you go directly into Debug (with a compile) it will use the old url.

Related