我正在使用Visual Studio的链接文件概念共享文件。因此,我需要使用 MSBuild 在每个生成时复制链接的内容文件。
为此,我在项目标签内的 .vbproj 文件中编写了此代码。
<Target Name="CopyLinkedContentFiles" BeforeTargets="Build">
<Copy SourceFiles="%(Content.Identity)" DestinationFiles=(Content.Identity)"
SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true"
Condition="'@(AllFiles)' != ''" />
</Target>
它工作正常。所有链接的文件都被复制了。
但是在这里我需要添加某些约束,例如"不复制带有.vb的文件 扩展">。如何实现呢?
我试过这段代码
<Target Name="CopyLinkedContentFiles" BeforeTargets="Build">
<CreateItem Include="%(Content.Identity)">
<Output ItemName="AllFiles" TaskParameter="Include" />
</CreateItem>
<ItemGroup>
<AllFiles Remove="@(AllFiles)" Condition="'%(Extension)' == '.vb'"/>
</ItemGroup>
<Copy SourceFiles="@(AllFiles)" DestinationFiles="@(AllFiles)"
SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true"
Condition="'@(AllFiles)' != ''" />
</Target>
它不起作用。未复制任何文件。请提出任何想法。
删除项目的方式应该有效。但是复制任务的源文件和目标文件在您显示的代码中是相同的,因此这显然是一个空操作。请改用这样的东西:
<Copy SourceFiles="@(AllFiles)" DestinationFolder="$(MyDestDir)" />
或者,如果目标文件名取决于输入文件名:
<Target Name="MyCopy">
<ItemGroup>
<AllFiles Include="%(Content.Identity)" Condition="'%(Extension)' != '.vb'">
<!-- Add metadata which will be used as destination directory:
strip point from extension and convert to uppercase -->
<Ext>$([System.String]::Copy('%(Extension)').Replace('.','').ToUpper())</Ext>
</AllFiles>
</ItemGroup>
<Copy SourceFiles="@(AllFiles)"
DestinationFiles="@(AllFiles->'$(OutDir)%(Ext)%(Filename)%(Extension)')" />
</Target>
您不需要检查 AllFiles 是否为空:如果是,则不会复制任何内容。
如您所见,我使用了一种更简单、更短的方式来实现项目的过滤:使用 Remove 时,您始终需要两个语句,只需在扩展上使用 Condition 即可,您只需要一个。为了完整起见,这里有 4 种不同的方式,包括您的,但第一种是最短的(另请注意,您不需要 CreateItem,只需使用一个 Item:更少的输入,相同的效果(:
<ItemGroup>
<Content Include="a.foo;b.foo;a.vb;b.vb"/> <!-- sample items -->
</ItemGroup>
<Target Name="FilterExamples">
<ItemGroup>
<AllFilesUsingCondition Include="%(Content.Identity)" Condition="'%(Extension)' != '.vb'"/>
<VbFiles Include="%(Content.Identity)" Condition="'%(Extension)' == '.vb'"/>
<AllFilesUsingExclude Include="%(Content.Identity)" Exclude="@(VbFiles)"/>
<AllFilesUsingRemove Include="%(Content.Identity)"/>
<AllFilesUsingRemove Remove="@(VbFiles)"/>
<AllFilesUsingRemoveCondition Include="%(Content.Identity)"/>
<AllFilesUsingRemoveCondition Remove="@(AllFilesUsingRemoveCondition)" Condition="'%(Extension)' == '.vb'"/>
</ItemGroup>
<Message Text="AllFilesUsingCondition=@(AllFilesUsingCondition)" />
<Message Text="AllFilesUsingExclude=@(AllFilesUsingExclude)" />
<Message Text="AllFilesUsingRemove=@(AllFilesUsingRemove)" />
<Message Text="AllFilesUsingRemoveCondition=@(AllFilesUsingRemoveCondition)" />
</Target>
输出:
AllFilesUsingCondition=a.foo;b.foo
AllFilesUsingExclude=a.foo;b.foo
AllFilesUsingRemove=a.foo;b.foo
AllFilesUsingRemoveCondition=a.foo;b.foo