将包含通配符的MSBuild属性展开为Items

时间:2012-01-29 18:38:21

标签: c# .net msbuild

我正在尝试编写MSBuild脚本,该脚本将在某个预定义目录(F:\ Files)中的任意文件(在命令行上指定为属性)执行某些操作(例如,打印其路径)。

给出以下目录结构

F:\Files\TextFile.txt
F:\Files\Subdir1\ImageFile.bmp
F:\Files\Subdir1\SubSubdir\ImageFile2.bmp
F:\Files\Subdir1\SubSubdir\TextFile2.txt

和MSBuild脚本

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="PrintNames" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <TargetDir>F:\Files</TargetDir>
    </PropertyGroup>

    <ItemGroup>
        <Files Include="$(TargetDir)\$(InputFiles)"/>
    </ItemGroup>

    <Target Name="PrintNames">
        <Message Text="Files: @(Files, ', ')" />
    </Target>
</Project>

运行将InputFiles设置为“** \ * .bmp; ** \ * .txt”的脚本仅适用于bmp文件。 Txt文件取自当前工作目录,而不是“F:\ Files”

1 个答案:

答案 0 :(得分:7)

您必须解决两个问题:

  1. $(InputFiles)被指定为标量属性,但您想将其解释为数组
  2. $(InputFiles)包含要在中对$(InputFiles)中的模式列表进行转换后扩展的通配符。
  3. 很容易分别解决两个问题中的任何一个,但两者的结合实际上是棘手的。我有一个可能的解决方案,它可以工作,但缺点是你必须在模式定义中编码'*'字符。

    <?xml version="1.0" encoding="utf-8"?> 
    <Project ToolsVersion="4.0" DefaultTargets="PrintNames" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
      <PropertyGroup> 
        <TargetDir>c:\temp\MyContent</TargetDir> 
        <InputFilesRelativeEsc>%2A%2A\%2A.bmp;%2A%2A\%2A.txt</InputFilesRelativeEsc>
      </PropertyGroup> 
    
      <Target Name="PrintNames"> 
        <ItemGroup>
            <_TempGroup Include="$(InputFilesRelativeEsc)" />
        </ItemGroup>
    
        <CreateItem Include="@(_TempGroup->'$(TargetDir)\%(Identity)')"> 
            <Output TaskParameter="Include" ItemName="_EvaluatedGroup" /> 
        </CreateItem> 
        <Message Text="_EvaluatedGroup: %(_EvaluatedGroup.FullPath)" />
    
      </Target> 
    </Project> 
    

    它的工作原理如下。属性InputFilesRelativeEsc是相对文件模式的列表。注意通配符是编码的(%2A是星号的十六进制代码)。由于编码的通配符,当您_TempGroup此模式进入此组时,组Include不会尝试搜索和提取文件列表。现在_TempGroup是一个由两个元素组成的组:**\*.bmp**\*.txt。既然你有一个真正的小组,你可以改变它。唯一的复杂因素是运行转换的正常MSBuild机制不会扩展通配符。您必须使用较早的CreateItem任务。 <{1}}任务实际上已被MSBuild团队宣布弃用,但它仍然有效。