将包含通配符的MSBuild属性扩展为项

5

我正在尝试编写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个回答

7
你需要解决两个问题:
  1. $(InputFiles)作为标量属性被指定,但你希望将其解释为数组。
  2. $(InputFiles)包含通配符,你希望在对$(InputFiles)中的模式列表进行转换后扩展它们。
解决其中任意一个问题都很容易,但两个问题的组合实际上很棘手。我有一种可能的解决方案,并且它有效,但缺点是你必须在模式定义中编码“*”字符。
<?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中时,该组不会尝试搜索并提取文件列表。现在_TempGroup是一个由两个元素组成的组:**\*.bmp**\*.txt。既然您有了一个真正的组,就可以对其进行转换。唯一的复杂之处在于,运行转换的常规MSBuild机制不会展开通配符。您必须使用较旧的CreateItem任务。MSBuild团队实际上已宣布CreateItem任务已过时,但仍可使用。

看起来这是唯一的方法(不需要实现自定义任务),谢谢。我尝试使用属性函数(.Replace("%", "%2A"))来避免传递转义属性的必要性,但它没有起作用。 - Maciej Wozniak
非常好,是的:确认CreateItem任务确实以这种方式展开在属性中转义的通配符,而在<ItemGroup>中内联创建ItemGroup则不起作用。 - Jeremy McGee
1
我该如何使用它来输出<EmbbededResource> <Link/> </EmbeddedResource>项目? - mcintyre321

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接