【问题标题】:Transforming multiple config files for multiple projects via MsBuildProj file通过 MsBuildProj 文件为多个项目转换多个配置文件
【发布时间】:2014-08-28 03:24:42
【问题描述】:

我正在尝试在基于模式的文件列表上运行多个命令(给定目录的子目录下所有*.config 形式的文件),如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="BuildSolution" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <UsingTask TaskName="TransformXml"
      AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll" />

  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <TransformConfiguration>Release</TransformConfiguration>
    <PublishFolder>$(OutDir)_PublishedWebsites</PublishFolder>
  </PropertyGroup>

  <Target Name="BuildSolution">
    <MSBuild Projects="$(MSBuildProjectDirectory)\SolutionName.sln"
      ContinueOnError="false"
      Properties="PublishProfile=$(TransformConfiguration);DeployOnBuild=true" />
  </Target>

  <ItemGroup>
    <ConfigFiles Include="$(PublishFolder)\**\*.config" />
  </ItemGroup>

  <Target Name="TransformWebConfig" AfterTargets="BuildSolution" 
            Condition="'@(ConfigFiles)'!=''"
            Outputs="%(ConfigFiles.Identity)">

    <PropertyGroup>
      <ConfigFile>%(ConfigFiles.Identity)</ConfigFile>
      <BackupFile>$([System.IO.Path]::ChangeExtension($(ConfigFile),&quot;.Source.config&quot;))</BackupFile>
      <TransformFile>$([System.IO.Path]::ChangeExtension($(ConfigFile),$(TransformConfiguration) + &quot;.Source.config&quot;))</TransformFile>
    </PropertyGroup>

    <Message Text="$(ConfigFile)" />
    <Message Text="$(BackupFile)" />
    <Message Text="$(TransformFile)" />

    <Copy SourceFiles="$(ConfigFile)"
          DestinationFiles="$(BackupFile)" />

    <Exec Command="attrib -r $(ConfigFile)" />

    <TransformXml Source="$(BackupFile)"
                  Transform="$(TransformFile)"
                  Destination="$(ConfigFile)"
                  StackTrace="false" />

  </Target>

</Project>

但是,不执行匹配文件的批处理。

  • 从我添加的输出中,我看到属性$(PublishFolder) 指向正确的目录,但是,@(ConfigFiles) 项为空。

我也尝试手动列出目录名称和配置文件名称,如下所示:

  <ItemGroup>
    <Sites Include="Site1" />
    <Sites Include="Site2" />
  </ItemGroup>
  <ItemGroup>
    <ConfigFiles Include="Web" />
    <ConfigFiles Include="NLog" />
  </ItemGroup>

  <Target Name="TransformWebConfig" AfterTargets="BuildSolution">

    <PropertyGroup>
      <SiteConfigFile>$(PublishFolder)\%(Sites.Identity)\%(ConfigFiles.Identity)</SiteConfigFile>
    </PropertyGroup>

    <Message Text="$(SiteConfigFile)" />

    <Copy SourceFiles="$(SiteConfigFile).config"
          DestinationFiles="$(SiteConfigFile).Source.config"/>

    <Exec Command="attrib -r $(SiteConfigFile).config" />

    <TransformXml Source="$(SiteConfigFile).Source.config"
                  Transform="$(SiteConfigFile).$(TransformConfiguration).config"
                  Destination="$(SiteConfigFile).config"
                  StackTrace="false" />
  </Target>

但是,在这种情况下,转换仅应用于一个站点中的一个文件。


知道该怎么做才能让它工作吗?


我经历过的类似问题和 MSDN 参考资料:

MSBUild: Copy files with a name based on the original (following a pattern)

MSBuild multiple outputpath

How to invoke the same msbuild target twice with different parameters from within msbuild project file itself

msbuild array iteration

http://msdn.microsoft.com/en-us/library/ms171454.aspx


编辑:

在创建文件后移动任务下的 ItemGroup 可以读取文件列表,但是,现在只转换列表中的第一个文件:

<ItemGroup>
  <ConfigFiles Include="$(PublishFolder)\**\Web.config;$(PublishFolder)\**\NLog.config"
               Exclude="$(PublishFolder)\**\Packages.config;$(PublishFolder)\**\*.*.config;$(PublishFolder)\**\bin\*.config" />
</ItemGroup>

<PropertyGroup>
  <ConfigFile>%(ConfigFiles.Identity)</ConfigFile>
  <BackupFile>$([System.IO.Path]::ChangeExtension($(ConfigFile),&quot;.Source.config&quot;))</BackupFile>
  <TransformFilePrefix>$([System.String]::Concat($(TransformConfiguration), &quot;.config&quot;))</TransformFilePrefix>
  <TransformFile>$([System.IO.Path]::ChangeExtension($(ConfigFile), $(TransformFilePrefix)))</TransformFile>
</PropertyGroup>

<Message Text="$(PublishFolder)" />
<Message Text="@(ConfigFiles)" />
<Message Text="$(ConfigFile)" />
<Message Text="$(BackupFile)" />
<Message Text="$(TransformFile)" />

<Copy SourceFiles="$(ConfigFile)"
      DestinationFiles="$(BackupFile)" />

<Exec Command="attrib -r $(ConfigFile)" />

<TransformXml Source="$(BackupFile)"
              Transform="$(TransformFile)"
              Destination="$(ConfigFile)"
              StackTrace="false" />

【问题讨论】:

  • PublishFolder 设置为什么。我尝试了示例一,当我将 PublishFolder 设置为指向一些配置文件时,我看到 TransformWebConfig 被多次调用并且 ConfigFile 属性是正确的。 TransformFile 属性未正确构建。
  • @BrianWalker $(OutDir)_PublishedWebsites 其中 $(OutDir) 是构建机器放置所有构建二进制文件的位置(并以反斜杠结尾)。
  • @BrianWalker 看起来文件夹是在解决方案构建后才创建的,但是在此之前它到达了ItemGroup,因此没有找到文件。

标签: msbuild msbuild-target msbuild-itemgroup msbuild-batching


【解决方案1】:

找到解决方案:

为创建项目组创建一个目标:

  <Target Name="ListWebConfigs" AfterTargets="BuildSolution">

    <ItemGroup>
      <ConfigFiles Include="$(PublishFolder)\**\Web.config;$(PublishFolder)\**\NLog.config"
                   Exclude="$(PublishFolder)\**\Packages.config;$(PublishFolder)\**\*.*.config;$(PublishFolder)\**\bin\*.config" />
    </ItemGroup>

    <Message Text="$(PublishFolder)" />
    <Message Text="@(ConfigFiles)" />

  </Target>

然后是实际转换的另一个:

  <!-- \x to prevent MSBuild from skipping "because all output files are up-to-date" -->
  <Target Name="TransformWebConfig" AfterTargets="ListWebConfigs" Inputs="@(ConfigFiles)" Outputs="%(ConfigFiles.Identity)\x">

    <PropertyGroup>
      <ConfigFile>%(ConfigFiles.Identity)</ConfigFile>
      <BackupFile>$([System.IO.Path]::ChangeExtension($(ConfigFile),&quot;.Source.config&quot;))</BackupFile>
      <TransformFilePrefix>$([System.String]::Concat($(TransformConfiguration), &quot;.config&quot;))</TransformFilePrefix>
      <TransformFile>$([System.IO.Path]::ChangeExtension($(ConfigFile), $(TransformFilePrefix)))</TransformFile>
    </PropertyGroup>

    <Message Text="$(PublishFolder)" />
    <Message Text="@(ConfigFiles)" />

    <Message Text="$(ConfigFile)" />
    <Message Text="$(BackupFile)" />
    <Message Text="$(TransformFile)" />

    <Copy SourceFiles="$(ConfigFile)" DestinationFiles="$(BackupFile)" />

    <Exec Command="attrib -r $(ConfigFile)" />

    <TransformXml Source="$(BackupFile)"
                  Transform="$(TransformFile)"
                  Destination="$(ConfigFile)"
                  StackTrace="false" />

  </Target>

【讨论】:

  • 你应该把它标记为答案,这样问题就很明显了。
猜你喜欢
  • 2016-10-18
  • 1970-01-01
  • 2021-05-13
  • 2016-10-04
  • 2012-02-17
  • 2017-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多