3

ItemGroup特定の名前のファイルを除外しながら(拡張子に関係なく)、特定のディレクトリ内のすべてのファイルから構築しようとするスクリプトがあります。

除外するファイルのリストには、最初はファイル拡張子が含まれています。私はCommunity Tasksを使用RegexReplaceして、拡張子をアスタリスクに置き換えています。次に、このリストをアイテムのExclude属性で使用します。リストが正しいように見えても、何らかの理由でファイルが適切に除外されません。

原因を見つけるために、2つのタスクを持つテストスクリプト(以下)を作成しました。最初のスクリプトは、2つの異なる方法でファイルパターンのリストを使用して2つのプロパティを初期化します。2番目のタスクは、属性でこれらのプロパティの両方を使用した結果のプロパティとファイルの両方を出力しExcludeます。

プロパティの値は同じように見えますが、結果のグループは異なります。これはどのように可能ですか?

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
         DefaultTargets="Init;Test" ToolsVersion="3.5">
  <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>

  <Target Name="Init">
    <ItemGroup>
      <OriginalFilenames Include="TestDir\SampleProj.exe"/>
      <OriginalFilenames Include="TestDir\SampleLib1.dll"/>
    </ItemGroup>
    <RegexReplace Input="@(OriginalFilenames)" Expression="\.\w+$" Replacement=".*">
      <Output TaskParameter="Output" ItemName="PatternedFilenames"/>
    </RegexReplace>
    <PropertyGroup>
      <ExcludeFilesA>TestDir\SampleProj.*;TestDir\SampleLib1.*</ExcludeFilesA>
      <ExcludeFilesB>@(PatternedFilenames)</ExcludeFilesB>
    </PropertyGroup>
  </Target>

  <Target Name="Test">
    <Message Text='ExcludeFilesA: $(ExcludeFilesA)' />
    <Message Text='ExcludeFilesB: $(ExcludeFilesB)' />
    <ItemGroup>
      <AllFiles Include="TestDir\**"/>
      <RemainingFilesA Include="TestDir\**" Exclude="$(ExcludeFilesA)"/>
      <RemainingFilesB Include="TestDir\**" Exclude="$(ExcludeFilesB)"/>
    </ItemGroup>
    <Message Text="&#xA;**AllFiles**&#xA;@(AllFiles, '&#xA;')" />
    <Message Text="&#xA;**PatternedFilenames**&#xA;@(PatternedFilenames, '&#xA;')" />
    <Message Text="&#xA;**RemainingFilesA**&#xA;@(RemainingFilesA, '&#xA;')" />
    <Message Text="&#xA;**RemainingFilesB**&#xA;@(RemainingFilesB, '&#xA;')" />
  </Target>

</Project>

出力(わかりやすくするために多少再フォーマット):

ExcludeFilesA: TestDir\SampleProj.*;TestDir\SampleLib1.*
ExcludeFilesB: TestDir\SampleProj.*;TestDir\SampleLib1.*

AllFiles:
  TestDir\SampleLib1.dll
  TestDir\SampleLib1.pdb
  TestDir\SampleLib2.dll
  TestDir\SampleLib2.pdb
  TestDir\SampleProj.exe
  TestDir\SampleProj.pdb

PatternedFilenames:
  TestDir\SampleProj.*
  TestDir\SampleLib1.*

RemainingFilesA:
  TestDir\SampleLib2.dll
  TestDir\SampleLib2.pdb

RemainingFilesB:
  TestDir\SampleLib1.dll
  TestDir\SampleLib1.pdb
  TestDir\SampleLib2.dll
  TestDir\SampleLib2.pdb
  TestDir\SampleProj.exe
  TestDir\SampleProj.pdb

両方ExcludeFilesAを観察し、ExcludeFilesB同じように見えますが、結果のグループはRemainingFilesA異なりRemainingFilesBます。

RemainingFilesA最終的には、同じ方法で生成されたパターンを使用してリストを取得したいと思いExcludeFilesBます。方法を提案できますか、それとも私のアプローチを完全に再考する必要がありますか?

4

2 に答える 2

2

これの本当の原因は、カスタムタスクが例外をスローしたときに誤って明らかになりました。

の実際の値は、ExcludeFilesA予想TestDir\SampleProj.*;TestDir\SampleLib1.*どおりです。ただし、の実際の値はExcludeFilesBですTestDir\SampleProj.%2a;TestDir\SampleLib1.%2a

おそらくMessage、使用する前に文字列をエスケープ解除しますが、使用IncludeExcludeないでください。これは、文字列が同じように見えるが、動作が異なる理由を説明します。

ちなみに、実行順序はこれとは関係がないようです。(徹底的な実験を経て)すべてがこのスクリプトに表示される順序で正確に実行および評価されることは間違いありません。

于 2009-12-20T15:36:51.687 に答える
0

ItemGroupsは、ターゲットを実行する前に評価する必要があり、PatternedFilenamesItemGroupはそのターゲットコンテナ内にオンザフライで作成されます。CreateItemタスクを使用してこれを回避できます。これによりPatternedFilenames、実行全体でスコープが確保されます。

<RegexReplace Input="@(OriginalFilenames)" Expression="\.\w+$" Replacement=".*">
  <Output TaskParameter="Output" ItemName="PatternedFilenames_tmp"/>
</RegexReplace>
<CreateItem Include="@(PatternedFilenames_tmp)">
  <Output TaskParameter="Include" ItemName="PatternedFilenames"/>
</CreateItem>
于 2009-12-19T21:27:10.760 に答える