防止将引用的程序集 PDB 和 XML 文件复制到输出

Posted

技术标签:

【中文标题】防止将引用的程序集 PDB 和 XML 文件复制到输出【英文标题】:Preventing referenced assembly PDB and XML files copied to output 【发布时间】:2011-01-01 22:58:41 【问题描述】:

我有一个 Visual Studio 2008 C#/.NET 3.5 项目,其中包含一个用于压缩内容的后期构建任务。但是,我发现我还在输出目录(和 ZIP)中获取了引用程序集的 .pdb(调试)和 .xml(文档)文件。

例如,如果 MyProject.csproj 引用 YourAssembly.dll 并且在与 DLL 相同的目录中存在 YourAssembly.xml 和 YourAssembly.pdb 文件,它们将显示在我的输出目录(和 ZIP)中。

我可以在压缩时排除 *.pdb,但我不能完全排除 *.xml 文件,因为我有具有相同扩展名的部署文件。

有没有办法防止项目复制引用的程序集 PDB 和 XML 文件?

【问题讨论】:

@HenrikHolmgaardHøyer 这个问题与您的“可能重复”完全相反 【参考方案1】:

我希望能够在我的主应用程序中添加和删除引用的程序集,同时避免需要维护我需要删除或排除的文件。

我翻遍了Microsoft.Common.targets 寻找可行的方法并找到了AllowedReferenceRelatedFileExtensions 属性。它默认为.pdb; .xml,所以我在我的项目文件中明确定义了它。问题是你需要 something (空白是不够的)否则它仍然会使用默认值。

<Project ...>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    ...
    <AllowedReferenceRelatedFileExtensions>
      <!-- Prevent default XML and PDB files copied to output in RELEASE. 
           Only *.allowedextension files will be included, which doesn't exist in my case.
       -->
      .allowedextension
    </AllowedReferenceRelatedFileExtensions> 
  </PropertyGroup>

【讨论】:

这可能是“正确”的方式,但它太隐蔽了,这在我的书中很糟糕。 这在从 Visual Studio IDE 构建时有效。但是,在通过 MSBuild 构建时,它对我不起作用。如果它在项目文件中,我不需要将其指定为 /p 选项。 适用于不熟悉 VS 项目幕后的任何人。这是一个很好的分步指南。kitsula.com/Article/How-to-exclude-xml-doc-files-from-msbuild 我把这个 sn-p 放在 vs2019 的“debug|any cpu”部分。它不起作用 @bh_earth0 我也使用 VS 2019,它对我有用。我花了一段时间才弄清楚为什么一开始它不起作用 - 我有几个 .csproj 文件(用于我的 .sln 中的多个项目),我不得不将 放在每个 .csproj 文件中。【参考方案2】:

您也可以通过命令行指定:

MsBuild.exe build.file /p:AllowedReferenceRelatedFileExtensions=none

【讨论】:

这看起来像是要走的路,因为您可以将它包含在您的构建定义 MSBuild 参数中,而不必修改 csproj 文件。 这在 TFS 中效果很好,并且在我的情况下不必修改 100 个项目 也适用于 TFS2018 和非 XAML 样式的构建。 简洁快速的解决方案。谢谢【参考方案3】:

您可以添加类似于del "$(TargetDir)YourAssembly*.xml", "$(TargetDir)YourAssembly*.pdb" 的构建后事件命令

【讨论】:

谢谢。如果您有引用程序集的静态列表,则此方法有效。然而,在我们的案例中,我们有超过两打,其中许多在我们重构时不断变化。 就我个人而言,我认为这是正确的答案——另一种方式是你破解了项目文件,而其他任何人(或多年后的你自己)都不知道在哪里可以看到这种情况被阻止。 我也喜欢这种方式。我喜欢让任何需要发生的事情(或最初被设计为发生的事情)完成,然后让后期构建事件最终让它像我想要的那样。这样看起来就干净多了! 即使这个解决方案有效,但它并没有真正优化,因为你会浪费时间复制你要删除的东西。我也一直将构建前/构建后步骤视为 hack,因为它们在构建系统中的工作效果不如目标或 proj 文件。 哇 @christ.s , *chuckle * 我希望在我回答这个问题后的十年里,Visual Studio 团队会让这件事变得更容易。 :-)【参考方案4】:

这是一个相当古老的问题,但由于没有关于如何通过 UI 关闭生成 PDB 和 XML 文件的答案,我认为它应该在这里是为了完整性。

在 Visual Studio 2013 中:在项目属性中,在编译选项卡下,取消选中“生成 XML 文档文件”,然后单击下方的“高级编译选项”并将“生成调试信息”更改为“无”,这样就可以了诀窍。

【讨论】:

这不会影响您包含的任何 nuget 包,它们仍将具有 pdbxml 文件。 我在我的 csproj 文件中使用 OctoPack 属性,这对我的 PDB 和 XML 文件起到了作用。我也在使用 VS 2015。构建 -> 输出下的高级 -> 将输出下的调试信息设置为无【参考方案5】:

前 2 个答案对我不起作用。我在这个链接中找到了一个对我有用的解决方案。 http://kitsula.com/Article/How-to-exclude-xml-doc-files-from-msbuild.

以防万一,以上链接失效:

    在解决方案资源管理器中卸载项目

    右键单击项目并单击“编辑 *.csproj”

    在每个环境的 PropertyGroup 部分添加下一行。

    重新加载并重建项目。

     <AllowedReferenceRelatedFileExtensions>
              *.pdb;
              *.xml
     </AllowedReferenceRelatedFileExtensions>
    

【讨论】:

【参考方案6】:

我对其他答案没有太多运气,我终于通过使用内置的"Delete" command 弄清楚了如何在我的实现中做到这一点,显然您需要implement wildcards 的特定方式,它是@ 987654323@,这是您需要放入“项目”标签下的“CSPROJ”(TargetDir 是内置变量,自动包含)中的所有内容:

<Target Name="RemoveFilesAfterBuild">   
    <ItemGroup>
        <XMLFilesToDelete Include="$(TargetDir)\*.xml"/>
        <PDBFilesToDelete Include="$(TargetDir)\*.pdb"/>
    </ItemGroup>
    <Delete Files="@(XMLFilesToDelete)" />
    <Delete Files="@(PDBFilesToDelete)" />
</Target>

我也遇到了生成各种特定语言文件夹的问题,如果您也遇到这个问题,您也可以删除未使用的特定语言文件夹。我选择仅在构建类型“Release”下触发它:

<ItemGroup>
    <FluentValidationExcludedCultures Include="be;cs;cs-CZ;da;de;es;fa;fi;fr;ja;it;ko;mk;nl;pl;pt;ru;sv;tr;uk;zh-CN;zh-CHS;zh-CHT">
        <InProject>false</InProject>
    </FluentValidationExcludedCultures> 
</ItemGroup>

<Target Name="RemoveTranslationsAfterBuild" AfterTargets="AfterBuild" Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <RemoveDir Directories="@(FluentValidationExcludedCultures->'$(OutputPath)%(Filename)')" />

    <ItemGroup>
        <XMLFilesToDelete Include="$(TargetDir)\*.xml"/>
        <PDBFilesToDelete Include="$(TargetDir)\*.pdb"/>
    </ItemGroup>
    <Delete Files="@(XMLFilesToDelete)" />
    <Delete Files="@(PDBFilesToDelete)" />
</Target>

【讨论】:

【参考方案7】:

我现在的回答可能很简单,但如果有相应的 dll,我想分享我用来删除 xml 文件的 BAT 脚本。如果您只想清理输出文件夹并且有其他不想删除的 xml 文件,这很有用。

SETLOCAL EnableDelayedExpansion

SET targetDir=%1

ECHO Deleting unnecessary XML files for dlls

FOR %%F IN (%targetDir%*.xml) DO (

  SET xmlPath=%%~fF
  SET dllPath=!xmlPath:.xml=.dll!

  IF EXIST "!dllPath!" (
    ECHO Deleting "!xmlPath!"
    DEL "!xmlPath!"
  )
)

用法:

Cleanup.bat c:\my-output-folder\

我花了一个小时完成这个简单的工作(感谢“延迟扩展”的东西),到处都是各种类型的搜索。希望它可以帮助像我这样的其他 BAT 新手。

【讨论】:

【参考方案8】:

如果您只想排除 XML 文件(例如调试版本),您可以执行以下操作:

<AllowedReferenceRelatedFileExtensions>
  <!-- Prevent default XML from debug release  -->
      *.xml
 </AllowedReferenceRelatedFileExtensions>

基本上,列出的每个扩展名(由分号分隔)都将被排除在外。

【讨论】:

这个问题及其接受的答案已有 4 年历史了,您的回答几乎是接受答案的复制粘贴。 不同的是我需要的只是 XML 文件的语法。我不得不对这个标签的正确语法做一些研究。我发现原始答案很有帮助并对其进行了投票,但我认为如果他们只需要过滤特定的文件类型,我可以为其他人节省一些时间。 但这不会包含 xml文件,而不是排除它吗?

以上是关于防止将引用的程序集 PDB 和 XML 文件复制到输出的主要内容,如果未能解决你的问题,请参考以下文章

如何防止引用程序集的嵌入式依赖项被复制到Visual Studio中的输出文件夹?

将 wwwroot 的内容从类库复制到托管程序集

如何检查 pdb 文件是不是对调试程序集有效

如何不将 app.config 文件复制到输出目录

在发布时强制将外部文件复制到 bin 文件夹

MEF - 插件及其引用的程序集