【问题标题】:MSBuild Task syntax for deleting files用于删除文件的 MSBuild 任务语法
【发布时间】:2010-12-01 12:11:32
【问题描述】:

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

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

【问题讨论】:

    标签: msbuild msbuild-task


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • RemoveDir 任务参考页(见上文)说所有文件和子目录都将被删除。
    • 我希望我可以标记您的两个答案,因为 RemoveDir 任务的链接向我展示了真正缺少的是我没有取消引用我的 OutputPath 属性以找到正确的目录。使用 ItemGroup 语法的 Sayeds 响应是我需要做的以获取所有 pdb 以删除它们。谢谢你们!
    • 对我有用,谢谢,但最好添加 ContinueOnError="true" 属性,以便首次重建
    • 旁注 - 如果路径超过 260 个字符,RemoveDir 将失败;你必须使用 Exec 和 rmdir 来代替。
    • 我一直在玩&lt;Delete Files=...&gt; 任务,并注意到当我从 Visual Studio 进行构建时,文件被删除,我在输出中看到了该信息。但是当我运行它时,它有一个 msbuild 命令行,这些文件 not 被删除,并且无论详细程度如何,我在输出中都看不到它。
    【解决方案2】:

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

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

    【讨论】:

    • @pylover 我有 Path\To\Obj**\* 路径应该是真正的文件夹路径;例如要删除的 C:\temp\folder。这可能是它对你不起作用的原因吗?您能否详细说明为什么它不起作用?
    • 使用 2012 年,我刚刚验证 RemoveDir 执行文档所说的 - 删除文件和文件夹。不需要额外的步骤。
    • @SayedIbrahimHashimi 对直接的方法感到抱歉,但我有你的书,但我仍然无法解决这个问题。 stackoverflow.com/questions/25525197/… 。你能帮忙吗?
    【解决方案3】:

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

    <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。防病毒程序可能会影响 RmDir,就像它偶尔会影响 Subversion 一样,但我宁愿拥有全面的 AV 保护而不是(错误)管理排除列表。

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

      • 当文件只读时,这是唯一对我有用的东西! (例如从 TFS 签出):) 谢谢。
      • 我有一个带有通配符的 ItemGroup,它扩展到了很多文件(完整路径),以至于 del 命令行变得太长。我的解决方案是直接将通配符传递给del,而不是使用ItemGroup。
      【解决方案5】:

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

      像这样:

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

      【讨论】:

      【解决方案6】:

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

      <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 个其他构建配置(是的,我知道)。

      如果您批量重建多个配置,请小心,因为它只会抹掉之前在每次重建时所做的所有努力,只剩下最后一个。呜呜呜。

      【讨论】:

        【解决方案7】:

        只要您必须处理单个目录,发布的答案就会起作用。如果您碰巧有嵌套文件夹,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>
        

        【讨论】:

          【解决方案8】:

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

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

          【讨论】:

          • 如果使用通配符的 ItemGroup 在 Target 内,则应在每次执行 Target 时对其进行评估。项目级别的 ItemGroup 在项目执行时确实会被评估。
          猜你喜欢
          • 2020-02-22
          • 1970-01-01
          • 2021-08-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-24
          • 1970-01-01
          相关资源
          最近更新 更多