11

問題: 除外属性で渡された値に基づいて、ItemGroups 配列が正しく作成されません。

このスクリプトを実行すると、いくつかのサンプル ファイルが作成され、Include/Exclude 属性に基づいて TheFiles という配列が作成されます。問題は、Exclude がハードコードされていないか、非常に単純なプロパティである場合に、間違ってしまうことです。

ターゲットの DynamicExcludeList は、次のファイルを誤って選択します:
.\AFolder\test.cs;.\AFolder\test.txt

ターゲットの HardcodedExcludeList は次のファイルを正しく選択します:
.\AFolder\test.txt

どんな助けでも大歓迎です、これは私を夢中にさせています。

(そのmsbuild v4に注意してください)

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Run">

      <Target Name="Run" >
        <CallTarget Targets="CreateSampleFiles" />
        <CallTarget Targets="DynamicExcludeList" />
        <CallTarget Targets="HardcodedExcludeList" />
      </Target>

      <Target Name="CreateSampleFiles" >
        <MakeDir Directories="AFolder" />
        <WriteLinesToFile Lines="Test" File="AFolder\test.cs" Overwrite="true" />
        <WriteLinesToFile Lines="Test" File="AFolder\test.txt" Overwrite="true" />
      </Target>

      <Target Name="DynamicExcludeList" >

        <PropertyGroup>
          <CommonFileExclusion>.\DIRECTORY_NAME_TOKEN\**\*.cs</CommonFileExclusion>
          <FinalExcludes>$(CommonFileExclusion.Replace('DIRECTORY_NAME_TOKEN', 'AFolder'))</FinalExcludes>
        </PropertyGroup>

        <Message Text="FinalExcludes: $(FinalExcludes)" />
        <ItemGroup>
          <TheFiles 
            Include=".\AFolder\**\*;" 
            Exclude="$(FinalExcludes)"
          />
        </ItemGroup>
        <Message Text="TheFiles: @(TheFiles)" />

      </Target>

      <Target Name="HardcodedExcludeList" >

        <PropertyGroup>
          <FinalExcludes>.\AFolder\**\*.cs</FinalExcludes>
        </PropertyGroup>

        <Message Text="FinalExcludes: $(FinalExcludes)" />
        <ItemGroup>
          <TheFilesWithHardcodedExcludes
            Include=".\AFolder\**\*;"
            Exclude="$(FinalExcludes)"
          />
        </ItemGroup>
        <Message Text="TheFilesWithHardcodedExcludes: @(TheFilesWithHardcodedExcludes)" />

      </Target>  
    </Project>

これは出力です。'TheFiles' と 'TheFilesWithHardcodedExcludes' の違いに注意してください。

PS C:\SVN\TrunkDeployment\TestMsBuild> msbuild .\Test.build.xml
Microsoft (R) ビルド エンジン バージョン 4.0.30319.1
[Microsoft .NET Framework バージョン 4.0.30319.1]
Copyright (C) Microsoft Corporation 2007. 無断複写・転載を禁じます。

ビルドは 2010 年 8 月 10 日午後 2:30:42 に開始されました。
ノード 1 のプロジェクト「C:\SVN\TrunkDeployment\TestMsBuild\Test.build.xml」(デフォルト ターゲット)。
動的除外リスト:
  FinalExcludes: .\AFolder\**\*.cs
  ファイル: .\AFolder\test.cs;.\AFolder\test.txt
HardcodedExcludeList:
  FinalExcludes: .\AFolder\**\*.cs
  TheFilesWithHardcodedExcludes: .\AFolder\test.txt
プロジェクト「C:\SVN\TrunkDeployment\TestMsBuild\Test.build.xml」(デフォルト ターゲット) のビルドが完了しました。


ビルドが成功しました。
    0 警告
    0 エラー

経過時間 00:00:00.06

編集

CreateItem を使用するように上記のスクリプトを更新しましたが、除外するアイテムのリストに複数のパスが含まれている場合 (つまり、CommonFileExclusionの値が変更された場合)にはまだ問題があります。

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Run">

      <Target Name="Run" >
        <CallTarget Targets="CreateSampleFiles" />
        <CallTarget Targets="DynamicExcludeList" />
        <CallTarget Targets="HardcodedExcludeList" />
      </Target>

      <Target Name="CreateSampleFiles" >
        <MakeDir Directories="AFolder" />
        <WriteLinesToFile Lines="Test" File="AFolder\test.cs" Overwrite="true" />
        <WriteLinesToFile Lines="Test" File="AFolder\test.txt" Overwrite="true" />
        <WriteLinesToFile Lines="Test" File="AFolder\test.vb" Overwrite="true" />
      </Target>

      <Target Name="DynamicExcludeList" >

        <PropertyGroup>
          <CommonFileExclusion>.\DIRECTORY_NAME_TOKEN\**\*.cs;.\DIRECTORY_NAME_TOKEN\**\*.vb;</CommonFileExclusion>
          <FinalExcludes>$(CommonFileExclusion.Replace('DIRECTORY_NAME_TOKEN', 'AFolder'))</FinalExcludes>
        </PropertyGroup>

        <Message Text="FinalExcludes: $(FinalExcludes)" />
        <CreateItem Include=".\AFolder\**\*;"
                     Exclude="$(FinalExcludes)">
          <Output TaskParameter="Include" ItemName="TheFiles"/>
        </CreateItem>
        <Message Text="TheFiles: @(TheFiles)" />

      </Target>

      <Target Name="HardcodedExcludeList" >

        <PropertyGroup>
          <FinalExcludes>.\AFolder\**\*.cs;.\AFolder\**\*.vb</FinalExcludes>
        </PropertyGroup>

        <Message Text="FinalExcludes: $(FinalExcludes)" />
        <CreateItem Include=".\AFolder\**\*;"
                     Exclude="$(FinalExcludes)">
          <Output TaskParameter="Include" ItemName="TheFilesWithHardcodedExcludes"/>
        </CreateItem>
        <Message Text="TheFilesWithHardcodedExcludes: @(TheFilesWithHardcodedExcludes)" />

      </Target>
    </Project>
4

2 に答える 2

19

わかりました、少し試してみましたが、問題は、複数の値に対して SCALAR 値を表すプロパティを使用しているという事実にあると思います。バッチ処理と変換をお勧めします ( http://scottlaw.knot.org/blog/?p=402およびhttp://msdn.microsoft.com/en-us/library/ms171476.aspxを参照)。たとえば、次のコードが機能しています。

<Target Name="DynamicExcludeList" >
  <ItemGroup>
    <ExtensionsExcluded Include="cs;vb" />
  </ItemGroup>

  <CreateItem Include=".\AFolder\**\*"
          Exclude="@(ExtensionsExcluded->'.\AFolder\**\*.%(identity)')">
    <Output TaskParameter="Include" ItemName="TheFiles"/>
  </CreateItem>
  <Message Text="TheFiles: @(TheFiles)" />
</Target>
于 2010-10-08T15:54:56.857 に答える
2

アイテムを動的に生成する代わりに、ターゲットでタスクをDynamicExcludeList使用します。CreateItemItemGroup

<Target Name="DynamicExcludeList" >

  <PropertyGroup>
    <CommonFileExclusion>.\DIRECTORY_NAME_TOKEN\**\*.cs</CommonFileExclusion>
    <FinalExcludes>$(CommonFileExclusion.Replace('DIRECTORY_NAME_TOKEN', 'AFolder'))</FinalExcludes>
  </PropertyGroup>

  <Message Text="FinalExcludes: $(FinalExcludes)" />

  <CreateItem Include=".\AFolder\**\*;"
              Exclude="$(FinalExcludes)">
    <Output TaskParameter="Include" ItemName="TheFiles"/>
  </CreateItem>

  <Message Text="TheFiles: @(TheFiles)" />
</Target>

理論的にはItemGroupCreateItemは同等ですが、このようなケース (動的な状況) をCreateItem使用する必要がある場合を見てきました。

于 2010-10-08T13:46:18.460 に答える