将文件复制到Web包目录后应用TransformXml

时间:2013-05-11 04:19:16

标签: .net visual-studio msbuild publish

我已将asp.net 4项目更改为应用自定义转换:

<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  ...
  <None Include="Configuration\System.Debug.xml">
    <DependentUpon>System.xml</DependentUpon>
  </None>
  <Content Include="Configuration\System.xml">
    <TransformOnBuild>true</TransformOnBuild>
  </Content>
  ...
  <Import Project="$(SolutionDir)\MsBuild\TransformFiles.targets" />
</Project>

转换逻辑在单独的文件中定义:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>
  <ItemDefinitionGroup>
    <!-- Set the default value to false here -->
    <None>
      <TransformOnBuild>false</TransformOnBuild>
    </None>   
    <Content>
      <TransformOnBuild>false</TransformOnBuild>
    </Content>   
    <Resource>
      <TransformOnBuild>false</TransformOnBuild>
    </Resource>
    <EmbeddedResource>
      <TransformOnBuild>false</TransformOnBuild>
    </EmbeddedResource>

    <_FilesToTransform>
      <IsAppConfig>false</IsAppConfig>
    </_FilesToTransform>
  </ItemDefinitionGroup>

  <PropertyGroup>
    <TransformAllFilesDependsOn>
      DiscoverFilesToTransform;
    </TransformAllFilesDependsOn>
  </PropertyGroup>

  <Target Name="TransformAllFiles" DependsOnTargets="$(TransformAllFilesDependsOn)" AfterTargets="Build;_CopyAppConfigFile">
    <!-- Now we have the item list _FilesToTransformNotAppConfig and _AppConfigToTransform item lists -->
    <!-- Transform the app.config file -->   

    <ItemGroup>
      <_AppConfigTarget Include="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')" />
    </ItemGroup>

    <PropertyGroup>
      <_AppConfigDest>@(_AppConfigTarget->'%(FullPath)')</_AppConfigDest>
      <_PkgPathFull>$([System.IO.Path]::GetFullPath($(WPPAllFilesInSingleFolder)))</_PkgPathFull>
    </PropertyGroup>

    <MakeDir Directories="@(_FilesToTransformNotAppConfig->'$(_PkgPathFull)\%(RelativeDir)')"
         Condition="Exists('%(RootDir)%(Directory)%(Filename).$(Configuration)%(Extension)')"/>

    <TransformXml Source="@(_AppConfigToTransform->'%(FullPath)')"
              Transform="%(RelativeDir)%(Filename).$(Configuration)%(Extension)"
              Destination="$(_AppConfigDest)"
              Condition=" Exists('%(RelativeDir)%(Filename).$(Configuration)%(Extension)') " />


    <TransformXml Source="@(_FilesToTransformNotAppConfig->'%(FullPath)')"
              Transform="%(RootDir)%(Directory)%(Filename).$(Configuration)%(Extension)"
              Destination="$(_PkgPathFull)\%(RelativeDir)%(Filename)%(Extension)"
              Condition=" Exists('%(RootDir)%(Directory)%(Filename).$(Configuration)%(Extension)') "/>
  </Target>

  <Target Name="DiscoverFilesToTransform">
    <ItemGroup>
      <_FilesToTransform Include="@(None);@(Content);@(Resource);@(EmbeddedResource)"
                     Condition=" '%(TransformOnBuild)' == 'true' "/>
    </ItemGroup>   

    <PropertyGroup>
      <_AppConfigFullPath>@(AppConfigWithTargetPath->'%(RootDir)%(Directory)%(Filename)%(Extension)')</_AppConfigFullPath>
    </PropertyGroup>

    <!-- Now look to see if any of these are the app.config file -->
    <ItemGroup>
      <_FilesToTransform Condition=" '%(FullPath)'=='$(_AppConfigFullPath)' ">
        <IsAppConfig>true</IsAppConfig>
      </_FilesToTransform>
    </ItemGroup>

    <ItemGroup>
      <_FilesToTransformNotAppConfig Include="@(_FilesToTransform)"
                                 Condition=" '%(IsAppConfig)'!='true'"/>

      <_AppConfigToTransform  Include="@(_FilesToTransform)"
                          Condition=" '%(IsAppConfig)'=='true'"/>
    </ItemGroup>
  </Target>
</Project>

问题是在发布过程之前应用转换,因此转换后的文件会被源覆盖:

1>------ Build started: Project: TestProject, Configuration: Debug Any CPU ------
...
1>TransformAllFiles:
1>  Transforming Source File: C:\sorces\TestProject\Configuration\System.xml
1>    Applying Transform File: C:\sorces\TestProject\Configuration\System.Debug.xml
1>    Output File: C:\sorces\TestProject\obj\Debug\Package\PackageTmp\Configuration\System.xml
1>  Transformation succeeded
1>
1>Build succeeded.
1>
1>Time Elapsed 00:00:01.42
2>------ Publish started: Project: TestProject, Configuration: Debug Any CPU ------
...
2>Copying Configuration\System.xml to obj\Debug\Package\PackageTmp\Configuration\System.xml.
...

在将文件复制到包目录后,是否可以应用转换? 我尝试了不同的建议,但没有运气。

更新1: 一个有趣的事情:在发布过程中根本不分析文件TransformFiles.targets。 我在档案中犯了错误:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Message-bla-bla Importance="high" Text="test001" />
</Project>

所以构建失败:

1>------ Build started: Project: TestProject, Configuration: Debug Any CPU ------
1>Build started 11.05.2013 10:18:56.
1>C:\sources\TestProject\MsBuild\TransformFiles.targets(3,3): error MSB4067: The element <Message-bla-bla> beneath element <Project> is unrecognized.
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

但发布成功(!!!):

1>------ Publish started: Project: TestProject, Configuration: Debug Any CPU ------
...
1>Publish is successfully deployed.
1>
========== Build: 0 succeeded, 0 failed, 2 up-to-date, 0 skipped ==========
========== Publish: 1 succeeded, 0 failed, 0 skipped ==========

1 个答案:

答案 0 :(得分:0)

有两个修复:

1更改AfterTargets属性:

<Target Name="TransformAllFiles" DependsOnTargets="$(TransformAllFilesDependsOn)" AfterTargets="CopyAllFilesToSingleFolderForMsdeploy;">

2重新启动Visual Studio(!)。