Chapter 9. Solution Deployment

This book has shown you how to customize and extend SharePoint using templates, Web Parts, and other techniques. If you wish to move your development efforts to another SharePoint farm, there is a mechanism provided, which enables a smooth transfer and installation—SharePoint solution packages.

In this chapter you'll learn about SharePoint solution packages and features, and how to create them. You will also see how Visual Studio 2010 supports developing for SharePoint 2010. After a deeper look at sandboxed solutions—a new feature of SharePoint 2010—you will learn how to deploy a solution package using stsadm and the new PowerShell cmdlets for SharePoint. If you have created your own solution packages for SharePoint 2007, the last section may be of relevance—it describes how to upgrade your existing solutions to SharePoint 2010, and how to integrate the new features of SharePoint 2010 in your solutions.

At a glance this chapter covers

  • SharePoint solution packages and features

  • An introduction to sandboxed solutions

  • How to create SharePoint solution packages and features

  • How to deploy SharePoint solutions using stsadm and PowerShell cmdlets

  • How to upgrade existing solution packages to SharePoint 2010

SharePoint Features

SharePoint features enable you to deploy applications and functions to a SharePoint site. Features are typically deployed as part of a solution package.

Features can contain templates, list definitions, event handlers, workflows, customizations, and other items. On the front-end web server, each feature is stored in its own subfolder within the folder %SharePointRoot%TEMPLATEFEATURES (see Figure 9-1).

SharePoint's Feature folder

Figure 9.1. SharePoint's Feature folder

When you open a features folder (e.g., ContactsList) in Windows Explorer, you can explore the typical structure of a feature. In the root of a feature is a file named feature.xml, which defines the feature. Listing 9-1 shows a simple example of a feature.xml file.

Example 9.1. Example of a feature.xml File

<?xml version="1.0" encoding="utf-8" ?>
<Feature  xmlns="http://schemas.microsoft.com/sharepoint/"
                   Id="A7CEA23C-A1FD-4c1a-A62E-1F523FBE3D5A"
                   Scope="Web"
                   Title="Msdn Links List"
                   Description="Creates a List for MSDN links"
                   Version="1.0.0.0">
   <ElementManifests>
     <ElementManifest Location="elements.xml"/>
   </ElementManifests>
</Feature>

Table 9-1 describes the elements in this file.

Table 9.1. Elements and Attributes of the feature.xml File

Element or Attribute

Description

Feature

The root node

xmlns

The namespace of the XML

ID

The GUID that identifies the feature in SharePoint

Scope

The scope of the feature (see Table 9-2)

Title

The title of the feature shown in the feature list

Description

Explains what the feature does

Version

The version of the feature

ElementManifests

Node for the referenced elements.xml files

ElementManifest

References an elements.xml file

Location

Defines where the referenced elements.xml (see Listing 9-2) is located

Features can provide their functions to different scopes, as listed in Table 9-2.

Table 9.2. Scopes of a Feature

Scope

Description

Farm

The feature will be available in the entire server farm.

WebApplication

The feature will be available for all web sites in a web application.

Site

The feature will be available for all web sites in a site collection.

Web

The feature will be available on a single web site.

In the feature.xml, another file is referenced in the ElementManifest node: elements.xml.

Listing 9-2 shows an example of an elements.xml file.

Example 9.2. Example of an elements.xml File

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ListInstance
                                Url="Lists/MsdnLinks"
                                Title="MsdnLinks"
TemplateType="103"
                                FeatureId="00BFEA71-2062-426C-90BF-714C59600103"
                                OnQuickLaunch="TRUE"/>
</Elements>

This elements.xml defines a ListInstance for links. When you activate the feature, a new list will be created, as defined in the elements.xml. Table 9-3 explains the nodes and attributes in the example elements.xml:

Table 9.3. Elements and Attributes of the Example elements.xml File

Element or Attribute

Description

Elements

The file's root node

xmlns

The namespace of the XML

ListInstance

A SharePoint item to be deployed through the feature

Url

The URL relative to the URL of the site collection

Title

The title displayed in the UI

TemplateType

The type of ListTemplate (e.g., the value 103 defines a list based on the link list template)

FeatureId

The GUID that identifies the feature containing the template

OnQuickLaunch

Element that, if set to true, displays a link to the list on the Quick Launch menu

The elements.xml file in the example contains the element ListInstance, which creates a new list when you activate the feature. There are many other feature element types you can use. Table 9-4 summarizes the options.

Table 9.4. Feature Element Types

Type

Description

ListTemplate

Specifies a list definition that is available as an option for creating lists

ListInstance

Creates a list instance using a list template

Field

Defines the properties of a site column

ContentType

Defines a content type

Module

Specifies files with which to provision SharePoint web sites within an element manifest

CustomAction

Defines an extension to the UI, such as a button on a ribbon or a link on a site settings page

CustomActionGroup

Contains the core definition for a grouping of custom actions

Receiver

Describes an event receiver for handling list item events

Workflow

Defines a workflow

The section "How To: Creating a Solution Package Step by Step" examines in detail the individual steps required to create a feature. In addition, Chapter 7 includes several examples using the different element types.

Solution Packages

If you create customizations and extensions for SharePoint, there are many items that need to be deployed: assemblies, resource files, features, images, application pages, site definitions, and so on. Imagine a scenario with three systems: development, staging, and production. There needs to be an easy way to deploy these files to the different systems.

SharePoint 2007 introduced solution packages, a powerful deployment tool. Using solution packages enables a developer or SharePoint administrator to transport and install extensions and customizations to other SharePoint servers. Solution packages can be deployed using the command-line tool stsadm or PowerShell cmdlets (see Figure 9-2).

Deploying a solution using PowerShell

Figure 9.2. Deploying a solution using PowerShell

A solution package is stored as a cabinet (CAB) file, with the file extension .wsp. This file contains all the files to be deployed. If you rename the file extension to .cab, you can open the solution and explore its content. Figure 9-3 shows the files and folders of an example WSP solution file.

Example WSP solution package

Figure 9.3. Example WSP solution package

  • In general, a solution package has the following structure, as illustrated in Figure 9-4:

  • A manifest file is in the root, where normally a .NET assembly is located too.

  • Subdirectories contain features, deployment files, definitions, and configurations.

Contents of a SharePoint solution

Figure 9.4. Contents of a SharePoint solution

The structure inside the WSP file defines the final structure in the file system of your SharePoint solution. The manifest file defines the inner structure of the solution. The manifest file is a XML file named manifest.xml. See Listing 9-3 for an example.

Example 9.3. Example of a manifest.xml file

<?xml version="1.0" encoding="utf-8"?>
<Solution
xmlns="http://schemas.microsoft.com/sharepoint/"
SolutionId="c6bee3ac-bc38-48f3-9adf-7a5c8b97eaa7">
  <Assemblies>
    <Assembly
Location="SharePointProject15.dll" DeploymentTarget="GlobalAssemblyCache">
      <SafeControls>
        <SafeControl Assembly="SharePointProject15, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=ce72b677bc54dfc7" Namespace="SharePointProject15.VisualWebPart2" TypeName="*" />
      </SafeControls>
    </Assembly>
  </Assemblies>
  <TemplateFiles>
    <TemplateFile Location="CONTROLTEMPLATESSharePointProject15VisualWebPart2

VisualWebPart2UserControl.ascx" />
  </TemplateFiles>
  <FeatureManifests>
    <FeatureManifest Location="SharePointProject15_WebPartsFeature.xml" />
     </FeatureManifests>
</Solution>

Table 9-5 describes each node of the manifest.xml file shown in Listing 9-3.

Table 9.5. Elements and Attributes of the Example manifest.xml File

Element or Attribute

Description

Solution

Specifies the top-level element for a solution manifest file

xmlns

Specifies the XML namespace

SolutionId

Specifies the GUID of the solution identifying the package in SharePoint

Assemblies

Specifies the assemblies to include in the solution

Assembly

Specifies an assembly to include in the solution

SafeControls

Specifies the safe controls of an assembly that are included in a solution

SafeControl

Adds or removes a control assembly from the safe controls list for a solution

TemplateFiles

Specifies the template files to include in the solution

TemplateFile

Specifies a template file to include in the solution

FeatureManifests

Specifies the features to include in the solution

FeatureManifest

Specifies a feature to include in the solution

Because a solution package is stored as a cabinet file, you can use the utility makecab.exe to create such a cab (WSP) file. A data definition file (DDF) contains the instructions required by makecab to create the WSP file. This includes

  • The name of the WSP file

  • The location of the source files

  • The location of the new WSP file

  • All files that are in the solution package

Listing 9-4 gives an example of a DDF. The comments in the listing explain the usage of the commands.

Example 9.4. An Example DDF

.OPTION EXPLICIT                                    ; Generate errors on variable typos
;
.Set CabinetNameTemplate=MsdnLinkList.wsp ; The name of the WSP file
.set DiskDirectoryTemplate=CDROM                   ; All cabinets go in a single directory
.Set CompressionType=MSZIP                              ;
.Set Cabinet=on                                         ;
.Set Compress=on                                                   ;
.Set DiskDirectory1=.                                ; Use the specified directory for output
;
;*** Disable size limits for wsp (cab) files ;
;
.Set CabinetFileCountThreshold=0
.Set FolderFileCountThreshold=0
.Set FolderSizeThreshold=0
.Set MaxCabinetSize=0
.Set MaxDiskFileCount=0
.Set MaxDiskSize=0
;
;*** Files to zip                                              ;
;
"D:SolutionExample14TEMPLATEFEATURESMsdnLinkListelements.xml" "MsdnLinkListelements.xml"
"D:SolutionExample14TEMPLATEFEATURESMsdnLinkListfeature.xml" "MsdnLinkListfeature.xml"
"D:SolutionExamplemanifest.xml" "manifest.xml"

Solution packages can deploy the following items:

  • Site definitions

  • Feature definitions and their corresponding element definitions and files

  • Web Part files

  • Template files and root files

  • Resource files

  • Assemblies

  • Code access security policies

Farm administrators deploy solution packages to a web server. These solutions have full access to the server object model, and there are no usage limits. SharePoint 2010 introduces an additional type of solution package called sandboxed solution. A sandboxed solution can be deployed by a site collection admin to a site Solution Gallery. These solutions have limited access to the server object model—they can be validated and monitored.

Sandboxed Solutions

Before SharePoint 2010, the farm administrator had to trust custom code running on the server. That meant having to perform lengthy tests and code reviews before custom code was allowed to run on the server, which cost a lot of time and money.

With SharePoint 2010, Microsoft introduced the concept of sandboxing user code, which allows for isolation and resource limitations regarding memory, CPU, database query count, and time. This means that users can add and consume custom solutions safely without impacting overall farm performance and stability. This new solution type addresses key scenarios that include the ability to use custom Web Parts and event receivers.

Sandboxed solutions run with lower trust for hosted environments, for testing foreign solutions, and for secured production servers. A sandboxed solution cannot access the full SharePoint object model; it is limited to a subset of the Microsoft.SharePoint namespace. Sandboxed solutions run in a safe and monitored process with restricted access to resources. A SharePoint admin is enabled to monitor and validate these solutions. Sandboxed solutions address hosted SharePoint solutions, such as SharePoint Online, which is hosted in the cloud. They enable you to extend a hosted SharePoint solution with your own secure code. A SharePoint installation contains a Solution Gallery, which stores sandboxed solutions for further installation and activation. To peruse this gallery, click Site Settings on the Site Actions menu. On the settings page, click Solutions under the Galleries section (see Figure 9-5).

Solution Gallery for sandboxed solutions

Figure 9.5. Solution Gallery for sandboxed solutions

Restrictions of Sandboxed Solutions

You are restricted with regard to the SharePoint items you can deploy with a sandboxed solution and the code you can write in it.

Using a sandboxed solution you can deploy the following SharePoint items:

  • Web Parts (code only; not visual Web Parts)

  • Event receivers

  • Content types

  • List templates

  • List instances

  • Custom actions

  • InfoPath forms

In general, with a sandboxed solution you can't deploy files to disk. This means you can't deploy the following SharePoint items:

  • Visual Web Parts (they contain web controls that have to be deployed to disk)

  • Business data connectivity models

  • Application pages

  • User controls

  • Files included in mapped folders, such as IMAGES or LAYOUTS

You can do the following things with your code in a sandboxed solution:

  • Read and write to lists and libraries within the same site collection

  • Access a large subset of the Microsoft.SharePoint namespace. All the classes below SPSite are available: SPSite, SPWeb, SPList, and SPListItem.

  • Run client-side code (i.e., Silverlight and JavaScript—including usage of jQuery library)

Some aspects of custom code are not allowed in the sandbox:

  • Call web services in an intranet or over the Internet

  • Access data outside the site collection where the solution has been deployed

  • Read and write files with your code

  • Run code that is not marked to allow partially trusted callers (code with restricted rights may call full-trust code if it is marked with the appropriate attribute)

  • Use objects above SPSite (e.g., SPFarm)

  • Use security-related functions (RunWithElevatedPreviledges and other SPSecurity methods)

Tip

For a complete reference to the sandboxed API, see www.microsoft.com/downloads/ details.aspx?FamilyID=f0c9daf3-4c54-45ed-9bde-7b4d83a8f26f&displaylang=en.

The Sandbox Architecture

The structure of a sandboxed solution is very similar to a farm solution. The main differences lie in the way the solution is deployed.

A sandboxed solution can run with full trust when it is deployed as full trust, or with partial trust when the solution is deployed at the site collection scope. Depending on how the solution is deployed, it can be hosted by different services. The Microsoft SharePoint Foundation Sandboxed code execution host service (SPUserCodeV4) executes the user code (code in your sandboxed solution) in the sandbox. This service consists of the following three processes:

  • Microsoft SharePoint Foundation Sandboxed code execution host service (SPUCHostService.exe)

  • Microsoft SharePoint Foundation Sandboxed Code Execution Worker Process (SPUCWorkerProcess.exe)

  • Microsoft SharePoint Foundation Sandboxed Code Execution Worker Process Proxy (SPUCWorkerProcessProxy.exe)

The user code service (SPUCHostService.exe) decides whether you can run sandboxed solutions on the server on which this service is running. Your sandboxed solution code runs in the sandboxed worker process (SPUCWorkerProcess.exe). This is in contrast to having the code of a full-trust solution run inside of w3wp.exe. SPUCWorkerProcessProxy exposes a subset of the SharePoint API. If a method is not exposed, you cannot use it in the sandboxed solutions.

Sandbox architecture

Figure 9.6. Sandbox architecture

Life Cycle of a Sandboxed Solution

The life cycle of a sandboxed solution consists of the following stages: upload, activation, deactivation, and deletion (as shown in Figure 9-7), as well as an optional stage, upgrade.

Life Cycle of a Sandboxed Solution

Figure 9.7. Life Cycle of a Sandboxed Solution

Table 9-6 describes each stage:

Table 9.6. Stages in the Life Cycle of a Sandboxed Solution

Stage

Description

Upload

Uploads the WSP file to the Solution Gallery.

Activate

Validates the selected solution is validated. If this is successful, the solution is activated to run the code it contains and make its features available for activation. Features with a scope of SiteCollection are autoactivated.

Deactivate

Disables the code of the solution and ensures that the contained features are no longer available.

Delete

Removes the solution from the Solution Gallery.

Upgrade

Uses the selected solution to upgrade a previously installed version of the solution that is still active.

To manage sandboxed solutions in your site collection, open the Solution Gallery by clicking Site Settings from the Site Actions menu. Then, on the settings page, click Solutions in the Galleries section, and the Solution Gallery will appear (see Figure 9-5, shown previously). In the Solution Gallery, you can upload, activate, upgrade, deactivate, and delete your solutions.

Deploying a Sandboxed Solution

To upload a WSP file, select the Solution tab and click the Upload button. Choose the location of your file and upload it, as shown in Figure 9-8. The next step is to activate the solution, at which point your solution is validated through the solution validators. Once it is validated, the solution will be activated to run the code that it contains, and the site-scoped features will be activated automatically. (You need to activate web-scoped features on each web site separately.)

Uploading a WSP file to the Solution Gallery

Figure 9.8. Uploading a WSP file to the Solution Gallery

Upgrading a Sandboxed Solution

When you create a new version of an active solution running in your site collection, you can easily upgrade the previous version to the newer one.

For a successful upgrade, two things are important:

  • Both the old and new versions must contain the same solution ID

  • The solution files must have different names, such as solution-v1.wsp and solution-v2.wsp.

If version 1 is active and you upload version 2, SharePoint will recognize the new version of the solution (because both solutions have the same ID, but different hash codes) and ask if you want to upgrade. Alternatively, you can just upload version 2 and choose Upgrade at a later date. Interesting, you can also switch back to version 1 after version 2 has been installed, meaning that you can perform a downgrade as well. When you upgrade a solution, it is validated through the solution validators, too.

Upgrading a solution in the Solution Gallery

Figure 9.9. Upgrading a solution in the Solution Gallery

Note

You can also use PowerShell to manage sandboxed solutions via command-line scripts. For instance, the Add-SPUserSolution cmdlet uploads a new user solution package to the Solution Gallery:

Add-SPUserSolution -LiteralPath C:MySandboxedSolution.wsp -Site http://DemoSite

Unfortunately, stsadm does not support the new sandboxed solutions feature.

Monitoring Sandboxed Solutions

A SharePoint administrator can measure the performance of a sandboxed solution. SharePoint administrators can assign resources with the UI in Central Administration.

You can access the quotas from the Application Management page. In the site collection section, click Configure Quotas and Locks (see Figure 9-10). First, select the site collection you wish to edit. In the site quota section, you can set the user resource quota properties.

Setting site collection quotas and locks for sandboxed solutions

Figure 9.10. Setting site collection quotas and locks for sandboxed solutions

You can limit the site storage and enable a daily resource use limit in points. Points are calculated based on a number of performance indicators such as CPU execution time, memory usage, database query time, abnormal termination, critical exceptions, unhandled exceptions, and data marshalling size. For a detailed view of the performance indicators, enter the command [Microsoft.SharePoint.Administration.SPUserCodeService]::Local.ResourceMeasures at the SharePoint management shell. Alternatively, you can use PowerShell, if you load the SharePoint snap-in (Add-PSSnapin Microsoft.SharePoint.PowerShell) before entering your command (see Figure 9-11).

Getting the local resource measures for sandboxed solutions

Figure 9.11. Getting the local resource measures for sandboxed solutions

This will show the details on each indicator. Table 9-7 lists these performance indicators.

Table 9.7. Performance Indicators

Indicator

Resources per Point

Description

AbnormalProcessTerminationCount

1

Number of abnormally terminated sandboxed solution processes

CPUExecutionTime

3600

Amount of time the CPU spends executing instructions

CriticalExceptionCount

3600

Number of fatal errors

InvocationCount

100

Number of solution invocation events

PercentProcessorTime

85

Percent of CPU usage by solution

ProcessCPUCycles

100000000000

Number of solution CPU cycles

ProcessHandleCount

10000

Number of Windows handles

ProcessIOBytes

10000000

Memory consumed for input/output (I/O)

ProcessThreadCount

10000

Thread count in the overall processes

ProcessVirtualBytes

100000000

Memory consumed

SharePointDatabaseQueryCount

20

Number of SharePoint database queries

SharePointDatabaseQueryTime

120

Elapsed time to execute query

UnhandledExceptionCount

50

Number of unhandled exceptions

UnresponsiveProcessCount

2

Number of unresponsive processes

If a sandboxed solution hits the defined resource limits, it is shut down.

If a special solution uses too many resources or causes too many errors, the SharePoint farm administrator may want to block the solution. In order to block it, go to Central Administration

Performance Indicators

Sandboxed Solution Validators

The monitoring and blocking of a solution is used for already deployed solutions. Another line of defense is the validation of sandboxed solutions before execution.

Farm administrators can deploy solution validators to their farm. These validators always run when a sandboxed solution is activated or upgraded. When a solution fails validation, an error message is shown to the user and the solution is not activated (see Figure 9-12). If a validator is added after solution has been activated, the solution validator will be called the next time the solution is executed. For more information on how to develop and deploy your own validators, see the section "How-to for creating a Sandboxed Solution".

Example of solution validation failure

Figure 9.12. Example of solution validation failure

Sandboxed Solution Full-Trust Proxies

The sandbox provides sufficient functionality for most applications required at a site collection level. But what if you need to perform a function that exceeds the security restrictions of a sandbox? If you want your application to reach outside the sandbox for such operations as web service calls and database access, you have the option of creating a full-trust proxy.

A full-trust proxy enables you to extend the boundaries of a sandboxed solution when necessary. It is a special class library that's deployed to the GAC and runs under full trust.

Since the assembly runs under full trust, you can create a proxy operation that calls a web service or has access to other data sources that are not accessible for a sandboxed solution. Your proxy exposes a method that can be called by the sandboxed user code to perform a specific task, such as reading data from data sources outside the site collection of your sandboxed solution.

The purpose of a full-trust proxy is to break your architecture down into two major pieces:

  • One part that runs completely as a sandboxed solution (limited by the sandbox to the usual list definitions, fields, content types, Web Parts, and so forth).

  • A custom API you build using full-trust proxies that the sandbox solutions can use (providing access to web services and other data, and permitted to use the full SharePoint API).

Figure 9-13 illustrates this architecture.

Full-Trust Proxies API Architecture

Figure 9.13. Full-Trust Proxies API Architecture

Using Full-trust proxies, you weaken slightly the security of sandboxed solutions, but you still have much more control over the called code than you do with normal full-trust solutions.

Warning

The proxy has to be registered by a farm administrator and is accessible to the whole farm, which means that all developers who know about the assembly, class, and method can use the method. You need to be cognizant of this when considering the methods to expose in the proxy. Try to keep them to a minimum.

You can write your own full-trust proxies by creating one or two class libraries containing the following classes:

  • A class that inherits from Microsoft.SharePoint.UserCode.SPProxyOperation: This class will be used to execute operations that are normally disqualified for sandboxed solutions.

  • A second class that inherits from Microsoft.SharePoint.UserCode.SPProxyOperationsArgs: This class will be passed to the Execute method of the SPProxyOperation class.

Both classes have to be deployed to the GAC and registered in SharePoint.

Then you can call the class that inherits from SPProxyOperation from your sandboxed code.

Figure 9-14 illustrates this approach.

Tip

Create your full-trust proxies as farm solutions, which are registered using feature activation and unregistered using deactivation of the feature. Then the farm administrators can enable and disable them.

Full-trust proxy architecture

Figure 9.14. Full-trust proxy architecture

Later, in the section "Creating a Sandboxed Solution using Visual Studio 2010," you will learn how to construct such a full-trust proxy.

Deploying Solution Packages Using PowerShell Cmdlets

Windows PowerShell is the command-line interface and scripting language that was developed specifically for system administration and is used for SharePoint 2010 administration (see Figure 9-15).

With Windows PowerShell, administrators have a powerful tool for scripting and shell administration. PowerShell follows a completely new paradigm as compared to other shells like bash or cmd.exe. While those shells accept and return text, Windows PowerShell uses .NET objects as input and output, since it is based on an object model supported by the .NET Common Language Runtime (CLR). This is an immense change that offers more control, efficiency, and productivity to developers and administrators.

Adding a solution using Windows PowerShell

Figure 9.15. Adding a solution using Windows PowerShell

Cmdlets

Windows PowerShell introduces the concept of cmdlets (aka commandlets). A cmdlet is a simple command-line tool that is integrated into the shell and executes a single function. You can use a single cmdlet, but their power is more obvious when used together to perform complex tasks or automated administration.

PowerShell comes with a large collection of built-in cmdlets. A cmdlet is a simple command used for interaction with a managed application (including the operating system). PowerShell runs cmdlets as instances of .NET classes focused on the simple cmdlet model. Cmdlets return objects instead of text. The output can be forwarded (piped) to other cmdlets. This way you can combine cmdlets. You provide the parameters, validate the values, and set details for objects and layout; and PowerShell does the remaining work—parsing parameters, binding values, and formatting and displaying the output. You can create your own cmdlets and share them with others as needed.

Tip

For more information about developing custom cmdlets, visit http://msdn.microsoft.com/en-us/magazine/cc163293.aspx.

An Interactive Environment

Windows PowerShell supports a completely interactive environment, similar to other shells. If you enter a command at the input prompt, the command will be processed and the output displayed in the shell window. You can send the output from a command to a file or printer, or you can use a pipe operator (|) to send it to another command. For example, you can use the command Get-Command -Noun SP* to get all commands containing a noun starting with SP. Then you can use the pipe operator to send it to the cmdlet measure-object to count the number of search results.

The PowerShell Scripting Language

A new language, the PowerShell scripting language, has been introduced for PowerShell for the following reasons:

  • Windows PowerShell needed a language to manage .NET objects

  • The language had to support complex tasks

  • The language had to meet the conventions for other languages used in .NET programming, such as C#

Scripting with PowerShell and the PowerShell Integrated Scripting Environment

If you repeat the same commands frequently, it is useful to save the commands in a file and execute the file. Such a file is called a script.

Windows PowerShell offers complete script support. You can run a script by entering the name of the script at the prompt. The file extension for PowerShell scripts is .ps1.

Although scripts are very useful, they can also be used to spread harmful code. Execution policies in PowerShell specify which scripts may be run and whether they must be digitally signed. For security reasons, PowerShell does not allow you to execute a script by double-clicking the file, as you can with .bat or .vbs files.

For scripting purposes, PowerShell 2.0 comes with the PowerShell Integrated Scripting Environment (ISE). This application enables you to run commands, and write, test, and debug scripts in a user-friendly environment. ISE is a WPF application and requires .NET 3.5.

ISE offers the following:

  • A command pane for running interactive commands, just as in the Windows PowerShell console. Simply type a command and press Enter, and the output will appear in a separate output pane.

  • A script pane to compose, edit, debug, and run functions and scripts.

  • Multiple tabs, each with its own command and script pane to allow you to work on several tasks independently.

  • The ability to edit text in complex scripts.

  • The ability to extend every aspect of ISE through its underlying scripting object model with your own code.

  • Separate profiles. You can create a PowerShell profile and add aliases, functions, and variables to it. Every time PowerShell starts, these settings are loaded.

PowerShell ISE

Figure 9.16. PowerShell ISE

PowerShell and SharePoint 2010

To start administering SharePoint 2010 with PowerShell, launch the SharePoint 2010 management shell (see Figure 9-17) from the Start menu, under All Programs

PowerShell and SharePoint 2010
Starting the SharePoint 4.0 management shell

Figure 9.17. Starting the SharePoint 4.0 management shell

The management shell is actually just a PowerShell console that preloads the SharePoint PowerShell snap-in. When you look at the target for the shortcut, you should see the following:

C:WindowsSystem32WindowsPowerShellv1.0PowerShell.exe -NoExit  "
& ' C:Program FilesCommon FilesMicrosoft SharedWeb Server
Extensions14CONFIGPOWERSHELLRegistration\sharepoint.ps1 ' "

A peek inside the SharePoint.ps1 file (see Figure 9-18) reveals the secret:

SharePoint.ps1

Figure 9.18. SharePoint.ps1

The SharePoint.ps1 script runs the Add-PsSnapin cmdlet to load the new SharePoint 2010 cmdlets, as shown in Figure 9-19. It also changes the threading model of PowerShell so that commands are processed in the same thread. This is important for the disposal of disposable objects, which is important when you are working with SharePoint objects such as SPWeb. Knowing the sharePoint.ps1 script and its contents, you can easily load any PowerShell console (i.e., either the native PowerShell console or another editor such as the PowerShell ISE) and administer SharePoint 2010. To do so, run the sharepoint.ps1 script or enter the following commands:

$ver = $host | select version
if ($ver.Version.Major -gt 1)  {$Host.Runspace.ThreadOptions = "ReuseThread"}
Add-PsSnapin Microsoft.SharePoint.PowerShell
Set-location $home

PowerShell Cmdlets for SharePoint 2010 Overview

SharePoint ships with hundreds of SharePoint PowerShell commands out of the box. To compile a list of these cmdlets, enter the following at the shell:

Get-Command -PSSnapin Microsoft.SharePoint.PowerShell | select Name

This command returns the names of all the installed SharePoint PowerShell cmdlets. As usual, the naming convention for the commands is: [Verb]-SP[Noun]. To obtain the exact number of cmdlets, use the following command:

Get-Command -PSSnapin Microsoft.SharePoint.PowerShell | measure-object
Getting a list of SharePoint cmdlets in PowerShell

Figure 9.19. Getting a list of SharePoint cmdlets in PowerShell

Note

In order to use PowerShell for SharePoint operations, you need to be a site collection administrator and a db_owner of the content database.

Getting Help: What Are Cmdlets Good For?

If you want to get more information about a cmdlet, you can use the built-in help:

Get-Help <cmdlet>

To get more information, add the parameters –full or –detailed (see Figure 9-20).

A summary of the Get-Help command

Figure 9.20. A summary of the Get-Help command

Deploying a Farm Solution Package

To deploy a farm solution, you first need to upload the solution to the farm. This is accomplished with the Add-SPSolution cmdlet:

Add-SPSolution -LiteralPath C:MySolution.wsp

Now the solution package is in the solution store of the farm, but it is not yet deployed. To deploy it, execute the command as shown in Figure 9-21:

Install-SPSolution -Identity MySolution.wsp -GACDeployment

Eventually it will become necessary to remove the solution from the farm. To achieve this, you will have to first have to uninstall the solution:

Uninstall-SPSolution -Identity SolutionName

Then you can remove the solution:

Remove-SPSolution -Identity SolutionName

This deletes the solution package from the solution store.

Installing a solution using PowerShell

Figure 9.21. Installing a solution using PowerShell

Deploying a Sandboxed Solution using PowerShell

As an alternative to using stsadm, you can use SharePoint PowerShell cmdlets for sandboxed solution deployment.

You can use the Add-SPUserSolution cmdlet to upload a new user solution package to the Solution Gallery as follows:

Add-SPUserSolution -LiteralPath C:MySandboxedSolution.wsp -Site http://DemoSite

However, this cmdlet does not activate the uploaded user solution. Use the Install-SPUserSolution cmdlet to activate the user solution in the site collection, like this:

Install-SPUserSolution -Identity MySandboxedSolution -Site http://DemoSite

The Install-SPUserSolution cmdlet activates a user solution in a site collection.

If you have to remove a solution from the Solution Gallery, the user solution must be inactive. To handle this, you can use the Uninstall-SPUserSolution cmdlet, which deactivates a user solution on a site collection. It also removes the included features from the site collection features.

You can use the Remove-SPUserSolution cmdlet to remove a user solution from the Solution Gallery as follows:

Remove-SPUserSolution -Identity MySandboxedSolution.wsp -Site sitename

Deploying Solution Packages Using stsadm

After creating a WSP solution package file, you can deploy it onto a SharePoint server. One option for this task is the command-line tool stsadm.

By default you can find the SharePoint admin tool stsadm.exe in the folder %SharePointRoot%Bin. stsadm enables a SharePoint administrator to manage administrative tasks for SharePoint via the command line and write batch files and scripts for these tasks. stsadm offers access to operations and parameters that are not accessible via Central Administration. Important examples of this are the following operations:

  • addcontentdb

  • addsolution

  • upgradesolution

  • setadminport

  • renameserver

There are two major requirements for running stsadm:

  • You must run stsadm on the server you are managing.

  • You have to be a member of the local group Administrators.

Note

If you are already familiar with stsadm and like it, you can continue using it for SharePoint 2010. But note that since Microsoft's introduction of the new PowerShell cmdlets for SharePoint administration, stsadm exists only for backward compatibility.

Adding a Solution Package

To deploy a solution package, you need to add the WSP file to the configuration database. You can do this with the stsadm operation addsolution:

stsadm -o addsolution -filename C:MySolution.wsp

This command adds the solution to the configuration database, but does not deploy it. To deploy the solution package, you have to execute the deploysolution command:

stsadm -o deploysolution -name MySolution.wsp -immediate -allowGacDeployment -force

When you issue deployment commands to stsadm, these commands are executed asynchronously via a timer job. This way, solution packages can be deployed to several servers in a farm. After the deployment of a solution, SharePoint forces a reset of IIS. Because this causes problems when the server is used, you can set a parameter to schedule the deployment for a period when demand is low (such as nighttime). If you create a deployment script, you may prefer to run the tasks synchronously, such as addsolution and deploysolution. To do this, you can use the command execadmsvcjobs. This command executes all commands immediately instead of waiting for execution by the timer job, as shown in Listing 9-5 and Figure 9-22.

Example 9.5. Adding and Deploying a Solution

SET STSADM="C:Program FilesCommon FilesMicrosoft Sharedweb server extensions14BINstsadm.exe"
%STSADM% -o addsolution -filename c: MySolution.wsp
%STSADM% -o execadmscvjobs
%STSADM% -o deploysolution -name MySolution.wsp -immediate -allowGacDeployment -force
%STSADM% -o execadmscvjobs
Deploying a solution using stsadm

Figure 9.22. Deploying a solution using stsadm

Removing Solutions

Particularly during development, but also for normal deployments, it can become necessary to remove a deployed solution. You can achieve this with the stsadm operations retractsolution and deletesolution, as shown in Listing 9-6.

Example 9.6. Removing a solution

SET STSADM="C:Program FilesCommon FilesMicrosoft Sharedweb server extensions14BINstsadm.exe"
%STSADM% -o retractsolution -name MySolution.wsp -immediate
%STSADM% -o execadmscvjobs
%STSADM% -o deletesolution -name MySolution.wsp -override
%STSADM% -o execadmsvcjobs

Installing Features

When deploying the solution package the included features are installed, too. However, you have to activate the features in a separate step. To do this, execute the activatefeature operation of stsadm, as follows:

stsadm -o activatefeature

You can also install a feature without activating it, as follows:

stsadm -o installfeature

Tip

See http://technet.microsoft.com/en-us/library/cc263384.aspx for a complete reference for stsadm operations and properties.

Creating a Solution Package Step by Step

The following example shows the steps needed to build a solution package. This example creates a simple solution package for deploying a feature that creates a list called MsdnLinks, which contains interesting MSDN links.

Note

Visual Studio is not used for this example. Since Visual Studio generates many XML files in the background, it can be difficult to understand in detail how it actually creates a solution package. Instead, in this example, every step is performed manually so that you can better understand what happens. This example is designed to show you the individual steps required to assemble a solution package.

List for MSDN links

Figure 9.23. List for MSDN links

Step 1: Creating the Folder Structure

Begin by constructing a folder structure in a working folder, as shown in Figure 9-24. This structure should be similar to the structure of the SharePoint folders in %SharePoint Root%.

Folder structure for the example solution

Figure 9.24. Folder structure for the example solution

Step 2: Building the Feature

The list for the MSDN links will be created when you activate the MsdnLinks list. To do this, you must first build a feature that creates a list based on the SharePoint list type linksList (TemplateType="103").

Go to the MsdnLinksList folder and create two XML files: feature.xml and element.xml. feature.xml is the main file (see Listing 9-7). The attribute ID contains a unique GUID, which identifies the feature in the farm. The Scope attribute specifies the level at which you can activate and use the feature. In this case it is Web, for deployment on a single web site. feature.xml references the element manifest file (see Listing 9-8) containing the real function of the feature.

Example 9.7. feature.xml

<?xml version="1.0" encoding="utf-8" ?>
<Feature
                xmlns="http://schemas.microsoft.com/sharepoint/"
                Id="A7CEA23C-A1FD-4c1a-A62E-1F523FBE3D5A"
                Scope="Web"
                Title="Msdn Links List"
                Description="Creates a List for MSDN links"
                Version="1.0.0.0">
                <ElementManifests>
                                <ElementManifest Location="elements.xml"/>
                </ElementManifests>
</Feature>

Tip

SharePoint uses GUIDs to identify features, solutions, and so forth. To this end, the GUID generator tool in the Windows SDK is very useful for creating valid GUIDs (see Figure 9-25). Always click New GUID to be sure the GUID is really unique.

GUID generator

Figure 9.25. GUID generator

In our example, the element manifest forces SharePoint to create a new link list called MsdnLinks. The attributes TemplateType and FeatureID point to the link list that is the template for the list. Setting the attribute OnQuickLaunch to true makes the list visible in the Quick Launch menu of your web site.

Example 9.8. elements.xml

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ListInstance
                                Url="Lists/MsdnLinks"
                                Title="MsdnLinks"
                                TemplateType="103"
                                FeatureId="00BFEA71-2062-426C-90BF-714C59600103"
                                OnQuickLaunch="TRUE"/>
</Elements>

Step 3: Creating a Solution Definition

After you've built the feature, you can create the manifest.xml file in the SolutionExample folder. The manifest.xml file (see Listing 9-9) is an installation instruction for SharePoint. It informs SharePoint how to use and where to install the files contained in the solution package. The ID of the solution identifies your solution package as unique in SharePoint.

In this example, the feature manifest references the feature.xml file to deploy the new feature.

Example 9.9. manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<Solution
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.microsoft.com/sharepoint/"
SolutionId="05FB6131-4714-403b-B3AA-C73C5C535AC3">
  <FeatureManifests>
    <FeatureManifest Location="MsdnLinkListfeature.xml" />
  </FeatureManifests>
 </Solution>

Step 4: Creating a DDF

The next step is to write the SolutionExample.ddf file (see Listing 9-10) in the SolutionExample folder. This file contains all the instructions for makecab.exe to create your WSP file.

Example 9.10. The DDF

.OPTION EXPLICIT                                     ; Generate errors on variable typos
;
.Set CabinetNameTemplate=MsdnLinkList.wsp  ; The name of the WSP file
.set DiskDirectoryTemplate=CDROM                    ; All cabinets go in a single directory
.Set CompressionType=MSZIP                               ;
.Set Cabinet=on                            ;
.Set Compress=on                                                    ;
.Set DiskDirectory1=.                                 ; Use the specified directory for output
;
;*** Disable size limits for wsp (cab) files ;
;
.Set CabinetFileCountThreshold=0
.Set FolderFileCountThreshold=0
.Set FolderSizeThreshold=0
.Set MaxCabinetSize=0
.Set MaxDiskFileCount=0
.Set MaxDiskSize=0
;
;*** Files to zip                                              ;
;
"D:SolutionExample14TEMPLATEFEATURESMsdnLinkListelements.xml" "MsdnLinkListelements.xml"
"D:SolutionExample14TEMPLATEFEATURESMsdnLinkListfeature.xml" "MsdnLinkListfeature.xml"
"D:SolutionExamplemanifest.xml" "manifest.xml"

Step 5: Creating the Solution Package

Now you have created all the files to build the solution package. To create the CAB-based solution package, run the command-line tool makecab.exe.

The DDF is needed for the creation of the WSP file using makecab.

At the command line, enter the following command to create the WSP:

makecab -f SolutionExample.ddf

MakeCAB generates three files:

  • setup.rpt

  • setup.inf

  • MsdnLinkList.wsp

The setup.rpt file contains information about the total files included in the WSP file, how much data was compressed, and the time taken to compress the data. The setup.inf file contains information about the cabinet file that was created, and also contains a list of the files included in the WSP file. The MsdnLinkList.wsp file the your solution package you can deploy to SharePoint. The setup.rpt and setup.inf files are not important for your solution package, so you can delete them.

To make the MakeCAB step easier and repeatable, write a batch file, as shown in Listing 9-11.

Example 9.11. MakeCAB.bat

makecab -f makecab.ddf
del setup.inf
del setup.rpt
pause

The output is shown in Figure 9-26.

The MakeCAB tool creates the WSP file.

Figure 9.26. The MakeCAB tool creates the WSP file.

The WSP file MsdnLinkList.wsp should now exist in the SolutionExample folder. Now the solution package is ready for deployment using stsadm or PowerShell cmdlets.

How To: Creating a Solution Package Using Visual Studio 2010

The previous example outlined the necessary steps to create a solution package. However, if you want to create a solution package containing many features, assemblies, and so on, this process will become quite complex and difficult. Therefore, Visual Studio 2010 aids the developer in building flexible SharePoint solution packages.

Using the Project Templates

You can easily start assembling SharePoint solutions using Visual Studio 2010, provided that you have set up a SharePoint 2010 development environment with the following:

  • A 64-bit operating system (Windows Server 2008, Windows 7, or Windows Vista)

  • SharePoint Foundation or SharePoint Server 2010

  • Visual Studio 2010

Start Visual Studio 2010 and create a new project. Visual Studio 2010 includes many project templates for SharePoint solutions, as shown in Figure 9-27. The result of every project template is a WSP solution package. In this example, choose the Empty SharePoint Project template. Set the name, location, and solution name of your project and click OK. This starts the SharePoint Customization wizard, as shown in Figure 9-28.

SharePoint project templates in Visual Studio 2010

Figure 9.27. SharePoint project templates in Visual Studio 2010

Site and Security Level for Debugging

The wizard (Figure 9-28) asks for the URL of a SharePoint you can use for debugging your new solution. By default, Visual Studio proposes your local SharePoint installation. Click Validate to check that the URL is valid and the SharePoint site is available.

The security level for your solution is also configurable. In this instance, choose "Deploy as a farm solution," and click Finish to initialize your project in Visual Studio.

The SharePoint Customization wizard

Figure 9.28. The SharePoint Customization wizard

Adding SharePoint Items and Features to Your Project

Once the project is established, you will see its predefined structure—there is a folder for the features and one for the package (see Figure 9-29).

The project structure in Solution Explorer

Figure 9.29. The project structure in Solution Explorer

You can extend your project with

  • SharePoint items, such as Web Parts and list definitions

  • Mapped folders, such as layouts (for application pages and more) and images

  • Additional features and feature receivers

To add a new SharePoint item, right-click the Project and choose Add

The project structure in Solution Explorer
Adding a new item

Figure 9.30. Adding a new item

Add two more Web Parts using the same approach. Now you should have three Web Parts in your project.

Each Web Part has its own folder. A feature named Feature 1 was automatically created when you added the first Web Part, and all subsequent SharePoint items were added to this feature. (For more information about using the different SharePoint items in your project, review Chapter 7.)

Perhaps you would prefer to use more than one feature to deploy your SharePoint items, though. You can add a new feature by right-clicking the features folder and selecting Add Feature. When you right-clicking the features folder, you can add an event receiver or resource to the feature (as explained in Chapter 3).

The name Feature 1 doesn't provide much information about the content of a features folder. Right-click the Feature 1 folder, choose Rename, and enter a more descriptive name, such as MyWebPartsFeature.

Editing Your Features

Double-click a features folder to open the Feature Designer, as illustrated in Figure 9-31. In the Feature Designer are three zones: the header, a middle part, and the footer. In the header you can edit the following general information:

  • The title and description of your feature, which are displayed in the feature administration.

  • The scope of your feature. Depending on the scope, you can see the appropriate SharePoint items in your solution.

In the center pane of the Feature Designer you can add items to or remove items from your feature. In the footer are advanced options—here you can specify a list of features on which the activation of the current feature depends. Clicking the + to the left of Feature Activation Dependencies opens a menu to define these. Click Add to add a dependency. You can choose a dependency on a feature in your solution, or add a custom feature activation dependency by entering the title, feature ID, and description. In the dependency list you can select a dependency and remove it. If it is a custom one, you can also edit it. If you want to look behind the scenes, you can switch from design view to manifest view. Here you'll see a preview of the generated manifest, and you'll have the opportunity to edit the template for the generated manifest. Advanced users can ignore the generated XML and edit the manifest directly in the XML editor, as shown in the following exercise.

To edit the next feature, double-click the next features folder in Solution Explorer, or double-click the feature in the Packaging Explorer next to the Feature Designer (see Figure 9-31).

Feature Designer and Packaging Explorer

Figure 9.31. Feature Designer and Packaging Explorer

If the Feature Designer is enabled, you can also edit the feature properties when you opened the designer. In the Property window you can edit the Properties shown in Table 9-8. If the window is not open, press F4 to display it.

Table 9.8. Feature Properties

Property

Description

Activate on Default

Indicates whether the feature is activated during installation.

Always Force Install

Indicates whether the feature should be installed by force, even if the feature is already installed.

Auto Activate in Central Admin

Indicates whether the feature is activated by default for administrators.

Creator

The developer who created the feature.

Default Resource File

The central resource file for retrieving feature resources.

Deployment Path

The path within the package to which the feature will be deployed.

Description

Indicates what the feature does.

Feature Id

The SharePoint ID of the feature.

Image Alt Text

The text for the image associated with the feature.

Image Url

The relative URL of the image associated with the feature.

Is Hidden

Indicates whether the feature is visible in the list of available features to activate.

Receiver Assembly

The fully qualified name of the assembly that contains the event receiver for the feature.

Receiver Class

The class name of the event receiver for the feature.

Require Resources

Indicates whether SharePoint checks for resources for a particular language and culture.

Scope

The context in which a feature is activated.

Solution Id

Specifies the ID of the SharePoint server where the feature will be installed (Microsoft internal use only)

Title

The title of the feature (limited to 255 characters)

UIVersion

Specifies a string that indicates the compatible versions of the site.

Upgrade Actions Receiver Assembly

The fully qualified name of the assembly containing the feature event receiver that handles custom upgrade actions.

Upgrade Actions Receiver Class

The class name of the feature event receiver that handles custom upgrade actions.

Version

Specifies a System.Version–compliant representation of the version of the feature. This can be up to four numbers delimited by decimal points.

Editing Your Solution Package

When you double-click the root node in the Packaging Explorer or the package folder in Solution Explorer, you open the designer for your package, as shown in Figure 9-32.

Here you can enter the name of your package (WSP) file and force a reset of the web server after deployment. As described previously, from the Feature Designer you can assign items in your solution such as mapped folders and features to your package.

Editing your solution in the package designer

Figure 9.32. Editing your solution in the package designer

At the bottom of the designer are three buttons: Design, Advanced, and Manifest.

From the Advanced menu, you can add, edit, or delete additional assemblies, as shown in Figure 9-33. You have to decide whether to deploy the assembly to the GAC or the bin folder of the web application. Here you can also add safe controls and class resources.

When you click the Manifest button, you can preview the generated manifest, edit the template, or edit the complete manifest. You should be familiar with this procedure from the Feature Designer. You can also edit the manifest manually, as described in the previous exercise. If the package designer is enabled, you can also edit the package properties when you open the designer. In the Properties window (which you can open by pressing F4), you can edit the properties shown in Table 9-9.

Table 9.9. Package Properties

Property

Description

Deployment Server Type

The type of server that will host the package: WebFrontEnd or ApplicationServer

Description

The description of the package

Name

The name of the package (WSP) file

Receiver Assembly

The fully qualified name of the assembly that contains the event receiver for the package

Receiver Class

The class name of the event receiver for the package

Reset Web Server

Indicates whether IIS will be restarted after installing the package

Reset Web Server Mode On Upgrade

Indicates how IIS will be restarted after upgrading the package: StartStop or Recycle

Solution Id

The ID of the package

Title

The title of the package

Adding assemblies in the package designer

Figure 9.33. Adding assemblies in the package designer

Project Properties and Deployment Configuration

To set the project properties, select the project's root node in Solution Explorer, right-click, and select Properties. Alternatively, you can select the node and press Alt+Enter. You should be familiar with most of the tabs, except the new SharePoint tab. Select this tab now. As shown in Figure 9-34, you can enter pre- and post-commands to run on the command line—these include commands to copy files, start or stop services, and force an iisreset call. More interesting is the Active Deployment Configuration selection. Out of the box, Visual Studio comes with two configuration options: Default and No Activation. Select an entry and click View to explore these configurations.

Deployment configuration

Figure 9.34. Deployment configuration

The No Activation deployment configuration executes the following steps:

  • Running the predeployment command line

  • Packaging the WSP file

  • Recycling the application pool (if you're deploying a full-trust solution)

  • Retracting the previous version of the solution

  • Adding the solution

  • Running the postdeployment command line

The Default configuration does the same and also activates all features.

If you don't want to use the existing static configurations, click New to add your own deployment configuration. In general, the build and package steps are performed before every configuration—you can't edit this. Table 9-10 lists the available deployment and retraction steps. Using the pre- and postdeployment commands, you can extend these steps with your own custom actions. If this is insufficient, you can develop your own steps and add them using Visual Studio Extensions.

Tip

If you want to create your own deployment steps, there is a helpful walkthrough on MSDN at http://msdn.microsoft.com/en-us/library/ee256698(VS.100).aspx.

Table 9.10. Available Deployment and Retraction Steps for Deployment Configuration

Step

Description

Run Pre-Deployment Command

Runs any specified commands before the deployment starts

Run Post-Deployment Command

Runs any specified commands after the deployment ends

Recycle IIS Application Pool

Recycles the application pool of your SharePoint web application in IIS

Retract Solution

Retracts a previously installed version of your solution by deactivating, retracting, and deleting it from the local SharePoint site

Add Solution

Adds and installs your solution to the local SharePoint site

Activate Features

Activates all features in your solution for the local SharePoint site

In the Properties window you can also set some properties for your project. Here you can choose the active deployment configuration, too. Other properties you can edit include

  • Assembly deployment target: GAC or bin folder

  • Include assembly in package

  • Startup item

Do you recall the wizard at the beginning of the How-To where you specified the local site for debugging and where you decided whether you want to deploy the solution as full trust or sandboxed? Here in the Properties window you can also change those settings.

Debugging the Solution

To debug, press F5, click the Debug button, or click Debug on the build menu. This will build your project. Once the build has completed, the solution package will be created and deployed onto your development SharePoint site. You set the URL of this server in the wizard at the beginning of the project or in the project Properties window. You can follow the process in the Output window of Visual Studio.

Visual Studio will start Internet Explorer, which loads the URL of your SharePoint for debugging. You can now test your newly developed features inside SharePoint. The debugger is automatically attached to the IIS process w3wp.exe and Internet Explorer so that you can debug your solution. Your deployment configuration affects whether all features are activated by default, or whether you have to activate them manually. If you want to debug your code in a feature receiver when a feature is activated, set a breakpoint on the relevant line. When the feature is activated, the debugger will stop at this breakpoint. If you want to debug code that is already deployed, you can similarly set a breakpoint, and then click Attach to Process in the Tools menu of Visual Studio. Then select the w3wp.exe process to debug your solution in SharePoint, as shown in Figure 9-35.

Attach to the w3wp process to debug your code for SharePoint

Figure 9.35. Attach to the w3wp process to debug your code for SharePoint

Packaging the Solution

To provide the solution package for deployment on other systems, you need to pass the newly generated WSP file to these systems.

In the debugging process, you have already created a solution file. Examine the Output window or the project properties output path to find the location of the file. Alternatively, you can force Visual Studio to create a solution package. To do so right-click the project and click Package, or click Package in the build menu. If you want the WSP file copied to a special folder, you can change the output path in the build settings, or better still, insert a copy command as a predeployment command line in the SharePoint tab of your project properties:

xcopy "$(TargetDir)*.wsp" C:Solutions /Y

To customize this packaging step further, you can define your own deployment configuration (as described previously in the "Project Properties and Deployment Configuration" section). The solution package is now ready for deployment using stsadm, PowerShell cmdlets, or the object model.

How To: Creating a Sandboxed Solution Using Visual Studio 2010

When you create a new SharePoint 2010 Project in Visual Studio 2010, the wizard will ask whether you want to create a sandboxed solution or a full-trust solution.

By default, Sandboxed is selected if the type of solution can be deployed as sandboxed.

You can also set this project property later, in the project properties window (see Figure 9-36).

Project properties

Figure 9.36. Project properties

While developing your sandboxed solution, remember the restrictions mentioned earlier. Visual Studio supports the writing valid code for sandboxed solutions by filtering IntelliSense.

Tip

Visual Studio compiles your code against the full version of SharePoint API, but at runtime your code runs against the reduced, sandboxed API. To ensure that your solution only contains valid code for a sandboxed solution you can use a workaround for compile-time checking: delete the Microsoft.SharePoint.dll reference on [SharePoint Root]UserCodeassembliesMicrosoft.SharePoint.dll. However, please note that this workaround is only for checking; remember to reset the reference when building the solution package for deployment.

To create your first sandboxed solution, choose the Empty SharePoint Project template in Visual Studio 2010. Set the name to, say, SandboxedWebPart and the solution name to SandboxedSolutionDemo. Next, choose "deploy as sandboxed solution." For this demo, add a Web Part to your solution—right-click the project and add a Web Part named SandboxDemoWebPart.

Warning

Take care you don't select a visual Web Part. You can't use visual Web Parts in a sandboxed solution. They contain web controls, which have to be deployed to disk. This is not allowed for sandboxed solutions.

Open the .cs code file of your Web Part to edit it. Listing 9-12 shows sample code.

This code enables your Web Part to show all lists in your site collection in a bulleted list. When completed, the final Web Part should appear similar to Figure 9-37.

Sandbox Web Part

Figure 9.37. Sandbox Web Part

Example 9.12. Web Part Code

using System;
using System.Diagnostics;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace Apress.SP2010.SandboxedWebPart.SandboxWebPart
{
    [ToolboxItemAttribute(false)]
    public class SandboxWebPart : WebPart
    {
private ListBox myListsBox = new ListBox();
        private Label result = new Label();
        public SandboxWebPart()
        {
            try
            {
                using (SPWeb site = SPContext.Current.Site.RootWeb)
                {
                    SPListCollection lists = site.Lists;
                    foreach (SPList list in lists)
                    {
                       myListsBox.Items.Add(list.Title);
                    }
                }


            }
            catch (Exception ex)
            {
                result.Text = ex.Message;
              }
        }
        protected override void CreateChildControls()
        {
            this.Controls.Add(myListsBox);
            this.Controls.Add(result);
            base.CreateChildControls();
        }
    }
}

Debugging the Solution

During development, Visual Studio 2010 automatically builds the solution package, deploys it, and activates it in the Solution Gallery when you start debugging by pressing F5.

If you browse to the Solution Gallery, you can see your new solution activated (see Figure 9-38). When you start debugging, Visual Studio automatically attaches the debugger to SPUCWorkerProcess.exe to debug your solution.

Solution Gallery

Figure 9.38. Solution Gallery

If you want to debug an already deployed sandboxed solution, you need to attach to SPUCWorkerProcess.exe manually, as shown in Figure 9-39.

Attaching to the SPUCWorkerProcess.exe process

Figure 9.39. Attaching to the SPUCWorkerProcess.exe process

Creating a Full-Trust Proxy

If you want to extend the capabilities of your sandbox, you can create a full-trust proxy for your sandboxed solution. The full-trust proxy in the following example extends the previous sandboxed Web Part example. The proxy writes the names of the lists in your site collection to a log file (see Figure 9-40) on disk.

Text file created by the full-trust proxy

Figure 9.40. Text file created by the full-trust proxy

To do so, you need to

  • Create a full-trust proxy class library

  • Deploy this DLL to the GAC

  • Register the full-trust proxy in SharePoint

  • Extend the sandboxed solution with the full-trust proxy

The full-trust proxy is a DLL you have to deploy to the GAC. To build one, add a class library project to the existing SharePoint solution you started earlier for the sandboxed Web Part. Call it, for example, FullTrustProxy. The default framework for a new class library project is the new .NET 4.0 Framework, so you need to set the target framework to .NET 3.5 in the project properties. Otherwise, you'll be unable to reference the project in your SharePoint 2010 projects, because SharePoint 2010 is based on .NET 3.5. The assembly has to be signed when you deploy it to the GAC. To sign it, go to the Signing tab in the project properties (see Figure 9-41) and check the "Sign the assembly" check box. In the window that appears, enter a name for the key file, uncheck "Protect my key file with password," and click OK. Then add a reference to Microsoft.SharePoint.dll.

The DLL has to be signed for GAC deployment.

Figure 9.41. The DLL has to be signed for GAC deployment.

The next step is to add two class files:

  • FullTrustProxyArgs.cs, a class that inherits from Microsoft.SharePoint.UserCode.SPProxyOperationsArgs (this just passes arguments)

  • FullTrustProxyOps.cs, which inherits from Microsoft.SharePoint.UserCode.SPProxyOperation and does the work

The FullTrustProxyArgs class delivers the parameters needed by the FullTrustProxyOps class, as shown in Listing 9-13.

Example 9.13. FullTrustProxyArgs Class

using System;
using System.Reflection;
using Microsoft.SharePoint.UserCode;

namespace Apress.SP2010.FullTrustProxy
{
    [Serializable]
    public class FullTrustProxyArgs : SPProxyOperationArgs
    {
        public string FileContents { get; set; }
public string FullTrustProxyOpsAssemblyName
        {
            get
            {

                // Return the full assembly name, like "FullTrustProxy,
                //  Version=1.0.0.0, Culture=neutral,
                //  PublicKeyToken=29d96910438b4111";
                return Assembly.GetExecutingAssembly().FullName;
            }
        }
        public string FullTrustProxyOpsTypeName
        {
            get
            {
               return "Apress.SP2010.FullTrustProxy.FullTrustProxyOps";
            }
        }

        public FullTrustProxyArgs()
        {
        }
        public FullTrustProxyArgs(string fileContents)
        {
            this.FileContents = fileContents;
        }
    }
}

The FullTrustProxyOps class implements the operations to be executed by the full-trust proxy.

In the example, in Listing 9-14 the proxy writes a string to a log file in the temp folder. Figure 9-40 shows the output of the proxy operation. It is important to allow partially trusted callers for the assembly so that the sandboxed code can call the proxy.

Example 9.14. FullTrustProxyOps Class

using System;
using System.IO;
using System.Security;
using Microsoft.SharePoint.UserCode;

[assembly: AllowPartiallyTrustedCallers()]
namespace Apress.SP2010.FullTrustProxy
{
    public class FullTrustProxyOps : SPProxyOperation
    {
        public override object Execute(SPProxyOperationArgs args)
        {
            if (args != null)
            {
         string tempPath = Environment.GetEnvironmentVariable("TEMP", EnvironmentVariableTarget.Machine);

                FullTrustProxyArgs fileArgs = args as FullTrustProxyArgs;
                FileStream fStream =
new FileStream(tempPath + @"SPFullTrustProxyLog.txt",
                                  FileMode.Append);
                fStream.Write(System.Text.ASCIIEncoding.ASCII.GetBytes(
                              fileArgs.FileContents), 0,
                 fileArgs.FileContents.Length);
                fStream.Flush();
                fStream.Close();
                return fileArgs.FileContents;
            }
            else return null;
        }
    }
}

Deploying the Full-Trust Proxy DLL to the GAC

Your first full-trust proxy is now complete. But before you can use it, you need to deploy it to the GAC.

Add a new empty SharePoint project called DeployFullTrustProxy to your open Visual Studio solution. It must be deployed as full trust. Set a reference to the project output of the class library project. The solution is used to deploy and register the DLL. Open the package designer and click the Advanced button. Here, you add the project output of the class library project, as shown in Figure 9-42.

Deploy the Full-Trust Proxy DLL to the GAC

Figure 9.42. Deploy the Full-Trust Proxy DLL to the GAC

Registering the Full-Trust Proxy Using a Feature Receiver

Before you can use the full-trust proxy, you need to register the DLL in SharePoint.

The best way to do this is to use a feature receiver so that the farm administrator can activate and deactivate the full-trust proxy in Central Administration, as shown in Figure 9-43.

Managing the full-trust proxy via a feature in Central Administration

Figure 9.43. Managing the full-trust proxy via a feature in Central Administration

Add a feature with the scope of Farm, and a feature event receiver to the project. The feature will be used to register your proxy as SPProxyOperationType in SharePoint (see Listing 9-15).

Example 9.15. Feature Event Receiver

using System;
using System.Runtime.InteropServices;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.UserCode;
using Apress.SP2010.FullTrustProxy;

namespace Apress.SP2010.DeployFullTrustProxy.Features.Feature1
{
    [Guid("65a428e1-c14a-4f9c-b7fe-9dbac8e830d4")]
    public class Feature1EventReceiver : SPFeatureReceiver
    {
        // Handle the event raised after a feature has been activated
        public override void FeatureActivated(SPFeatureReceiverProperties
                                               properties)
        {
            try
            {
                SPUserCodeService userCodeService = SPUserCodeService.Local;
                if (userCodeService != null)
                {
                    SPProxyOperationType operation =
                        new SPProxyOperationType(
                            new FullTrustProxyArgs().FullTrustProxyOpsAssemblyName,
                            new FullTrustProxyArgs().FullTrustProxyOpsTypeName);
userCodeService.ProxyOperationTypes.Add(operation);
                    userCodeService.Update();
                }
            }
            catch
            {
              // Exception handling
            }
        }
        // Handle the event raised before a feature is deactivated
        public override void FeatureDeactivating(
                             SPFeatureReceiverProperties properties)
        {
            try
            {
                SPUserCodeService userCodeService = SPUserCodeService.Local;
                if (userCodeService != null)
                {
                    SPProxyOperationType operation = null;
                    foreach (SPProxyOperationType operationType in
                             userCodeService.ProxyOperationTypes)
                    {
                        if (operationType.AssemblyName.Equals(new
                            FullTrustProxyArgs().FullTrustProxyOpsAssemblyName,
                            StringComparison.CurrentCultureIgnoreCase))
                        {
                            operation = operationType;
                            break;
                        }
                    }
                    if (operation != null)
                    {
                        userCodeService.ProxyOperationTypes.Remove(operation);
                        userCodeService.Update();
                    }
                }
            }
            catch
            {
                // Exception handling
            }
        }
    }
}

Now the proxy is completed. You could build, package, and deploy the solution containing your full-trust proxy. However, the proxy is only one half of the scenario; it's just a tool to achieve the goal of extending the boundaries of a sandboxed solution, which we'll describe next.

Using the Full-Trust Proxy to Extend a Sandboxed Solution

In the next step, you will extend your sandboxed solution to use the proxy.

Add a reference in the SandboxedWebPart project named to the project output of the proxy class library project. In the next step, edit the code of the existing Web Part (see Listing 9-12) in the project. Listing 9-16 shows the new code of the Web Part in bold. The proxy call consists of two simple lines: first you create a new instance of FullTrustProxyArgs and deliver the parameter string as the argument for the proxy, and then you call the proxy operation with SPUtility.ExecuteRegisteredProxyOperation. That's it.

Example 9.16. Web Part Code

using System;
using System.Diagnostics;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Apress.SP2010.FullTrustProxy;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace Apress.SP2010.SandboxedWebPart.SandboxWebPart
{
    [ToolboxItemAttribute(false)]
    public class SandboxWebPart : WebPart
    {
        private string myLists;
        private ListBox myListsBox = new ListBox();
        private Label result = new Label();
        public SandboxWebPart()
        {
            try
            {
                using (SPWeb site = SPContext.Current.Site.RootWeb
                {
                   SPListCollection lists = site.Lists;
                   foreach (SPList list in lists)
                   {
                           myListsBox.Items.Add(list.Title);
                           myLists += list.Title + Environment.NewLine;
                   }
                }
                  FullTrustProxyArgs proxyArgs = new FullTrustProxyArgs(myLists);
                  SPUtility.ExecuteRegisteredProxyOperation(
                       proxyArgs.FullTrustProxyOpsAssemblyName,
                                proxyArgs.FullTrustProxyOpsTypeName,
                                proxyArgs);

            }
            catch (Exception ex)
            {
                result.Text = ex.Message;
          }

        }
        protected override void CreateChildControls()
{
            this.Controls.Add(myListsBox);
            this.Controls.Add(result);
            base.CreateChildControls();
        }
    }
}

Now you are ready for a test flight. Deploy both solutions to your development SharePoint.

If you want to check that your full-trust proxy is registered correctly in SharePoint, you can enter the following command at the SharePoint management shell or PowerShell:

[Microsoft.SharePoint.Administration.SPUserCodeService]::Local.ProxyOperationTypes.

If your full-trust proxy was registered, your output should look similar to that shown in Figure 9-44.

Insert the Web Part into a web site and test the full-trust proxy. The Web Part should display all the lists in the site collection. In addition, you will find a file called SPFullTrustProxyLog.txt created by the proxy in the temp folder.

Check whether your full-trust proxy was registered in SharePoint.

Figure 9.44. Check whether your full-trust proxy was registered in SharePoint.

Creating a Solution Validator

Farm administrators can proactively deploy solution validators to their farms. These validators always run when a sandboxed solution is activated or upgraded. You can easily create your own solution validator by performing the following steps:

  • Writing a solution validator class

  • Creating an error page

  • Deploying the solution validator to the GAC

  • Registering the solution validator in SharePoint

Start with a new Empty SharePoint project and name it SolutionValidatorDemo. Choose "Deploy as farm solution" in the wizard. Then add a class with the name SolutionValidator to your project. This file will contain your validator, as shown in Listing 9-17. It shows the general structure of a solution validator and gives examples of how to validate. You can validate an assembly and a solution.

Example 9.17. Solution Validator

using System;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.UserCode;

namespace Apress.SP2010.SolutionValidatorDemo
{
    [Guid("481823F5-75A7-4EF8-8A4B-11C4D52D1014")]
    public class SolutionValidator : SPSolutionValidator
    {
        private const string strValidatorName = "My Solution Validator";
        // Help method to validate the content of files in the solution
        private byte[] LoadBytes(ReadOnlyCollection<byte> bytes)
        {

            byte[] fileBytes = new byte[bytes.Count];
            int count = 0;
            foreach (byte b in bytes)
            {
                fileBytes[count] = b;
                count++;
            }

            return fileBytes;
        }
        // Help method to validate features in the solution
        private bool CheckForFeature(string fileContents, string type)
        {
            string EorF = "<Elements";

            if (type.Equals("ReceiverAssembly"))
                EorF = "<Feature";

            if (fileContents.Contains(EorF) && fileContents.Contains("<" + type))
            {
                return true;
            }

            return false;
        }

        public SolutionValidator()
        {

        }

        public SolutionValidator(SPUserCodeService userCodeService)
            : base(strValidatorName, userCodeService)
        {
            this.Signature = 1983;
        }

        public override void ValidateAssembly(
             SPSolutionValidationProperties properties, SPSolutionFile assembly)
        {
            properties.ValidationErrorUrl =
"/_layouts/SolutionValidatorDemo/SolutionValidationErrorPage.aspx";
            bool valid = true;

// Block Solutions containing assemblies named "TestSolution"
            string blockAssemblyName ="TestSolution";
           // Block Solutions containing assemblies with the Public Key Token
           string blockPKT = "29d96910438b4111";

            byte[] fileBytes = LoadBytes(assembly.OpenBinary());
            Assembly a = Assembly.Load(fileBytes);
            string[] assemblyFullName = a.FullName.ToLower().Split(','),
            string assemblyName = assemblyFullName[0];
            string version = assemblyFullName[1].Replace("version=", "").Trim();
            string culture = assemblyFullName[2].Replace("culture=", "").Trim();
            string publicKeyToken = assemblyFullName[3].
                                          Replace("publickeytoken=", "").Trim();

            // Validate AssemblyName
            if (assemblyName.Equals(blockAssemblyName.ToLower()))
            {
                valid = false;
                properties.ValidationErrorMessage += "Assembly name '"
                                                  + assemblyName + "' not valid. ";
            }
            // Validate PublicKeyToken
            if (publicKeyToken.Equals(blockPKT.ToLower()))
            {
                valid = false;
                properties.ValidationErrorMessage += "Assembly PublicKeyToken '"
                                              + publicKeyToken + "' not valid. ";
            }


            if (!valid)
            {
                properties.ValidationErrorUrl += "?ErrorMessage="
                                              + properties.ValidationErrorMessage;
            }

                properties.Valid = valid;

        }

        public override void ValidateSolution(
                             SPSolutionValidationProperties properties)
        {
            properties.ValidationErrorUrl =
               "/_layouts/SolutionValidatorDemo/SolutionValidationErrorPage.aspx";
            bool valid = true;
            string blockSolutionID = "{3CCB9CAF-54A7-42FF-A03F-F6D6D881BC70}";
            string[] blockFileName = {"SandboxedWebPart","Test"};
            string[] blockFileExt = { "xml", "jpg","webpart" };
            string[] blockFileContent = { "Sand", "box"};

           ReadOnlyCollection<SPSolutionFile> files = properties.Files;
foreach (SPSolutionFile file in files)
           {

               // Block Filenames
               foreach (string filename in blockFileName)
               {
                   if (file.Location.ToLower().Equals(filename))
                   {
                       valid = false;
                       properties.ValidationErrorMessage += "Filename '"
                                                    + filename + "' is blocked. ";

                   }
               }

               // Block FileExtensions
               foreach (string ext in blockFileExt)
               {
                   if (file.Location.ToLower().EndsWith(ext))
                   {
                       valid = false;
                       properties.ValidationErrorMessage += "File extension '"
                                                         + ext + "' is blocked. ";
                   }
               }

               if (file.Location.ToLower().EndsWith("xml"))
               {
                   byte[] fileBytes = LoadBytes(file.OpenBinary());

                   string fileContents = ASCIIEncoding.ASCII.GetString(fileBytes);

                   // Check for file content
                   foreach (string content in blockFileContent)
                   {
                       if (fileContents.ToLower().Contains(content))
                       {
                           valid = false;
                           properties.ValidationErrorMessage += "File '"
                             + file.Location + "' contains blocked characters. ";

                       }
                   }

                   // Check for features like ContentType, CustomAction, Workflow,
                   // Receivers, ReceiverAssembly, ListTemplate, Module,
                   // Field, and WebPart

                   if (CheckForFeature(fileContents, "ListTemplate"))
                   {
                      valid = false;
                      properties.ValidationErrorMessage = "Solution is blocked
                                              from including List Definitions. ";
                   }
}
            }
            // Block SolutionID
            if (properties.SolutionId.Equals(new Guid(blockSolutionID)))
            {
                valid = false;
                properties.ValidationErrorMessage += "SolutionID is not valid. ";
            }

            // Block SolutionID stored in SharePoint list
            string strListName = "block";

            using (SPSite site = properties.Site)
            {
               SPList list = site.OpenWeb().Lists.TryGetList(strListName);
               if (list!=null)
               {
                  SPListItemCollection items = list.GetItems();
                  foreach (SPListItem item in items)
                  {
                     if (properties.SolutionId.Equals(new Guid(item.Title)))
                     {
                        valid = false;
                        properties.ValidationErrorMessage += "SolutionID is not
                                                              valid. ";
                        break;
                     }


                  }
               }
            }
            if (!valid)
            {
                properties.ValidationErrorUrl += "?ErrorMessage=" +
                                      properties.ValidationErrorMessage;
            }

            properties.Valid = valid;
        }
    }
}

Creating an Error Page for the Solution Validation

If a solution is not valid, you can display an error message. If you wish, you can define your own custom error page, such as the one shown in Figure 9-45.

Solution validator error page

Figure 9.45. Solution validator error page

To construct this, add a new application page called SolutionValidationErrorPage.aspx to your project. Listing 9-18 shows example code for your error page.

Example 9.18. Custom Error Page: SolutionValidationErrorPage.aspx

<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
     Solution Validation failed: <%= this.ErrorMessage %>
</asp:Content>
<asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle"
             runat="server">
      Solution Validation Failure
</asp:Content>
<asp:Content ID="PageTitleInTitleArea"
             ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server" >
      Solution Validation Failure
</asp:Content>

To display the error message of the validator, retrieve the message from the url parameter, as shown in Listing 9-19.

Example 9.19. Custom Error Page CodeBehind

using System;
using Microsoft.SharePoint.WebControls;
namespace Apress.SP2010.SolutionValidatorDemo.Layouts.SolutionValidatorDemo
{
    public partial class SolutionValidationErrorPage : LayoutsPageBase
    {
        public string ErrorMessage= String.Empty;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["ErrorMessage"] != null)
            {
                this.ErrorMessage = Request.QueryString["ErrorMessage"].ToString();
            }
        }
}
}

Deploying and Registering the Solution Validator

When you have finished developing your validator, you can deploy it as a farm feature as follows:

  1. Add a new feature to your SharePoint project.

  2. Set the scope to Farm.

  3. Add a feature event receiver. Once the receiver contains code like that shown in Listing 9-20, you can simply activate and deactivate your solution validator with the feature using Central Administration (see Figure 9-43).

Warning

When you deploy a restrictive solution validator to your development machine, remember to deactivate it when you want to resume developing sandboxed solutions.

Example 9.20. Feature Event Receiver

using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;

using Microsoft.SharePoint.Administration;

namespace Apress.SP2010.Features.SolutionValidatorFeature
{
    [Guid("2a4d3a6b-ab9c-4008-9408-26dd4cd1f6d8")]
    public class SolutionValidatorFeatureEventReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(
                          SPFeatureReceiverProperties properties)
        {
            SPUserCodeService.Local.SolutionValidators.Add(
                          new SolutionValidator(SPUserCodeService.Local));
        }
        public override void FeatureDeactivating(
                          SPFeatureReceiverProperties properties)
        {
            SPUserCodeService.Local.SolutionValidators.Remove(
                          new Guid("481823F5-75A7-4EF8-8A4B-11C4D52D1014"));
        }
    }
}

Now you are ready to test this. Deploy your solution to your development machine.

If you want to check whether your solution validator was registered in SharePoint, you can enter the following command at the SharePoint management shell or PowerShell:

[Microsoft.SharePoint.Administration.SPUserCodeService]::Local.SolutionValidators.

If your solution validator was registered correctly, the output should appear similar to that shown in Figure 9-46.

Check whether your solution validator was registered in SharePoint

Figure 9.46. Check whether your solution validator was registered in SharePoint

Tip

On CodePlex is the Generic Solution Validator at http://spgenericvalidator.codeplex.com/. You can install this validator on your SharePoint 2010 server to set solution validation settings on a config page in your site collection.

Upgrading Custom Developed Solutions to SharePoint 2010

If you have already customized and extended SharePoint 2007, you have probably created your own solutions. If you want to use your solutions in SharePoint 2010, one option is to use backward compatibility mode. If you wish to edit your solutions in Visual Studio 2010, however, we recommend you upgrade them.

Backward Compatibility Mode

SharePoint 2010 comes with a UI compatibility mode for SharePoint 2007 for backward compatibility.

If you upgrade your SharePoint 2007 farm to SharePoint 2010, backward compatibility mode is active by default. If you want to use the SharePoint 2010 UI, you can activate the new experience for every site collection, or for a single site in the site settings (Site Collection AdministrationSupported User Experiences). You can also activate backward compatibility mode via the API; set the UI version to 3 for compatibility mode and to 4 for the SharePoint 2010 UI, as shown in Listing 9-21.

Example 9.21. Activating Backward Compatibility Mode

public class UIModeFeatureEventReceiver : SPFeatureReceiver
{
   public override void FeatureActivated(SPFeatureReceiverProperties properties)
   {
            // Feature is scoped at Web, so the parent type is SPWeb
            using (SPWeb web = properties.Feature.Parent as SPWeb)
            {
                web.UIVersion = 3;
                web.Update();
            }
    }
   public override void FeatureDeactivating(
                                          SPFeatureReceiverProperties properties)
   {
       // Feature is scoped at Web, so the parent type is SPWeb
            using (SPWeb web = properties.Feature.Parent as SPWeb)
            {
                web.UIVersion = 4;
                web.Update();
            }
   }
}

Reasons for Upgrading

If you wish to use the new SharePoint 2010 features and develop your solutions with Visual Studio 2010, it is necessary to upgrade your existing solutions. The following are some important reasons to upgrade:

  • New APIs (Microsoft.SharePoint.Linq.dll, Microsoft.SharePoint.Client.dll, Microsoft.SharePoint.Taxonomy.dll) vs. old API (Microsoft.SharePoint.dll)

  • Deprecated APIs

  • LINQ to SharePoint

  • Client APIs

  • New technologies available: Silverlight, AJAX, and JSON

  • New UI: ribbon, pop-ups, CSS

  • Business Connectivity Services (BCS)

  • Changed paths (14 hive instead of 12 hive)

  • Large list query throttling

  • Sandboxed solutions

Depending on how you created your existing solutions, there are different options for migrating them to Visual Studio 2010 and SharePoint 2010:

  • Upgrading a Visual Studio Extensions for Windows SharePoint Services (VSeWSS) 2005/2008 solution

  • Upgrading a WSP package

  • Upgrading a custom solution

Upgrading a VSeWSS Solution

For SharePoint 2007 development with Visual Studio 2005 or 2008, Microsoft offered VSeWSS 3.0. If you have created your solutions with VSeWSS, you can upgrade them to a Visual Studio 2010 solution.

Unfortunately, you can't open a VSeWSS project directly with Visual Studio 2010. If you try to do so, you'll get the following error message: "The project type is not supported by this installation." However, Microsoft offers an additional project template as an extension for Visual Studio 2010 (VSIX) that allows the importing of existing VSeWSS projects. You have to download and install this tool separately, as described in the next exercise.

This additional template enables you to import VSeWSS projects version 1.1 and above into a new Visual Studio 2010 SharePoint project, including your Visual Basic or C# code.

The import process converts the existing structure of your VSeWSS project as closely as possible to the new Visual Studio 2010 layout. This also means that you'll have one SharePoint item per feature, because VSeWSS had a one-to-one approach. Since Visual Studio 2010 is more flexible, allowing you to arrange multiple artifacts per feature, you can rearrange the features later.

When you choose the template, the wizard will also ask you for the security level setting. This time, full trust is the default. You should take this option, because the old solutions were also full trust. If you want to deploy your imported solution as a sandboxed solution in the future, you can change this setting in the project properties, as shown in the "Sandboxed Solutions" section earlier in the chapter (also see Figure 9-36). However, remember the restrictions of sandboxed solutions before taking this step.

When the import has finished, take a look at the Output window and the error list in Visual Studio 2010. In the Output window, choose Show Output from SharePoint Tools

to display a log of the import process and some extra information. This includes advice about what you need to do next. In the error list, you may also find messages and warnings concerning the import.

The import process handles a number of problems that can occur while importing the source project:

  • The source solution can contain artifacts whose handling has changed in SharePoint 2010, such as themes.

  • The source solution can be corrupt in many ways. The readme file delivered with the VSeWSS Import tool describes several scenarios.

For example, when you import a SharePoint 2007 theme, the import process detects this theme and displays a message explaining that the handling of themes has been changed in SharePoint 2010 and providing a pointer to solve the problem. You should check and fix the following:

  • The assembly name and default namespace of your project

  • Referenced assemblies or projects

  • Web references (ASMX) and service references (WCF)

During the import the default namespace of your old project is also imported. But the assembly name can differ from the source assembly name if your new project does not have the same name. Check this in the project properties, too.

The VSeWSS import process converts only the VSeWSS project. It does not import referenced projects that were part of the source solution. You need to add the referenced projects again to the solution and reference the output in the SharePoint project, or reference the resulting assemblies. References to Microsoft.SharePoint.* and Microsoft.Office.* assemblies are automatically updated from version 12 to version 14.

If your VSeWSS project contains web or service references, the files created by adding and updating these references are imported and the project will still build. But they are not added as web or service references to the project, so you can't update them. Hence, you should remove the files and add the web and service references again manually.

Visual Studio 2010 enables you to redesign the structure of your package and your features. Using the Package Explorer, features and assemblies can be easily added to or removed from your package. With the Feature Designer you can add multiple SharePoint items to one feature, remove them, and rename them. (The previous section "How To: Creating a Solution Package Using Visual Studio 2010" contains the details.)

Upgrading a WSP Package

For all other projects deployed via WSP files, upgrading a WSP package may be the best option. To upgrade a WSP-packaged solution, import it into Visual Studio 2010. This option can also be used to import and edit solutions created with SharePoint Designer 2010.

The import wizard gives you the option to choose which items of the solution you want to import (see Figure 9-48). Based on the chosen parts, Visual Studio creates a new project structure and inserts the chosen items. The tool only imports the XML files, images, and other files that are included in your WSP file. Since a WSP file doesn't contain your source code, you have to import your code manually and set the correct namespaces. The following exercise will guide you through the WSP import process.

When the import has finished, examine the Output window and the error list as described in the previous section. Since your code is not imported from a WSP file, it needs to be imported manually.

In this context, you should check and fix the following:

  • The assembly name and default namespace of your project

  • Referenced assemblies or projects

  • Web references (ASMX) and service references (WCF)

  • Your custom code import

You can redesign your solution easily using the Package Explorer and the Feature Designer. After the import, the features folders will be named Feature 1, Feature 2, and so on. You should rename them in Solution Explorer.

Upgrading Custom Solutions

Although importing VSeWSS projects and WSP packages can help greatly, in some cases you may have to explore other ways of upgrading your solutions to Visual Studio 2010 and SharePoint 2010.

This will become necessary in the following scenarios:

  • If you haven't used VSeWSS

  • If you didn't deploy your solutions through WSP files

  • If you don't want to use a VSeWSS or WSP import

  • If you have used your own installer or script

In these cases you need to create an empty SharePoint 2010 solution project and insert the items from the old project, as shown in the following exercise. (The section "How to: Creating a Solution Package Using Visual Studio 2010" may help you, too.)

Using Existing SharePoint 2007 Code in SharePoint 2010

In general your custom assemblies for SharePoint 2007 also run in SharePoint 2010. There are three different types:

  • Code that runs within IIS

  • Code that runs within the timer service

  • Code that runs outside of IIS

Code for SharePoint 2007 that runs within IIS will work in SharePoint 2010 without recompilation. If your code runs within the timer service (such as workflows, feature receivers, and timer jobs), you have to compile it for SharePoint 2010. It's the same with code that utilizes the SharePoint object model and runs outside of IIS in a service or console application: you need to recompile or provide binding redirects. Thinking of deprecated APIs, it's recommended that you always import your source code into your SharePoint/Visual Studio 2010 projects and recompile it.

Deprecated APIs

In SharePoint 2010, numerous APIs of previous versions have been deprecated. But don't worry: most deprecated types and methods are still available in SharePoint 2010. Microsoft will not invest in these APIs in the future, so you should use the newer alternatives. While recompiling your code in Visual Studio 2010, compiler warnings will tell you which elements are deprecated and which newer alternatives are available. When you edit your code, IntelliSense will also indicate deprecated types and methods, as shown in Figure 9-49.

Compiler warnings and IntelliSense indicate deprecated types and methods.

Figure 9.49. Compiler warnings and IntelliSense indicate deprecated types and methods.

Most deprecated types and methods are in the Microsoft.SharePoint.Portal namespace. In fact, with a few exceptions, the entire namespace has been made obsolete. Other examples of deprecated types and methods are shown in Table 9-11.

Table 9.11. Examples of Deprecated Types and Methods

Namespace

Deprecated Type or Method

Microsoft.SharePoint.Administration

SPVirtualServer

Microsoft.SharePoint

SPCheckoutStatus

Microsoft.SharePoint

SPRights

Microsoft.SharePoint

SPPermission

Microsoft.SharePoint.Webcontrols

RaisePostbackEvent

Microsoft.Office.Server

Get Context

You can find a complete list of deprecated types and methods in SharePoint 2010 at http://code.msdn.microsoft.com/sps2010deprecated. (For more information about the API see Chapters 2 and 3 of this book.)

Tip

Microsoft published a whitepaper entitled "Redeploying Customizations and Solutions in SharePoint Foundation 2010 and SharePoint Server 2010," which you can find at http://msdn.microsoft.com/en-us/library/ee662217%28office.14%29.aspx.

Summary

This chapter introduced SharePoint solution packages provided with SharePoint to deploy customizations and extensions. You learned about solution packages and features and how to create and use them, including the different ways you can deploy a solution package (via stsadm, PowerShell, or the UI). This chapter also introduced the new SharePoint 2010 feature of sandboxed solutions. Finally, you got an overview on how to upgrade your existing solution packages from SharePoint 2007 to SharePoint 2010.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.212.160