用于删除文件的MSBuild任务语法

用于删除文件的MSBuild任务语法,msbuild,msbuild-task,Msbuild,Msbuild Task,我正在尝试编写一个MSBuild任务,该任务在我的生产构建脚本上从我的bin文件夹中删除Obj目录和pdb,但似乎无法使其正常工作 是否有人有这样或类似的示例,或者有指向使用MSBuild删除文件和目录的简单示例的链接?如果要删除整个目录,则需要执行以下任务: 如果要从bin中删除PDB文件,则需要执行以下任务: 请注意,在删除任务中不能使用通配符,因此如果有多个pdb文件,则必须提供一个作为参数。您可以先删除这些目录中的文件,然后使用 <Target Name="SomeTarg

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


是否有人有这样或类似的示例,或者有指向使用MSBuild删除文件和目录的简单示例的链接?

如果要删除整个目录,则需要执行以下任务:


如果要从bin中删除PDB文件,则需要执行以下任务:



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

您可以先删除这些目录中的文件,然后使用

<Target Name="SomeTarget">
    <ItemGroup>
        <FilesToDelete Include="Path\To\Obj\**\*"/>
    </ItemGroup>   
    <Delete Files="@(FilesToDelete)" />   
    <RemoveDir Directories="Path\To\Obj\" />
</Target>

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

<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命令返回“系统找不到指定的文件”,而不是“目录不为空”。在我的机器上,如果在Windows资源管理器中打开$(BuildFolder),则似乎需要另一个RmDir。防病毒程序可能会影响RmDir,就像它偶尔会进行Subversion一样,但我宁愿使用全面的防病毒保护,也不愿(错误地)管理排除列表

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

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

<ItemGroup>
    <FileToDelete Include="c:\temp\fileToDelete.txt"/>
</ItemGroup>
<Exec Command="del /F /Q &quot;@(FileToDelete)&quot;"/>

也可以先从文件中删除readonly属性,然后执行msbuild delete任务

像这样:

<Target Name="DeleteFiles">
 <Message Text="Delete File" Importance="high"/>
 <Attrib Files="$(FileToDelete)" ReadOnly="false" />
 <Delete Files="$(FileToDelete)" />
</Target>`

`

在Visual Studio 2013中,将其添加到我的.csproj文件末尾,正好在
结束标记之前


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


如果批量重建多个配置,请务必小心,因为它只会擦除每个重建上以前的所有工作,只留下最后一个配置。Whups.

只要你需要处理一个目录,发布的答案就会有效。如果您碰巧有嵌套文件夹,
RemoveDir
将失败,并出现
目录不为空
错误

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

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

只是为了再添一条我发现的皱纹。我正在使用Visual Studio 2015。通过通配符删除的帖子答案对我来说仍然很麻烦我怀疑通配符是在生成之前计算的,而不是在生成之后计算的。这意味着如果要删除的文件是在生成过程中创建的,则不会进行删除。它还导致了一种奇妙的行为,即每次构建时删除都会起作用,这使得测试非常愉快


我要放弃通配符了。对于我正在做的事情,我知道引起问题的文件,并且我正在硬编码(如果可以在项目文件中称之为)实际的文件名。

RemoveDir任务参考页(见上文)表示所有文件和子目录都将被删除。我希望我能标记您的两个答案,因为RemoveDir任务的链接告诉我真正缺少的是我没有取消引用OutputPath属性以查找正确的目录。Sayeds使用ItemGroup语法的响应是我需要抓取所有pdb来删除它们的操作。谢谢你们两位!对我有效,所以谢谢,但最好添加
ContinueOnError=“true”
属性,用于第一次重建IDENote-如果路径长度超过260个字符,RemoveDir将失败;您必须将Exec与rmdir一起使用。我一直在玩
任务,并注意到当我在Visual Studio中进行构建时,文件被删除,我在输出中看到了这些信息。但是当我运行它时,它有一个msbuild命令行,文件不会被删除,并且在输出中我看不到任何关于它的信息,不管详细程度如何。@pylover其中我有Path\To\Obj***路径应该是一个真正的文件夹路径;例如,要删除的C:\temp\文件夹。这可能是它不适合你的原因吗?你能提供更多的细节为什么它不工作吗?使用2012,我刚刚验证了RemoveDir是否按照文档所说的那样删除文件和文件夹。不需要额外的步骤。@SayedIbrahimHashimi为直接的方法感到抱歉,但我有你的书,但我仍然无法找到解决这个问题的方法。你能帮忙吗?看起来这里引用的Attrib任务好像是项目的一部分。这是在文件为只读时唯一对我有效的方法!(例如,从TFS签出):)谢谢。我有一个带有通配符的项目组,它扩展到了太多文件(完整路径),以至于
del
命令行太长。我的解决方案是直接将通配符传递给
del
,而不是使用ItemGroup。如果使用通配符的ItemGroup位于目标内部,则应在每次执行目标时对其进行评估。在项目执行时,项目级别的项目组确实会得到评估。
<Target Name="DeleteFiles">
 <Message Text="Delete File" Importance="high"/>
 <Attrib Files="$(FileToDelete)" ReadOnly="false" />
 <Delete Files="$(FileToDelete)" />
</Target>`
<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>