Skip to main content

Cloud

Using STSDEV and MSBUILD Targets to Generate a WSP That Spans Multiple Visual Studio Projects

We have been using STSDEV to automatically generate WSPs for several months now. For the most part, the tool has proven a very useful mechanism to ensure that our WSPs are created efficiently and accurately. Recently, however, we ran into an issue when trying to create a WSP that packages up files from multiple Visual Studio projects. As currently implemented, STSDEV is tied to a single Visual Studio project and a single RootFiles folder location per WSP. To get around this limitation, we have developed an approach that builds upon STSDEV’s use of custom MSBUILD targets to pull files from multiple Visual Studio projects into a single location for packaging into a WSP.

1. Create a Visual Studio solution and project using the STSDEV New Solution Wizard

a. Solution Name should be the name you want to give to the WSP / SharePoint solution

b. Solution Type should be “Empty Solution (no assembly)”

c. Solution/Project Version Type should be Visual Studio 2008 with .NET 3.0… STSDEV crashes if you select .NET 3.5 in the wizard but this can be changed later in Visual Studio

New Solution Wizard

2. Modify the Visual Studio project

a. Rename the project to indicate that it is a packaging project

i. This solution/project will serve as the packaging mechanism for the WSP

ii. The project should not include any code or designer files

b. Exclude the Manifest.xml and SolutionPackage.ddf files from the project… these should not be added to TFS

c. Ensure that the project assembly name matches the SolutionName element value in SolutionConfig.xml… both are set to the solution name given in the New Solution Wizard

Solution Explorer - 1

3. Add to the Visual Studio solution each of the projects that will be packaged in the WSP

Solution Explorer - 2

4. In the packaging project, add project references to each of the projects to be packaged

a. This will copy the referenced dlls to the bin folder of the packaging project

b. Ensure that the Copy Local property of the reference is true

5. Update the SolutionConfig.xml file in the packaging project

a. Set the AssemblyDeployment element to True

b. Set the SafeControlSettings element to True

c. Add an Assembly element for each of the dlls to be packaged

d. Include a SafeControl element for any assemblies that contain web parts or other controls

<?xml version="1.0" encoding="utf-8"?>

<!–Created by STSDEV at 8/9/2008 12:31:21 PM–>

<Solution>

<SolutionId>11E57418-B3D8-4B94-90D6-15E80AE1C879</SolutionId>

<SolutionName>MyTestProject.Packaging</SolutionName>

<ResetWebServer>True</ResetWebServer>

<AssemblyDeployment>True</AssemblyDeployment>

<SafeControlSettings>True</SafeControlSettings>

<CasPermissions>False</CasPermissions>

<Assemblies>

<Assembly Location="MyTestProject.ClassLibrary1.dll" DeploymentTarget="WebApplication" />

<Assembly Location="MyTestProject.WebPart1.dll" DeploymentTarget="WebApplication">

<SafeControls>

<SafeControl Assembly="MyTestProject.WebPart1, Version=1.0.0.0, Culture=neutral,

PublicKeyToken=9f4da00116c38ec5" Namespace="MyTestProject.WebPart1" TypeName="*" Safe="True" />

</SafeControls >

</Assembly>

<Assembly Location="MyTestProject.WebPart2.dll" DeploymentTarget="WebApplication">

<SafeControls>

<SafeControl Assembly="MyTestProject.WebPart2, Version=1.0.0.0, Culture=neutral,

PublicKeyToken=9f4da00116c38ec5" Namespace="MyTestProject.WebPart2" TypeName="*" Safe="True" />

</SafeControls >

</Assembly>

</Assemblies>

</Solution>

6. Add an ItemGroup element to the Microsoft.SharePoint.targets file in the packaging project

a. Include a child element for each project that contains files to be merged into the RootFiles directory of the WSP

b. The Include attribute of the child elements should be set to the path of the project’s RootFiles folder with a recursive wildcard for all subfolders and files

<ItemGroup>

<WebPart1RootFiles Include="..MyTestProject.WebPart1RootFiles***.*" />

<WebPart2RootFiles Include="..MyTestProject.WebPart2RootFiles***.*" />

</ItemGroup>

7. Add a new Target element called CopyRootFiles that follows the pattern below

a. A RemoveDir element to delete the packaging project RootFiles folder… this clears out the files that were copied in the last build

b. A Copy element for each project to be packaged in the WSP

i. The SourceFiles attribute points to one of the ItemGroup child elements created above

ii. The DestinationFiles attribute is set to copy the source files to the packaging project RootFiles folder while maintaining the folder structure in which the source files are located

c. Message elements to write status messages to the build output stream

<Target Name="CopyRootFiles">

<Message Text="Deleting RootFiles folder…" Importance="high" />

<RemoveDir Directories="$(ProjectRootFilesFolder)" />

<Message Text="Copying WebPart1 RootFiles …" Importance="high" />

<Copy SourceFiles="@(WebPart1RootFiles)"

DestinationFiles="@(WebPart1RootFiles->’$(ProjectRootFilesFolder)

%(RecursiveDir)%(Filename)%(Extension)’)" />

<Message Text="Copying WebPart2 RootFiles …" Importance="high" />

<Copy SourceFiles="@(WebPart2RootFiles)"

DestinationFiles="@(WebPart2RootFiles->’$(ProjectRootFilesFolder)

%(RecursiveDir)%(Filename)%(Extension)’)" />

</Target>

8. Update the DebugBuild and ReleaseBuild targets to have a dependency on CopyRootFiles… add the attribute DependsOnTargets=”CopyRootFiles” to the existing elements

<Target Name="DebugBuild" DependsOnTargets="CopyRootFiles">

<Target Name="ReleaseBuild" DependsOnTargets="CopyRootFiles">

When you build your packaging project, the files in each of the RootFiles folders referenced in the CopyRootFiles build target will be copied into the RootFiles folder in the packaging project. The project references set in the packaging project will cause the dlls output by the source project to be copied to the packaging project’s bin folder. With all of these files located in the folder structure of the packaging project, STSDEV can package all of the files into a single WSP.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

PointBridge Blogs

More from this Author

Follow Us
TwitterLinkedinFacebookYoutubeInstagram