16

次のmsbuildコードがあります。

  <PropertyGroup>
    <DirA>C:\DirA\</DirA>
    <DirB>C:\DirB\</DirB>
  </PropertyGroup>

  <Target Name="CopyToDirA"
          Condition="Exists('$(DirA)') AND '@(FilesToCopy)' != ''"
          Inputs="@(FilesToCopy)"
          Outputs="@(FilesToCopy -> '$(DirA)%(Filename)%(Extension)')">
    <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DirA)" />
  </Target>

  <Target Name="CopyToDirB"
          Condition="Exists('$(DirB)') AND '@(FilesToCopy)' != ''"
          Inputs="@(FilesToCopy)"
          Outputs="@(FilesToCopy -> '$(DirB)%(Filename)%(Extension)')">
    <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DirB)" />
  </Target>

  <Target Name="CopyFiles" DependsOnTargets="CopyToDirA;CopyToDirB"/>

したがって、ターゲットを呼び出すと、関連するファイルがとにCopyFilesコピーされます。ただし、それらのファイルがまだ存在しておらず、最新のものではない場合に限ります。$(DirA)$(DirB)

ただし、ターゲットCopyToDirAとは、一方がにコピーされ、もう一方が-にCopyToDirBコピーされることを除いて、同じように見えます。それらを最初にで呼び出され、次にで呼び出される1つのターゲットに統合することは可能ですか?$(DirA)$(DirB)$(DirA)$(DirB)

ありがとう。

4

3 に答える 3

14

Dirs を含む ItemGroup を生成し、それに対して % を生成できるはずです。

<ItemGroup>
    <Dirs Include="C:\DirA\;C:\DirB\">
</ItemGroup>
<Target Name="CopyFiles"
    Condition="Exists('%(Dirs)') AND '@(FilesToCopy)' != ''"
    Inputs="@(FilesToCopy)"
    Outputs="@(FilesToCopy -> '%(Dirs)%(Filename)%(Extension)')">
    <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="%(Dirs)" />
</Target>

または、2 つの明示的な呼び出しを行うことができます。

<Target Name="CopyFiles">
    <MsBuild Projects="$(MSBuildProjectFullPath)" Targets="CopyASetOfFiles" Properties="FilesToCopy=@(FilesToCopy);DestDir=$(DirA)" />
    <MsBuild Projects="$(MSBuildProjectFullPath)" Targets="CopyASetOfFiles" Properties="FilesToCopy=@(FilesToCopy);DestDir=$(DirB)" />
</Target>

<Target Name="CopyASetOfFiles"
    Condition="Exists('$(DestDir)') AND '@(FilesToCopy)' != ''"
    Inputs="@(FilesToCopy)"
    Outputs="@(FilesToCopy -> '$(DestDir)%(Filename)%(Extension)')">
    <Copy SourceFiles="@(FilesToCopy)" DestinationFolder="$(DestDir)" />
</Target>

私はどちらの構文もテストしていませんが、後者の方が比較的自信があります。

(答えがあるとすれば、私の机の上のサイード・ハシミの本にあります。

  1. 本を入手する
  2. 退屈する
  3. Sayed はこの投稿を見つけ、素晴らしいテスト済みの回答を思いつきます)
于 2009-08-18T15:35:09.630 に答える
9

誰かがすでに述べたように、答えはバッチ処理です。

ここにいくつかのリンクがあります:

于 2009-08-20T05:07:51.140 に答える
4

はい、MSBuild ではバッチ処理と呼ばれるものが必要です。の

;%(Dirs.Identity)

Outputs で定義すると、Dirs ItemGroup の各アイテムに対してこのタスクが実行されます。

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

<ItemGroup>
    <Dirs Include="C:\DirA" />
    <Dirs Include="C:\DirB" />
</ItemGroup>

<Target Name="CopyFiles"
    Inputs="@(FilesToCopy);@(Dirs)"
    Outputs="@(FilesToCopy -> '%(Dirs.Identity)%(Filename)%(Extension)');%(Dirs.Identity)" >
    <Message Text="%(Dirs.Identity)" />
</Target>

</Project>

出力:

Build started 8/19/2009 10:11:57 PM.
Project "D:\temp\test.proj" on node 0 (default targets).
  C:\DirA
CopyFiles:
  C:\DirB
Done Building Project "D:\temp\test.proj" (default targets).

次の条件で Message タスクを Copy タスクに変更すると、完了です。

Condition="Exists('%(Dirs.Identity)') AND '@(FilesToCopy)' != ''"
于 2009-08-20T02:20:15.630 に答える