81

我正在尝试编写一个 MSBuild 任务,该任务从我的生产构建脚本的 bin 文件夹中删除 Obj 目录和 PDB,并且似乎无法使其正常工作。

有没有人有一个他们这样做或类似的例子,或者一个使用 MSBuild 删除文件和目录的简单例子的链接?

4

8 回答 8

137

您可以先删除这些目录中的文件,然后再删除目录本身

<Target Name="SomeTarget">
    <ItemGroup>
        <FilesToDelete Include="Path\To\Obj\**\*"/>
    </ItemGroup>   
    <Delete Files="@(FilesToDelete)" />   
    <RemoveDir Directories="Path\To\Obj\" />
</Target>
于 2009-09-27T01:17:23.517 回答
100

如果您要删除整个目录,则需要RemoveDir任务:

<RemoveDir Directories="Path/To/Obj" />

如果你想从 bin 中删除 PDB 文件,你需要Delete任务:

<Delete Files="Path/To/Bin/MyApp.pdb" />

请注意,您不能在 Delete 任务中使用通配符,因此如果您有多个 pdb 文件,则必须提供ItemGroup作为参数。

于 2009-09-25T17:49:07.087 回答
19

为可能遇到与我遇到的相同问题的其他人发帖。

Delete 任务无法删除只读文件,这是我需要能够做到的,因为当 MSBuild 从 TFS 获取最新的文件时,这些文件被标记为只读。我使用 EXEC 命令删除只读文件:

<ItemGroup>
    <FileToDelete Include="c:\temp\fileToDelete.txt"/>
</ItemGroup>
<Exec Command="del /F /Q &quot;@(FileToDelete)&quot;"/>
于 2011-12-14T17:04:49.707 回答
12

只要您必须处理单个目录,发布的答案就会起作用。如果您碰巧有嵌套文件夹,RemoveDir则会因Directory not empty错误而失败。

一种稍微通用的方法也可以处理嵌套文件夹:

<Target Name="CleanOutDir">
    <ItemGroup>
        <FilesToClean Include="$(OutDir)\**\*.*" />

        <!-- Bit of .Net to get all folders and subfolders -->
        <FoldersToClean Include="$([System.IO.Directory]::GetDirectories(&quot;$(OutDir)&quot;))" />
    </ItemGroup>

    <Delete Files="@(FilesToClean)"/>
    <RemoveDir Directories="@(FoldersToClean)" />
</Target>
于 2015-07-30T17:11:22.853 回答
5

这段代码太丑了,应该附带一个晕机袋。;-) 但它很快,因为它不会建立要删除的文件列表等。

<Target Name="DeleteBuildFolder">
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
    <Exec Command="RmDir /S /Q &quot;$(BuildFolder)&quot;" />
</Target>

需要多少个 RmDir 命令?够了,所以几个 RmDir 命令返回“系统找不到指定的文件”而不是“目录不为空”。在我的机器上,如果 $(BuildFolder) 在 Windows 资源管理器中打开,它似乎需要另一个 RmDir。防病毒程序可能会像偶尔影响 Subversion 一样影响 RmDir,但我宁愿拥有全面的 AV 保护而不是(错误)管理排除列表。

于 2011-08-31T00:41:34.830 回答
4

也可以先从文件中删除 readonly 属性并执行 msbuild delete 任务。

像这样:

<Target Name="DeleteFiles">
 <Message Text="Delete File" Importance="high"/>
 <Attrib Files="$(FileToDelete)" ReadOnly="false" />
 <Delete Files="$(FileToDelete)" />
</Target>`
于 2012-07-17T11:57:28.350 回答
3

在 Visual Studio 2013 中,将此添加到我的 .csproj 文件的末尾,就在</Project>结束标记之前

<Target Name = "clean_folders" AfterTargets="Clean">
 <Exec Command = "rd /S /Q obj" />
 <Exec Command = "rd /S /Q bin" />
</Target>

起初它似乎没有工作,但我注意到 Visual Studio(或 R#,不确定)重新添加DesignTimeResolveAssemblyReferencesInput.cache到 obj 文件夹,它还重新添加了当前\bin文件夹(我在不同的子文件夹中有不同的构建\bin)。它清除了其他所有内容,包括我从导入的 .csproj 文件中获得的 25 个其他构建配置(是的,我知道)。

如果您批量重建多个配置,请小心,因为它只会抹去每次重建的所有先前努力,只留下最后一个。哇塞。

于 2014-08-03T23:07:44.830 回答
2

只是为了增加我发现的皱纹。我正在使用 Visual Studio 2015。通过通配符删除的已发布答案对我来说仍然很麻烦。 我怀疑通配符是在构建之前评估的,而不是在. 这意味着如果您要删除的文件是在构建期间创建的,则不会发生删除。它还会导致奇妙的行为,即每次构建时删除都会起作用,这使得这一切测试起来非常愉快。

我放弃了通配符。对于我正在做的事情,我知道导致问题的文件并且我正在硬编码(如果可以在项目文件中调用它)实际的文件名。

于 2016-03-31T19:26:30.810 回答