将包含通配符的 MSBuild Properties 展开到 Items 中

发布于 2024-12-29 23:03:38 字数 904 浏览 4 评论 0原文

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

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

I am trying to write MSBuild script that will perform some action (eg. print its path) on an arbitrary files (specified as a property on a command line) in some predefined directory (F:\Files).

Given the following directory structure

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

And MSBuild Script

<?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>

running the script with InputFiles set to "**\*.bmp;**\*.txt" works fine only for bmp files. Txt files are taken from the current working directory, not from "F:\Files"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拥醉 2025-01-05 23:03:38

您必须解决两个问题:

  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 任务。 CreateItem 任务实际上已被 MSBuild 团队声明弃用,但它仍然有效。

There are two problems that you have to solve:

  1. $(InputFiles) is specifed as a scalar property, but you want to interprete it as an array
  2. $(InputFiles) contains wildcards you want to expand after you do transformation on the list of patterns in $(InputFiles).

It is easy to solve either of two problems separately, but combination of the two is actually tricky. I have one possible solution, and it works, but the downside is you have to encode '*' characters in your pattern definition.

<?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> 

It works as follows. Property InputFilesRelativeEsc is a list of relative file patterns. Notice wildcard characters are encoded (%2A is a hex code for asterisk). Since the wildcards encoded, the group _TempGroup does not attempt to search for and extract list of files while you Include this patterns into this group. Now _TempGroup is a group which consists of two elements: **\*.bmp and **\*.txt. Now that you have a real group you can transform it. The only complication is that the normal MSBuild mechanism of running transform does not expand wildcards. You have to use older CreateItem task. The CreateItem task is actually declared deprecated by MSBuild team, but it still works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文