MSBuild 任务,如何删除嵌套目录?

Posted

技术标签:

【中文标题】MSBuild 任务,如何删除嵌套目录?【英文标题】:MSBuild Task, how to remove nested directories? 【发布时间】:2021-08-27 03:17:33 【问题描述】:

作为构建任务的结果,我有一个如下所示的目录结构:

BuildOutput\Database\Customer\Scripts
BuildOutput\Database\Customer\obj
BuildOutput\Database\Customer\obj\Debug
BuildOutput\Database\Logging\Scripts
BuildOutput\Database\Logging\obj
BuildOutput\Database\Logging\obj\Debug

我正在尝试编写一个 MSBuild 构建任务,该任务将删除“obj”目录及其子目录,但保留其余部分。这里我展示了CustomerLogging,但由于脚本只构建已更改的项目,因此可能有很多其他项目或根本没有。这似乎有点棘手。

我尝试了很多不同的方法。在 MSBuild 之外的 PowerShell 中,这会选择正确的目录:

[System.IO.Directory]::GetDirectories('$(OutputRoot)\Database', 'obj', ([System.IO.SearchOption]::AllDirectories))

但在 MSBuild 内部:

<ItemGroup>
  <UnusedDirs Include="$([System.IO.Directory]::GetDirectories('$(OutputRoot)\Database', 'obj', ([System.IO.SearchOption]::AllDirectories)))" />
</ItemGroup>
<Message Text="Cleaning up non required database directories" />
<RemoveDir Directories="@(UnusedDirs)" />

给出这个错误信息:

D:\Dev\Application\Package.proj(176,29): error MSB4186: Invalid static method invocation syntax: "[System.IO.Directory]::GetDirectories('$(OutputRoot)\Database', 'obj', ([System.IO.SearchOption]::AllDirectories))". Requested value '([System.IO.Sea
rchOption]::AllDirectories)' was not found. Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(`a`, `b`)).

它似乎不理解SearchOption 枚举。有没有办法让它在 MSBuild 中工作?还是有其他方法可以删除这些目录?

【问题讨论】:

【参考方案1】:

您不需要调用 .NET 框架函数目录。您可以使用RemoveDir 任务。

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="clobber"  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

   <Target Name="clobber">
      <ItemGroup>
        <_ClobberDirectories Include=".\**\obj"/>
      </ItemGroup>
      <RemoveDir Directories="@(_ClobberDirectories)" ContinueOnError="true"/>
   </Target>

</Project>

关于ContinueOnError,您的看法可能不同。

【讨论】:

不幸的是,似乎RemoveDir does not support wild cards,因此需要所有这些愚蠢的Get-Directories 东西。如果支持通配符会soooo简单得多... 但是“ItemGroup”被扩展为目录列表,没有留下通配符。 (您可以检查将 RemoveDir 替换为 &lt;Message Text="@(_ClobberDirectories)" Importance="high" /&gt;。因此它将删除它在树中找到的“obj”目录以及(根据定义)它们下面的所有文件/目录。我个人在我的项目中使用它。所以我可能会理解你的问题错了。 输出 itemGroup 匹配项很有帮助 - 谢谢。 itemGroup 似乎只适用于文件。如果我将包含更改为$(OutputRoot)\**,我会得到所有文件,但不会得到目录。如果我将其更改为$(OutputRoot)\**\obj,我根本找不到匹配项,而且肯定有obj 目录。

以上是关于MSBuild 任务,如何删除嵌套目录?的主要内容,如果未能解决你的问题,请参考以下文章

如何删除VS2015中的OpenCV的配置

如何删除git嵌套repo但保留其中一个分支的文件?

无法让 MSBuild 社区任务 RegexReplace 工作

仅当文件数大于零时,如何在 MSBuild 中运行任务?

如何删除嵌套属性?

如何删除嵌套对象属性[重复]