Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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

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" />
    <ItemGroup>
      <FilesToDelete Include="$(ProjectDir)12" />
    </ItemGroup>

    <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" />
    <ItemGroup>
      <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" />
    </ItemGroup>

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

    <!-- now grab the assemblies from the other projects -->
    <Message Text="------ Copying files into $(ProjectDir)GAC  ------" Importance="high" />
    <ItemGroup>
      <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" />
    </ItemGroup>

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


  </Target>
</Project>

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" />
</Target>

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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top