Using Solution Packages to Deploy Features and Content in Windows SharePoint Services 3.0

Summary: Learn how to use Windows SharePoint Services 3.0 solution packages to manage and deploy Features and content. (20 printed pages)

Joel Krist, Akona Consulting

Chris Hasz, Akona Consulting

December 2008

Applies to: Windows SharePoint Services 3.0

Contents

  • SharePoint Solution Framework

  • Deployment Package Creation Walkthrough

  • Conclusion

  • Additional Resources

SharePoint Solution Framework

A SharePoint solution can include many types of components, such as Features, site definitions, assemblies, templates, and additional resources for your project. This can make deployment of a complex solution a challenging task. The Windows SharePoint Services 3.0 solution framework helps to simplify the process of deploying and managing the life cycle of a SharePoint solution. The SharePoint solution framework works with solution files, or packages, to support the deployment and upgrade of SharePoint solutions in a controlled, repeatable manner. For more information about the SharePoint solution framework, see Solutions Overview.

Solution Package Structure

The recommended SharePoint solution package is a .cab file with a .wsp file name extension. It contains the optional files and resources that make up the solution and the required solution manifest file that Windows SharePoint Services uses to determine how to install the package. The solution manifest file must be named "manifest.xml" and must exist in the top-level (root) folder of the solution package. The solution manifest file uses the elements that are defined by the solution schema to define the parts of the solution, including its files, assemblies, code access security, Web Parts,

Features, site definitions, and other resources. (For more information about solution schemas, see Solution Schema.)

Figure 1 shows the contents of a SharePoint solution package that is used to provision a custom Web Part Page creation form with custom Web Part Page templates.

Figure 1. Solution package structure

In the package, notice the location of the manifest.xml file and the .aspx and .gif resources. The location of the resources is relative to the TEMPLATE folder for layouts or the FEATURES folder for Features. Both of these directories are located in the top-level SharePoint installation folder.

Figure 2 shows the contents of the manifest.xml file for the same solution.

Figure 2. Manifest.xml contents

The top-level Solution element (see Solution Element (Solution)) has a SolutionId attribute, which is a GUID that Windows SharePoint Services uses to uniquely identify the solution. The Solution element has child elements that can be used to specify the parts that make up the solution. For the complete list of supported child elements, see Solution Schema. The manifest.xml file shown here uses the FeatureManifest element to specify a single Feature and uses multiple TemplateFile elements to specify the resources that are used by the solution. These resources are deployed to folders that are relative to the TEMPLATE folder in the top-level SharePoint installation folder. The Location attribute of these elements specifies the path to the resource in the solution package.

Creating Solution Packages

You can create solution packages by using various techniques and tools, but the basic approach is always the same: identify and gather the solution resources, create a solution manifest file, create a diamond directive file (DDF), and run MakeCAB.exe on the DDF file to create the solution package.

Following are three approaches to creating a solution package:

  • Use the MakeCAB.exe command-line utility

    The MakeCAB.exe utility is provided with the Microsoft Cabinet Software Development Kit. To use MakeCAB.exe, you must first create a DDF file that specifies the folders and files that make up your solution. Then, run MakeCAB.exe against the DDF to generate the solution package. For more information, see the visual how-to article Creating a Solution Package in Windows SharePoint Services 3.0.

    Figure 3 shows the Custspcf.ddf file that was created for the custom Web Part Page template solution described earlier.

    Figure 3. MakeCAB Custspcf.ddf file contents

    The DDF file specifies the name of the solution package with the CabinetNameTemplate directive. You then specify the files that make up the solution by using a source folder | destination folder format. The source folder is the location of the file in the file system, and the destination folder is the location of the file in the solution package. The destination folder of a file must match the path for the file that is specified in the solution's manifest.xml file.

    You can invoke MakeCAB.exe directly from the command line or from within a batch file. In addition, you can automate the solution package creation process from within Microsoft Visual Studio by using a custom post-build event that invokes MakeCAB.exe.

  • Use a Custom Build Target with MSBuild and Visual Studio

    This approach allows you to perform the solution package creation process from within Visual Studio, and offers several benefits over the post-build event approach. There is great information already available on this approach. See the Andrew Connell (Microsoft MVP) visual how-to article Automating Solution Package Creation for Windows SharePoint Services by Using MSBuild and his blog topic Using Visual Studio 2005, MakeCab.exe and MSBuild to Create Windows SharePoint Services 3.0 Solution Files (*WSP's).

    In addition, explore the SPDeploy tool. This tool provides an MSBuild extension and a Visual Studio project template that enables you to create SharePoint customizations inside Visual Studio, and then package and deploy those changes to a remote server running Windows SharePoint Services. For more information, see Introducing SPDeploy.

  • Use a third-party tool.

    Third parties have developed tools that help automate and simplify the solution package creation process. One tool that is available on CodePlex is WSPBuilder. It is a console application that has the ability to create SharePoint solution packages, including the manifest.xml file and DDF file, based on a folder structure that matches the folder layout of the SharePoint installation folder.

Deployment Package Creation Walkthrough

The following section provides a walkthrough that describes the process of creating a SharePoint solution package that you can use to deploy a customized version of the Content Query Web Part (CQWP). The package provisions a customized version of the ItemStyle.xsl style sheet that is used by the Content Query Web Part to render displayed items. It adds a preconfigured version of the Content Query Web Part to the Web Part gallery that uses the custom style sheet, and a custom query to return the content to be displayed. (For additional information about displaying data with the Content Query Web Part, see Display Data From Multiple Lists with the Content Query Web Part.)

The walkthrough in this article focuses on the creation of the solution package instead of the customization of the Content Query Web Part. For more information about customizing the CQWP, see the Microsoft Enterprise Content Management team's blog topic Configuring and Customizing the Content Query Web Part, and another helpful blog topic, Customizing the Content Query Web Part and Custom Item Styles by Heather Solomon. The process of customizing the Content Query Web Part described in these articles is the same process that is used to create the customized version of the Content Query Web Part deployed by the solution package that is described in this article.

Create the Solution Package Folders

The following solution package uses a single SharePoint Feature (for more information, see Working with Features) to provision the two files that make up the customized Content Query Web Part solution. The first step in creating a solution package is to create a folder structure that contains these files and the Feature.xml and manifest.xml files that describe the Feature and solution. To begin, create a folder named Customized CQWP and beneath it, create two subfolders, one named FEATURE and the other named SOLUTION, as shown in Figure 4.

Figure 4. Solution package folder structure

The solution package shown in Figure 4 is not complex and all of its files can be placed in a single folder. However, when you need to create larger and more complex solution packages, it is helpful to place different Feature files and solution resources into multiple folders, so that you can manage the solution package creation process more easily. Notice that if you do place all the sample files provided here into a single folder, you must modify the DDF file so that it reflects the path changes.

Create the Solution Manifest File

The next step is to create the manifest file that describes the solution. Use a text editor to create a text file that contains the following markup.

<Solution SolutionId="<GUID>"
  xmlns="http://schemas.microsoft.com/sharepoint/">
  <FeatureManifests>
    <FeatureManifest Location="MyTasksDueCQWP\Feature.xml" />
  </FeatureManifests>
</Solution>

Replace the <GUID> placeholder string that is used for the SolutionId attribute with an actual GUID. You can create a GUID by using the GUIDGen.exe tool that is provided with Visual Studio. Make sure to select the registry format for the GUID and do not include the opening and closing braces when you paste the GUID into the manifest file. Figure 5 shows the Create GUID dialog box.

Figure 5. Using GUIDGen

The manifest.xml file shown earlier defines a single Feature that is defined by the Feature.xml file, located in the MyTasksDueCQWP folder of the solution package.

Save the file with the name manifest.xml to the SOLUTION folder that you created earlier.

Note

For servers that are running Windows SharePoint Services 3.0 without Service Pack 1 (SP1), the solution package verification process is case-sensitive with regard to the spelling of the manifest.xml file name. You can use uppercase or lowercase letters, but you must spell the file name consistently throughout or the verification process will fail. For servers that are running Windows SharePoint Services 3.0 with SP1, case-sensitivity is no longer an issue.

Create the Feature Files

Your next step is to create the files that describe the Feature that provisions the customized Content Query Web Part. Start by creating a text file that contains the following markup.

<Feature Title="My Tasks Due Pre-Configured CQWP"
         Id="<GUID>"
   Scope="Web"
         Description="Provisions a pre-configured version of the Content Query Web Part that displays the site collection tasks due for the current user."
         Version="1.0.0.0" Scope="Site" Hidden="FALSE"
         DefaultResourceFile="core" xmlns="http://schemas.microsoft.com/sharepoint/">
  <ElementManifests>
    <ElementManifest Location="elementManifest.xml" />
    <ElementFile Location ="MyTasksDueCQWP.webpart" />
    <ElementFile Location ="CustomItemStyle.xsl" />
  </ElementManifests>
</Feature>

Replace the <GUID> placeholder string that was used for the value of the ID attribute with the actual GUID, and then save the file with the name Feature.xml to the FEATURE folder that you created earlier.

The Feature.xml file shown here uses the ElementManifest element to specify that the file named elementManifest.xml contains the details of the Feature. It uses two ElementFile elements to specify the two files that should also be deployed with the Feature.

Next, you need to create the elementManifest.xml file that is referenced by the Feature.xml file. Begin by creating a text file that contains the following markup.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="MyTasksDueCQWP" List="113" Url="_catalogs/wp">
    <File Path="MyTasksDueCQWP.webpart" Url="MyTasksDueCQWP.webpart" Name="MyTasksDueCQWP.webpart" Type="GhostableInLibrary" />
  </Module>
  <Module Name="CustomItemStyle" Url="Style Library/XSL Style Sheets">
    <File Path="CustomItemStyle.xsl" Url="CustomItemStyle.xsl" Name="CustomItemStyle.xsl" Type="GhostableInLibrary" />
  </Module>
</Elements>

The elementManifest.xml file tells Windows SharePoint Services exactly how to deploy the Feature files when the Feature is activated. The first Module element causes the .webpart file for the preconfigured Content Query Web Part to be deployed to the site's Web Part gallery, specified with the URL attribute. The List attribute uses the value 113 to specify that the list is a Web Part gallery list type. This value derives from the Web Part library list template. This template is defined in the global Onet.xml file, which is located by default in the path C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\GLOBAL\XML.

The GhostableInLibrary attribute tells Windows SharePoint Services to create a list item for the file when it is added to the library. The second Module element provisions the CustomItemStyle.xsl style sheet to the XSL Style Sheets library. This style sheet provides a custom style that is used by the preconfigured CQWP. For more information about how to provision a file with the Module element, see How to: Provision a File.

Create the Content Query Customization Files

The next step in the solution package creation process is to create the files that actually customize and preconfigure the Content Query Web Part. Create a text file that contains the following markup.

<webParts>
  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <metaData>
      <type name="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, 
        PublicKeyToken=71e9bce111e9429c" />
      <importErrorMessage>Cannot import this Web Part.</importErrorMessage>
    </metaData>
    <data>
      <properties>
        <property name="Height" type="string" />
        <property name="GroupStyle" type="string">DefaultHeader</property>
        <property name="Description" type="string">Use to display all tasks that are due on the current day</property>
        <property name="Direction" type="direction">NotSet</property>
        <property name="DisplayColumns" type="int">1</property>
        <property name="FilterField2" type="string">{53101f38-dd2e-458c-b245-0c236cc13d1a}</property>
        <property name="TitleUrl" type="string" />
        <property name="DataSourcesString" type="string" />
        <property name="SampleData" type="string">&lt;dsQueryResponse&gt;
                    &lt;Rows&gt;
                        &lt;Row Title="Item 1" LinkUrl="http://Item1" Group="Group Header" __begincolumn="True" __begingroup="True" /&gt;
                        &lt;Row Title="Item 2" LinkUrl="http://Item2" __begincolumn="False" __begingroup="False" /&gt;
                        &lt;Row Title="Item 3" LinkUrl="http://Item3" __begincolumn="False" __begingroup="False" /&gt;
                    &lt;/Rows&gt;
                    &lt;/dsQueryResponse&gt;</property>
        <property name="ViewContentTypeId" type="string" />
        <property name="XslLink" type="string" null="true" />
        <property name="UseCopyUtil" type="bool">True</property>
        <property name="Title" type="string">My Tasks That Are Due</property>
        <property name="ContentTypeName" type="string" />
        <property name="ChromeState" type="chromestate">Normal</property>
        <property name="ItemStyle" type="string">CustomStyle</property>
        <property name="NoDefaultStyle" type="string" null="true" />
        <property name="ViewFieldsOverride" type="string" />
        <property name="GroupByFieldType" type="string" />
        <property name="AllowZoneChange" type="bool">True</property>
        <property name="AllowClose" type="bool">True</property>
        <property name="FilterType3" type="string" />
        <property name="ListName" type="string" />
        <property name="UseCache" type="bool">True</property>
        <property name="ParameterBindings" type="string" null="true" />
        <property name="Hidden" type="bool">False</property>
        <property name="AdditionalGroupAndSortFields" type="string" null="true" />
        <property name="FeedTitle" type="string" />
        <property name="ExportMode" type="exportmode">All</property>
        <property name="HeaderXslLink" type="string" />
        <property name="HelpMode" type="helpmode">Modeless</property>
        <property name="DataColumnRenames" type="string" />
        <property name="Width" type="string" />
        <property name="FeedDescription" type="string" />
        <property name="AllowHide" type="bool">True</property>
        <property name="CatalogIconImageUrl" type="string" />
        <property name="Default" type="string" />
        <property name="FeedEnabled" type="bool">False</property>
        <property name="WebsOverride" type="string" />
        <property name="AllowConnect" type="bool">True</property>
        <property name="HelpUrl" type="string" />
        <property name="ListGuid" type="string" />
        <property name="WebUrl" type="string" />
        <property name="ItemLimit" type="int">15</property>
        <property name="ListsOverride" type="string" />
        <property name="SortByFieldType" type="string">DateTime</property>
        <property name="ShowUntargetedItems" type="bool">False</property>
        <property name="TitleIconImageUrl" type="string" />
        <property name="ViewFlag" type="string" />
        <property name="ChromeType" type="chrometype">TitleOnly</property>
        <property name="FilterValue2" type="string">[Me]</property>
        <property name="Filter1ChainingOperator" type="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+
          FilterChainingOperator, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, 
          PublicKeyToken=71e9bce111e9429c">And</property>
        <property name="Filter2ChainingOperator" type="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+
          FilterChainingOperator, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, 
          PublicKeyToken=71e9bce111e9429c">Or</property>
        <property name="CommonViewFields" type="string">DueDate, DateTime</property>
        <property name="FilterType1" type="string">DateTime</property>
        <property name="GroupBy" type="string" />
        <property name="Xsl" type="string">&lt;xsl:stylesheet 
          xmlns:x="http://www.w3.org/2001/XMLSchema" version="1.0" 
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:cmswrt="http://schemas.microsoft.com/WebPart/v3/Publishing/runtime" exclude-result-prefixes="xsl cmswrt x" &gt; 
          &lt;xsl:import href="/Style Library/XSL Style Sheets/Header.xsl" 
          /&gt; &lt;xsl:import href="/Style Library/XSL Style Sheets/CustomItemStyle.xsl" 
          /&gt; &lt;xsl:import href="/Style Library/XSL Style Sheets/ContentQueryMain.xsl" 
          /&gt; &lt;/xsl:stylesheet&gt;</property>
        <property name="MissingAssembly" type="string">Cannot import this Web Part.</property>
        <property name="FilterOperator1" type="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+
          FilterFieldQueryOperator, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, 
          PublicKeyToken=71e9bce111e9429c">Leq</property>
        <property name="FilterValue3" type="string" />
        <property name="FilterField3" type="string" />
        <property name="AllowEdit" type="bool">True</property>
        <property name="FilterOperator2" type="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+
          FilterFieldQueryOperator, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, 
          PublicKeyToken=71e9bce111e9429c">Eq</property>
        <property name="FilterOperator3" type="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+
          FilterFieldQueryOperator, Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, 
          PublicKeyToken=71e9bce111e9429c">Eq</property>
        <property name="QueryOverride" type="string" />
        <property name="CacheXslTimeOut" type="int">86400</property>
        <property name="MainXslLink" type="string" />
        <property name="FireInitialRow" type="bool">True</property>
        <property name="SortByDirection" type="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+SortDirection, 
          Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">Desc</property>
        <property name="ItemXslLink" type="string">/Style Library/XSL Style Sheets/CustomItemStyle.xsl</property>
        <property name="FilterByAudience" type="bool">False</property>
        <property name="DisplayName" type="string" />
        <property name="ServerTemplate" type="string">107</property>
        <property name="GroupByDirection" type="Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart+SortDirection, 
          Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">Desc</property>
        <property name="FilterValue1" type="string">[Today]</property>
        <property name="ShowWithSampleData" type="bool">False</property>
        <property name="BaseType" type="string" />
        <property name="DataFields" type="string" />
        <property name="UseSQLDataSourcePaging" type="bool">True</property>
        <property name="AdditionalFilterFields" type="string" null="true" />
        <property name="PageSize" type="int">-1</property>
        <property name="FilterType2" type="string">User</property>
        <property name="ContentTypeBeginsWithId" type="string" />
        <property name="DataSourceID" type="string" />
        <property name="SystemViewFields" type="string" />
        <property name="AllowMinimize" type="bool">True</property>
        <property name="FilterField1" type="string">{cd21b4c2-6841-4f9e-a23a-738a65f99889}</property>
        <property name="SortBy" type="string">{8c06beca-0777-48f7-91c7-6da68bc07b69}</property>
        <property name="CacheXslStorage" type="bool">True</property>
      </properties>
    </data>
  </webPart>
</webParts>

Name the file MyTasksDueCQWP.webpart and save it to the FEATURE folder that you created previously.

The MyTasksDueCQWP.webpart file describes the preconfigured Content Query Web Part. The file was created initially by placing an instance of the Content Query Web Part on a Web Part Page, then using the Web Part's tool pane to configure it to query for all task items assigned to the current user and with a due date less than or equal to the current date. It then exports the Web Part to a .webpart file. Figure 6 shows the user interface (UI) for the process of exporting the configured Content Query Web Part.

Figure 6. Exporting the configured Content Query Web Part

The exported .webpart file is then manually edited and the following properties are customized.

<property name="ItemStyle" type="string">CustomStyle</property>

The ItemStyle property tells the Content Query Web Part which item style to use when rendering returned items. The CustomStyle property shown here is defined in the custom XSL style sheet, as shown in the following markup.

<property name="CommonViewFields" type="string">DueDate, DateTime </property>

The CommonViewFields property has been modified to tell the CQWP to include the value of the DueDate column when returning items that match the query.

<property name="ItemXslLink" type="string">/Style Library/XSL Style Sheets/CustomItemStyle.xsl</property>

The ItemXslLink property tells the Content Query Web Part which XSL style sheet to use when rendering returned items. In this case, we are telling it to use our custom style sheet that is shown in the following markup.

To create the custom XSL style sheet, create a text file that contains the following markup.

<xsl:stylesheet 
  version="1.0" 
  exclude-result-prefixes="x d xsl msxsl cmswrt"
  xmlns:x="http://www.w3.org/2001/XMLSchema" 
  xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" 
  xmlns:cmswrt="http://schemas.microsoft.com/WebParts/v3/Publishing/runtime"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
  <xsl:template name="CustomStyle" match="Row[@Style='CustomStyle']" mode="itemstyle">
    <xsl:variable name="SafeImageUrl">
      <xsl:call-template name="OuterTemplate.GetSafeStaticUrl">
        <xsl:with-param name="UrlColumnName" select="'ImageUrl'"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="SafeLinkUrl">
      <xsl:call-template name="OuterTemplate.GetSafeLink">
        <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="DisplayTitle">
      <xsl:call-template name="OuterTemplate.GetTitle">
        <xsl:with-param name="Title" select="@Title"/>
        <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="LinkTarget">
      <xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if>
    </xsl:variable>
    <div id="linkitem" class="item">
      <xsl:if test="string-length($SafeImageUrl) != 0">
        <div class="image-area-left">
          <a href="{$SafeLinkUrl}" target="{$LinkTarget}">
            <img class="image-fixed-width" src="{$SafeImageUrl}" alt="{@ImageUrlAltText}"/>
          </a>
        </div>
      </xsl:if>
      <div class="link-item">
        <xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate"/>
        <a href="{$SafeLinkUrl}" target="{$LinkTarget}" title="{@LinkToolTip}">
          <xsl:value-of select="$DisplayTitle"/>
        </a>
        <div class="description">
          <xsl:value-of select="@DueDate" />
        </div>
      </div>
    </div>
  </xsl:template>
</xsl:stylesheet>

Name the file CustomItemStyle.xsl and save it to the FEATURE folder created previously. The CustomItemStyle.xsl file contains the definition of the custom style that the preconfigured Content Query Web Part uses to render the items that are returned by the query. In this case, the style will cause an item's Title and Due Date to be rendered.

Create the DDF File

Your next step is to create the DDF file. The solution package creation process involves invoking MakeCAB.exe to build the actual solution package file. To create the DDF file to build the customized Content Query Web Part solution, create a text file with the following contents.

.OPTION EXPLICIT ; Generate errors
.Set CabinetNameTemplate=MyTasksDueCQWP.wsp
.Set DiskDirectoryTemplate=CDROM ; All cabinets go in single directory
.Set CompressionType=MSZIP ; All files compressed in cabinet files
.Set UniqueFiles="ON"
.Set Cabinet=on
.Set DiskDirectory1=.

SOLUTION\manifest.xml manifest.xml
FEATURE\Feature.xml MyTasksDueCQWP\Feature.xml
FEATURE\elementManifest.xml MyTasksDueCQWP\elementManifest.xml
FEATURE\MyTasksDueCQWP.webpart MyTasksDueCQWP\MyTasksDueCQWP.webpart
FEATURE\CustomItemStyle.xsl MyTasksDueCQWP\CustomItemStyle.xsl

The DDF file tells MakeCAB.exe to package the solution's manifest, placing it in the root of the solution package, with the files that constitute the customized Content Query Web Part Feature.

Name the file MyTasksDueCQWP.ddf and save it in the customized Content Query Web Part folder that you created earlier.

Create and Deploy the Solution Package

Now you are ready to actually build the solution package. You can do this by invoking MakeCAB.exe on the MyTasksDueCQWP.ddf file. Open a Command Prompt window, navigate to the customized Content Query Web Part folder that contains the DDF file, and execute the following command:

MakeCAB /f MyTasksDueCQWP.ddf

The result should be a SharePoint solution package named MyTasksDueCQWP.wsp that you can use to deploy and activate the Feature that provisions the customized Content Query Web Part.

Add the solution package to a SharePoint server farm solution store by using the following Stsadm.exe command:

Stsadm.exe -o addsolution -filename MyTasksDueCQWP.wsp

Then deploy the package by using the following command:

Stsadm.exe -o deploysolution -name MyTasksDueCQWP.wsp -local

After you have deployed the solution, activate the Feature to a site collection by using the following command; <FeatureGUID> is the Feature ID value from the Feature.xml file and <TargetSiteUrl> is the URL of the site where you want to activate the Feature:

Stsadm.exe -o activatefeature -id <FeatureGUID> -url <TargetSiteUrl>

To help build and deploy your solution package, create a file named Setup.bat that contains the following text. Save this batch file to the customized Content Query Web Part folder that contains the DDF file and the FEATURE and SOLUTION folders that you created earlier.

@rem===================================================================
@rem
@rem    setup.bat
@rem
@rem===================================================================

@echo off
setlocal
pushd .

goto LInitialize

@rem-------------------------------------------------------------------
@rem    LInitialize
@rem-------------------------------------------------------------------

:LInitialize
set SPAdminTool=%CommonProgramFiles%\Microsoft Shared\web server extensions\12\BIN\stsadm.exe
set Install=
set Uninstall=
set PackageFile=MyTasksDueCQWP.wsp
set PackageName=MyTasksDueCQWP.wsp
set DefaultSiteUrl="http://localhost"
set TargetSiteUrl=

goto LParseArgs

@rem-------------------------------------------------------------------
@rem    LParseArgs
@rem-------------------------------------------------------------------

:LParseArgs
@rem --- help ---
if "%1" == "/?"    goto LHelp
if "%1" == "-?"    goto LHelp
if "%1" == "/h"    goto LHelp
if "%1" == "-h"    goto LHelp
if "%1" == "/help" goto LHelp
if "%1" == "-help" goto LHelp

@rem --- Fix execute task ---
if "%1" == "/i"         (set Install=1)   & shift & goto LParseArgs
if "%1" == "-i"         (set Install=1)   & shift & goto LParseArgs
if "%1" == "/install"   (set Install=1)   & shift & goto LParseArgs
if "%1" == "-install"   (set Install=1)   & shift & goto LParseArgs
if "%1" == "/u"         (set Uninstall=1) & shift & goto LParseArgs
if "%1" == "-u"         (set Uninstall=1) & shift & goto LParseArgs
if "%1" == "/uninstall" (set Uninstall=1) & shift & goto LParseArgs
if "%1" == "-uninstall" (set Uninstall=1) & shift & goto LParseArgs

@rem --- Fix url ---
if "%1" == "/siteurl" (set TargetSiteUrl=%2) & shift & shift & goto LParseArgs
if "%1" == "-siteurl" (set TargetSiteUrl=%2) & shift & shift & goto LParseArgs

@rem --- Check invalid arguments ---
if not "%1" == "" (
echo Invalid argument.
goto LHelp
)

@rem --- Check arguments ---
if "%Install%" == "1" (
if "%Uninstall%" == "1" (
goto LHelp
)
)

if "%Install%" == "" (
if "%Uninstall%" == "" (
set Install=1
)
)

if "%TargetSiteUrl%" == "" (
set TargetSiteUrl=%DefaultSiteUrl%
)

goto LMain

@rem-------------------------------------------------------------------
@remLHelp
@rem-------------------------------------------------------------------

:LHelp
echo Usage:
echo setup.bat [/install or /uninstall][/siteurl ^<url^>]
echo           [/help]
echo.
echo Options:
echo  /install or /uninstall
echo  Install specified Solution package (.wsp) to the SharePoint server
echo  or uninstall specified Solution from the SharePoint server.
echo  Default value: install
echo  /siteurl
echo  Specify a site url to install and activate the custom action feature on.
echo  Default value: %DefaultSiteUrl%
echo  /help
echo  Show this information.
echo.

goto LTerminate

@rem-------------------------------------------------------------------
@rem    LMain
@rem-------------------------------------------------------------------

:LMain

if "%Install%" == "1" (
call :LDeploy
)
if "%Uninstall%" == "1" (
call :LRetract
)

goto LTerminate

@rem-------------------------------------------------------------------
@rem    LDeploy
@rem-------------------------------------------------------------------

:LDeploy
echo Building solution package ...
echo.
MakeCAB /f MyTasksDueCQWP.ddf

echo.
    echo Adding solution %PackageName% to SharePoint ...
    "%SPAdminTool%" -o addsolution -filename "%PackageFile%"

    echo Deploying solution %PackageName% ...
"%SPAdminTool%" -o deploysolution -name "%PackageName%" -local

    echo Activating feature Custom CQWP on site %TargetSiteUrl% ...
    "%SPAdminTool%" -o activatefeature -id <FeatureGUID> -url "%TargetSiteUrl%"

    goto :EOF

@rem-------------------------------------------------------------------
@rem    LRetract
@rem-------------------------------------------------------------------

:LRetract
    echo Deactivating feature Custom CQWP on %TargetSiteUrl% ...
    "%SPAdminTool%" -o deactivatefeature -id <FeatureGUID> -url %TargetSiteUrl%

    echo Uninstalling feature Custom CQWP ...
    "%SPAdminTool%" -o uninstallfeature -id <FeatureGUID> -force

    echo Retracting solution %PackageName% ...
"%SPAdminTool%" -o retractsolution -name "%PackageName%" -local

    echo Deleting solution %PackageName% from SharePoint ...
    "%SPAdminTool%" -o deletesolution -name "%PackageName%"

    goto :EOF

@rem-------------------------------------------------------------------
@rem    LTerminate
@rem-------------------------------------------------------------------

:LTerminate
    set UserInput=
    set /P UserInput=Hit enter key to quit.

    set SPAdminTool=
    set PackageFile=
    set PackageName=
    set Install=
    set Uninstall=
    set TargetSiteUrl=
    set UserInput=

popd
endlocal

Be sure to replace the <FeatureGUID> placeholder with the actual GUID for the Feature, which can be found in the solution's Feature.xml file.

After you deploy the solution, the custom XSL style sheet is located in the XSL Style library, as shown in Figure 7.

Figure 7. XSL Style Sheets Library with the new CustomItemStyle sheet

The customized Content Query Web Part .webpart file is located in the Web Part gallery, as shown in Figure 8.

Figure 8. Web Part Gallery showing the new .webpart file

Now you can add the customized, preconfigured Content Query Web Part to a Web Part Page. Figure 9 shows the Add Web Parts --Webpage dialog box.

Figure 9. Adding the preconfigured Content Query Web Part

If the site collection has tasks that are assigned to the current user, the tasks are returned and displayed by the Web Part. Figure 10 shows an example.

Figure 10. Display of assigned tasks

Conclusion

The Windows SharePoint Services 3.0 solution framework supports the process of deploying and managing SharePoint customizations. SharePoint solution packages are .cab files with a .wsp file name extension that contain the Features, files, and other resources that make up a SharePoint solution. The SharePoint solution framework and Feature infrastructure define schemas that support the creation of solution packages. These packages, in turn, can be used to deploy customizations that range from managed code assemblies to Web Parts to custom code access security policies.

Additional Resources

For more information, see the following resources: