135

I have a Visual Studio 2008 C#/.NET 3.5 project with a post build task to ZIP the contents. However I'm finding that I'm also getting the referenced assemblies' .pdb (debug) and .xml (documentation) files in my output directory (and ZIP).

For example, if MyProject.csproj references YourAssembly.dll and there are YourAssembly.xml and YourAssembly.pdb files in the same directory as the DLL they will show up in my output directory (and ZIP).

I can exclude *.pdb when ZIP'ing but I cannot blanket exclude the *.xml files as I have deployment files with the same extension.

Is there a way to prevent the project from copying referenced assembly PDB and XML files?

SamB
  • 9,039
  • 5
  • 49
  • 56
Jason Morse
  • 6,204
  • 5
  • 29
  • 29

9 Answers9

172

I wanted to be able to add and remove referenced assemblies in my primary application while avoiding the the need to maintain which files I needed to delete or exclude.

I dug through Microsoft.Common.targets looking for something that would work and found the AllowedReferenceRelatedFileExtensions property. It defaults to .pdb; .xml so I explicitly defined it in my project file. The catch is that you need something (whitespace is not sufficient) otherwise it will still use the default.

<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>
Jason Morse
  • 6,204
  • 5
  • 29
  • 29
  • 6
    This might be the "correct" way but it's so hidden which is bad in my books. – Mladen Mihajlovic Dec 09 '15 at 10:35
  • 1
    This worked when building from the Visual Studio IDE. However, it didn't work for me when building via MSBuild. I shouldn't need to specify it as a /p option if it's in the project file. – redcurry Apr 20 '18 at 15:52
  • 1
    For anyone who's not familiar with the behind the scenes of a VS project. Here's a nice step by step guide.http://kitsula.com/Article/How-to-exclude-xml-doc-files-from-msbuild – Reahreic Feb 09 '21 at 15:25
  • i put this snippet inside "debug|any cpu" section on vs2019. it doesnt work – bh_earth0 Feb 23 '22 at 12:32
  • @bh_earth0 I also use VS 2019 and it works for me. It took me a while to figure out why at first it did not work - I had several .csproj files (for serveral projects in my .sln) and I had to put the in each .csproj file. – Sebastian Mar 02 '22 at 16:25
  • This also works when building with `dotnet build` or `dotnet publish` (VS2019). +1 – Maxim Paperno Mar 29 '22 at 20:09
  • If you wish to apply this to all projects without having to modify each .csproj file, put the content from the answer in a *Directory.Build.props* file located at the project root level, i.e., the same place where the *.sln* file lives. The build system will apply this automatically to each compiled project. Note that a quirk (bug) in Visual Studio requires unloading the solution and reloading it before the *.props* file will be picked up. – Matt Davis Jul 01 '22 at 05:23
73

You can also specify this via the command line:

MsBuild.exe build.file /p:AllowedReferenceRelatedFileExtensions=none
Irvin Dominin
  • 30,819
  • 9
  • 77
  • 111
mwjackson
  • 5,403
  • 10
  • 53
  • 58
22

You can add a Post Build event command similar to del "$(TargetDir)YourAssembly*.xml", "$(TargetDir)YourAssembly*.pdb"

AndrewJacksonZA
  • 1,243
  • 2
  • 18
  • 31
  • 1
    Thanks. This works if you have a static list of referenced assemblies. In our case however we had over two dozen, with many of them in flux while we refactored. – Jason Morse Feb 19 '10 at 22:25
  • 4
    Personally I think this is the correct answer -the other way has you hacking the project file and anybody else (or yourself years later) would not know where to look to see this being prevented. – Mladen Mihajlovic Dec 09 '15 at 10:34
  • 1
    I prefer this way as well. I like to let whatever needs to happen (or was designed to happen in the first place) to finish and then let the post build events make it like I want it in the end. It just seems so much cleaner this way! – Arvo Bowen Dec 03 '16 at 22:59
  • Even tho this solution works, it's not really optimized since you loose time copying something you'll delete. I've also always considered pre/post build steps as hacks since they don't work as well in a build system than targets or proj files. – christ.s Jan 15 '20 at 17:59
  • Wow @christ.s , *chuckle * I would hope that in the ten years since I answered this question the Visual Studio team would've made this easier. :-) – AndrewJacksonZA Jan 20 '20 at 08:11
6

top 2 answers didn't work for me. I found a solution in this link which worked for me. http://kitsula.com/Article/How-to-exclude-xml-doc-files-from-msbuild.

Just in case, the above link is not working:

  1. Unload project in Solution Explorer

  2. Right click the project and click 'edit *.csproj'

  3. Add next lines in the PropertyGroup section of each environment.

  4. Reload and rebuild project.

     <AllowedReferenceRelatedFileExtensions>
              *.pdb;
              *.xml
     </AllowedReferenceRelatedFileExtensions>
    
Vasanth8891
  • 61
  • 1
  • 3
5

This is a rather old question, but since there is no answer about how to turn off generating PDB and XML files via UI, i figured that it should be here for completeness.

In Visual Studio 2013: in project properties, under compile tab, uncheck "Generate XML documentation file", then click on "Advanced Compile Options" below that and change "Generate debug info" to "None", and that will do the trick.

Dingo
  • 341
  • 3
  • 10
  • 19
    That won't effect any nuget packages you include they will still have `pdb` and `xml` files. – user692942 Oct 29 '15 at 12:44
  • I'm using OctoPack properties in my csproj file and this did the trick for my PDB and XML files. I was also using VS 2015. Build -> Advanced under Output -> set Debug Info to none under Output – Devin Prejean Mar 27 '17 at 17:18
3

I didn't have much luck with the other answers, I finally figured out how to do this in my implementation by using the built in "Delete" command, apparently there is a specific way you need to implement wildcards, it's bit nuanced, here's everything you need to be put into your "CSPROJ" (TargetDir is a built in variable, included automatically) under the "Project" tag:

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

I've also had trouble with various language specific folders being generated, if you have that issue too, you can also remove unused language specific folders too. I've chosen to only trigger this under the build type "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>
David Rogers
  • 2,601
  • 4
  • 39
  • 84
0

My answer might be trivial now but I'd like to share the BAT script I use to delete the xml files if there's a corresponding dll for it. It's useful if you just want to cleanup the output folder and has other xml files that don't want to remove.

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!"
  )
)

Usage:

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

It took me an hour to finish this simple work (thanks to the "delayed expansion" stuff) with all type of searching here and there. Hope it helps other BAT newbies like me.

Jeffrey Zhao
  • 4,923
  • 4
  • 30
  • 52
0

Using the AllowedReferenceRelatedFileExtensions property as others suggested above works well for me either in project files or via msbuild call as well.

There is one caveat though, which is that it works universally.

If we have a lot of projects that reference each other, this will also remove those pdbs that belong to the bottom projects referenced in top projects as well, not just external pdbs.

A possibility is to fallback to project-based setting and add it only to "bottom" projects, but that still makes it hard to get away with intermediate external references directly in top projects, so I am not sure how to control this properly.

In my opinion, it would be great to find a universal way of getting rid of all pdbs coming from external libraries but keep all pdbs coming from internal project references

One thing that seems to work for golden-means is using a combination as below:

/p:AllowedReferenceRelatedFileExtensions=.xml;.config /p:CopyLocalLockFileAssemblies=false 

the CopyLocalLockFileAssemblies property is set to false to prevent the copying of PDB files from NuGet packages, and the AllowedReferenceRelatedFileExtensions property is set to exclude ".pdb" files from external NuGet packages, but include all other related files (".xml" and ".config" files). Locally referenced projects that include PDB files will still have their PDB files copied to the output directory during build

-4

If you only want to exclude the XML files (for say a debug release) you can do something like this:

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

Basically, each extension (delimited by a semi-colon) listed will be excluded.

ProVega
  • 5,864
  • 2
  • 36
  • 34
  • 1
    This question and its accepted answer are 4 years old, and your answer is almost a copy-paste of the accepted answer. – Zack Oct 16 '15 at 13:38
  • 1
    What is different is the syntax for just XML files which is what I needed. I had to do some research for the proper syntax of this tag. I found the original answer helpful and up-voted it, but figured I could save someone else some time if they just needed to filter a specific file type. – ProVega Oct 16 '15 at 21:01
  • 16
    But won't this *include* the xml files, not exclude it? – David Gardiner May 18 '16 at 05:49