I'm working on a SharePoint solution containing five Visual Studio projects. One is a "common library"-type of project and the other four are features with code that depend on the library.

The issue is with developing, deploying, and packaging all on the same machine in this scenario. If the DLL for the common library is in the GAC (which it is as part of debugging and testing) then Visual Studio does not copy it to the bin\Release folder as part of a build. (This is even true if "Copy Local" is set to true on the properties of the reference to the common library.) So when WSPBuilder comes along to package it up the file is missing and the features will not work.

How should this be overcome?

  • There are a lot of good answers and techniques here. I've ticked the one that works best for me but it doesn't mean it's the best one.
    – Alex Angas
    Aug 16, 2010 at 23:28

5 Answers 5


Just to make simple answer: In your Visual Studio project create a folder called GAC and place your reffed assemblies there and WSPBuilder will take care of the rest. /WW

  • Isn't the problem with that idea that it's fine at the end of the project when all your classes/artifacts have been finalised, but no use at the beginning as you're adding new things to your assemblies daily! Hence you need something to regularly copy things as you go to the GAC folder (for WSPBuilder to pick up), otherwise you're manually copying files around all the time. I like the automated copy approach as it only needs to be done once, as you know you're always good. Just need to add new projects as they come along (or write better MSBuild, I couldn't seem to get a generic script). Jan 14, 2010 at 12:28
  • I agree Chris I def like your automated build, just wanted to point out a simple way to do it for those who gets scared of msbuild. Jan 14, 2010 at 12:31
  • Ah righto. Well yep, I agree MSBuild definitely can be pain as most folks don't do it every day :) Jan 14, 2010 at 12:48
  • You could add a cmd.exe command in your project post-build script.
    – xdhmoore
    Apr 18, 2012 at 18:30

Somebody have been doing WSP builds on his dev server, and not on build server ;-)

This is a known bug. We only ran into it when somebody by accident build his own WSP instead of taking it from the build server (as he should) where nothing was in the GAC.

hth Anders Rask

  • Build server! That's a luxury :-)
    – Alex Angas
    Jan 13, 2010 at 22:54

I refactored things on my current project to "consolidate" the number of WSPs used, so we have a similar situation. We have around 12 Visual Studio projects but only 2 WSPs - that's just the factoring which makes the most sense and offers the most convenience for us.

I wrote some MSBuild the other day to help WSPBuilder achieve the packaging we want - this might be what you're looking for. Effectively we have 2 special "packaging" projects which consolidate assemblies, files in the SharePoint root etc by grabbing these files from other projects in the solution at compile time. This sample is for 1 of my 2 packaging projects and is saved separately as say FooCollabBuild.csproj:

<?xml version="1.0" encoding="utf-8" ?>
<Project DefaultTargets="FooSharePointBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="FooSharePointBuild">

    <!-- first clear down the 12 directory -->
    <Message Text="------ Clearing down $(ProjectDir)12  ------" Importance="high" />
      <FilesToDelete Include="$(ProjectDir)12" />

    <Message Text="------ If an MSBuild error occurs here it can safely be ignored ------" Importance="high" />
    <RemoveDir ContinueOnError="true" Directories="@(FilesToDelete)" />

    <!-- now grab the 12 files from the other projects -->
    <Message Text="------ Copying files into $(ProjectDir)12  ------" Importance="high" />
      <SharePointFiles Include="$(SolutionDir)Foo.SharePoint.Common\12\**\*.*" Exclude="$(SolutionDir)Foo.SharePoint.Common\12\**\*.spvdinfo" />
      <SharePointFiles Include="$(SolutionDir)Foo.SharePoint.TeamSite\12\**\*.*" Exclude="$(SolutionDir)Foo.SharePoint.TeamSite\12\**\*.spvdinfo" />
      <SharePointFiles Include="$(SolutionDir)Foo.SharePoint.CrossSiteCollection\12\**\*.*" Exclude="$(SolutionDir)Foo.SharePoint.CrossSiteCollection\12\**\*.spvdinfo" />
      <SharePointFiles Include="$(SolutionDir)Foo.SharePoint.SubSiteCreation\12\**\*.*" Exclude="$(SolutionDir)Foo.SharePoint.SubSiteCreation\12\**\*.spvdinfo" />
      <SharePointFiles Include="$(SolutionDir)Foo.SharePoint.SubSiteCreation.Workflow\12\**\*.*" Exclude="$(SolutionDir)Foo.SharePoint.SubSiteCreation.Workflow\12\**\*.spvdinfo" />

    <Copy SourceFiles="@(SharePointFiles)" DestinationFolder="$(ProjectDir)12\%(RecursiveDir)" />

    <!-- now grab the assemblies from the other projects -->
    <Message Text="------ Copying files into $(ProjectDir)GAC  ------" Importance="high" />
      <Assemblies Include="$(SolutionDir)Foo.SharePoint.Common\bin\**\*.dll" />
      <Assemblies Include="$(SolutionDir)Foo.SharePoint.TeamSite\bin\**\*.dll" />
      <Assemblies Include="$(SolutionDir)Foo.SharePoint.CrossSiteCollection\bin\**\*.dll" />
      <Assemblies Include="$(SolutionDir)Foo.SharePoint.SubSiteCreation\bin\**\*.dll" />
      <Assemblies Include="$(SolutionDir)Foo.SharePoint.SubSiteCreation.Workflow\bin\**\*.dll" />

    <Copy SourceFiles="@(Assemblies)" DestinationFolder="$(ProjectDir)GAC\" />


This is then referenced in the actual .csproj file of the "package" project using:

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\FooCollabBuild.proj" />
<Target Name="AfterBuild">
  <CallTarget Targets="FooSharePointBuild" />

Then whenever I need a WSP (as opposed to copy 12/copy bin/copy GAC), I just use the WSPBuilder extensions on the package project to generate. Your SafeControls entries etc. will be taken care of since WSPBuilder sees the assemblies in the GAC folder.

Shout if you have any questions.

  • I have found that this method of modifying my project files to aggregate everything into deployment projects has saved an enormous amount of time. You can also use the build configurations to determine which files to aggregate (debug/release).
    – MBSurf
    Jan 28, 2010 at 15:51

My WSPBuilder.exe.config file has this setting:

<add key="IncludeAssemblies" value="true" />

Which causes WSPBuilder to include references from the GAC if I'm not mistaken..


The SharePoint solution that I am working on is using a number of Visual Studio projects to allow packaging up to a single wsp solution. We use post build events for each project to copy the various folders 12, 80, GAC into a Solution Folder called Build.

We found that in each of the 80 and GAC folders we needed to have a dummy file (we used a readme.txt file) put in the folder so that the folder is created when using TFS Build Servers.

The project that has the most dependencies then builds the wsp solution by running wsp builder on the Solution\Build folder and copies the .wsp file into a Solution\Deployment folder.

To keep the build times quick we have two build configurations one called Debug which adds the assemblies to the appropriate area web app bin or GAC. Whilst we have a separate build called TeamServer which has to be selected in order for the wsp to be built correctly.

I don't have my post build event code to hand at the moment, but if you need more info then just ask.

Regards Simon

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.