MSBuild Task, how to remove nested directories?

Viewed 143

As the result of a build task, I have a directory structure that looks like this:

{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

I am trying to write an MSBuild build task that will remove the 'obj' directories and their subdirectories, but leave the rest. Here I've shown Customer & Logging, but because the script only builds projects that have changed, there could be many others or none at all. This seems to be the tricky bit.

I've tried many different things. In PowerShell, outside of MSBuild, this selects the correct directories:

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

But inside of 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)" />

Gives this error message:

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`)).

It just doesn't seem to understand the SearchOption enum. Is there a way of getting this to work in MSBuild? Or is there another way to delete these directories?

2 Answers

You don't need to invoke .NET framework functions directory. You can use the RemoveDir task.

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

About the ContinueOnError your opinion might be different.

I was confused by the way MSBuild handles enum values as well, but then figured out that this will work:

<ItemGroup>
    <FilesToRemove Include="$([System.IO.Directory]::GetFiles($(RootDir), '*', System.IO.SearchOption.AllDirectories))" />
</ItemGroup>
Related