[Source: http://geekswithblogs.net/EltonStoneman]
There are a couple of reasons why you might want PDB files available in the GAC, say if you're running coverage reports over unit tests as part of your CI build, and the assemblies being instrumented all live in the GAC, or if you want to deploy BizTalk PDB files as a troubleshooting aid. Patrick Cauldwell has a PowerShell script to install PDBs to the GAC, which is a good basis for an MSBuild task to do the same.
The principle is straightforward – find the "hidden" GAC directory where it the assembly is deployed and copy the PDB file there. Danger here is that the GAC structure may change, so the task uses AssemblyName.CodeBase which gives you the full path to the physical location, rather than determining it from the current format.
The main work is done here:
string pdbFilename = string.Format("{0}.pdb", Path.GetFileNameWithoutExtension(this.AssemblyPath));
string pdbPath = Path.Combine(Path.GetDirectoryName(this.AssemblyPath), pdbFilename);
//if source PDB is found:
if (File.Exists(pdbPath))
{
//get the strong name info from the assembly:
AssemblyName gacAssemblyName = Assembly.LoadFile(this.AssemblyPath).GetName();
string gacPath = this.GetGacPhysicalLocation(gacAssemblyName);
//if GAC location found:
if (!string.IsNullOrEmpty(gacPath))
{
//copy PDB file:
try
{
File.Copy(pdbPath, Path.Combine(gacPath, pdbFilename));
Log.LogMessage("Added PDB file to GAC: {0}, location: {1}", pdbFilename, gacPath);
}
//log other conditions...
Where AssemblyPath is the path to the un-GACd assembly where the PDB file is expected to be found (e.g. the build output directory):
<Target Name="DeployPdbToGac">
<DeployPdbToGac AssemblyPath="$(BuildOutputDir)\x.y.dll"/>
</Target>
Full source code is here: MSBuild Task to Deploy PDB Files to GAC