在项目扩展中使用Msbuild变量

6

我目前有一个与web.api项目相关的解决方案,我想将其部署到本地IIS中的不同虚拟目录中。目前,在api的.csproj文件中我正在执行以下操作:

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

这些变量被广泛地用于web.config转换、复制到不同位置等操作中,通过像$(CustomerName)这样的引用来调用它们。
唯一不起作用的地方是虚拟目录的定义,即我想将构建配置连接到下面的IISUrl,你可以硬编码它:
<ProjectExtensions>
  <VisualStudio>
    <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
      <WebProjectProperties>
        ...
        <IISUrl>http://localhost/api/something</IISUrl>
        ...
      </WebProjectProperties>
    </FlavorProperties>
  </VisualStudio>
</ProjectExtensions>

<IISUrl>http://localhost/api/$(CustomerName)</IISUrl> 替换这个并不起作用。有什么想法吗?

澄清一下:Leo Lui-MSFT的答案已经回答了为什么它不起作用。我对如何使其工作感兴趣,即如何根据构建配置配置IISUrl。 - EluciusFTW
听起来和我过去遇到的问题很相似。看看这个答案提供的解决方案。思路是使用DefineConstants - l33t
2个回答

2
将其替换为http://localhost/api/$(CustomerName)并不起作用。有什么想法吗?
这是因为ProjectExtensions元素内的任何内容都将被MSBuild忽略。 您可以从此文档ProjectExtensions Element (MSBuild)中获取详细信息:

允许MSBuild项目文件包含非MSBuild信息。 ProjectExtensions元素内的任何内容都将被MSBuild忽略

这就是为什么Msbuild变量在Project Extensions中不起作用的原因。
希望这能帮到您。

谢谢您提供的信息。然而,您并没有提出如何使其正常工作的解决方案,即如何动态设置虚拟目录。 - EluciusFTW
@EluciusFTW,哦,抱歉,我看到你的问题是为什么它不起作用,而不是如何解决它。我以为你不关心解决方案,所以我没有提供解决方案。那么在<ProjectExtensions>上使用条件,例如<ProjectExtensions Condition="'$(Configuration)' == 'CustomerOne.Debug'">,然后在IISUrl中设置静态路径,并添加另一个带有另一个静态路径的条件。如果对你有效,你可以测试一下。 - Leo Liu
再次感谢,我一定会尝试的。但是这并不理想,因为我有大约20个构建配置。 - EluciusFTW
@Leu Lui-MSFT 很遗憾,它无法工作:“<ProjectExtensions>元素中的属性条件未被识别”。 - EluciusFTW
@EluciusFTW,是的,我刚刚测试了一下,得到了相同的结果。因此,Msbuild变量不能在ProjectExtensions元素及其内部使用。我将继续调查是否有任何解决方案。如果我有任何更新,我会让你知道。 - Leo Liu

1
你可以更新底层的项目文件。在你的项目文件中,像这样的一个目标就可以实现它。
  <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>

然而,它确实有副作用。更改底层项目文件意味着Visual Studio决定重新加载项目。
要使用它,您不能直接进入Debug。相反,先构建,重新加载项目,然后进入debug。如果直接进入Debug(进行编译),它将使用旧的url。

由于我的悬赏即将结束,而这是唯一的真正解决方案,我将把它授予这个答案。尽管它看起来像一个绝对的用例,也许没有比通过像这样的脚本编辑.csproj更好的解决方案 :/ - EluciusFTW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接