Using Deployment Step events to add functionality to Deployment Configuration

With the help of the extensibility features in the SharePoint tools in Visual Studio, you can add functionality to deployment configurations by subscribing to the DeploymentStepStarted and DeploymentStepCompleted events.

To learn more about deployment configurations and deployment steps in SharePoint projects, refer to the MSDN article here.

In this blog post I will show you how to use the DeploymentStepCompleted event and add you own code that is executed when a SharePoint project is either deployed or retracted.

Our scenario is the following: When retracting Web Parts we would like to delete the .webpart file from the SharePoint server. We will create a project item extension for the Visual Web Part project and from that extension we will subscribe to the DeploymentStepCompleted event. First we will need to create a SharePoint project item extension project.

To do that we will need to:

1)  Install the Visual Studio SDK from: https://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=47305cf4-2bea-43c0-91cd-1b853602dcc5

2) Create an empty VSIX project

3) Add a class library project which is project item extension project to the solution

4) Add the output from the project item extension project as MEF component content to the VSIX manifest in the VSIX project.

For detailed information on how to create project item extensions you can refer to the walkthrough here or Bing ‘Visual Studio 2010 How to: Create a SharePoint Project Item Extensions.

Let’s start by creating a project Item extension for Visual Web Part.

   

[Export(typeof(ISharePointProjectItemTypeExtension))]

[SharePointProjectItemType("Microsoft.VisualStudio.SharePoint.VisualWebPart")]

 internal class ItemExtension : ISharePointProjectItemTypeExtension

    {

        public void Initialize(ISharePointProjectItemType projectItemType)

        {

            projectItemType.DeploymentStepCompleted += new EventHandler<DeploymentStepCompletedEventArgs>(projectItemType_DeploymentStepCompleted);

        }

       

void projectItemType_DeploymentStepCompleted(object sender, DeploymentStepCompletedEventArgs e)

        {

            ISharePointProjectItem SPProjectItem = e.ProjectItem;

            string webPartUrl = GetWebPartFileUrl(SPProjectItem);

            if (e.DeploymentStepInfo.Id == DeploymentStepIds.RetractSolution && !string.IsNullOrEmpty(webPartUrl))

            {

                SPProjectItem.Project.SharePointConnection.ExecuteCommand<string>(DeleteWebPartFileCommand, webPartUrl);

            }

        }

 

Notice in above code we created a new class called Item Extension that implements the ISharePointProjectItemTypeExtension interface. In order for this class to be recognized in Visual Studio we added two attributes. With the Export attribute we are telling Visual Studio that this class is a project item extension and with second attribute (SharePointProjectItemType) we are telling Visual Studio that this extension applies to the Visual Web Part projects. Extension developers can subscribe to deployment step events in the Initialize method of the project item extension.

 projectItemType.DeploymentStepCompleted += new EventHandler<DeploymentStepCompletedEventArgs>(projectItemType_DeploymentStepCompleted);

The event we subscribed to is raised for all the deployment steps that are executed in the active deployment configuration. With the help of the event args parameter passed to the event handler we can check which step is being executed and decide what code to run.

if (e.DeploymentStepInfo.Id == DeploymentStepIds.RetractSolution && !string.IsNullOrEmpty(webPartUrl))

Since this includes deleting a file on the SharePoint server, the extension uses a custom SharePoint command to call into the SharePoint server object model. For detailed information on why to use SharePoint commands is discussed here.

 The line of code which uses the SharePoint command is:

SPProjectItem.Project.SharePointConnection.ExecuteCommand<string>(DeleteWebPartFileCommand, webPartUrl);

When this line of code is executed we create a new process named vssphost4.exe or use an existing one. The SharePoint command named DeleteWebpartFileCommand is executed inside this process during execution.

To create a SharePoint command class we need to:

1) Add a class library project that targets the .NET Framework 3.5 to the same solution as the VSIX and project item extension projects.

2) Add references to Microsoft.SharePoint.dll and Microsoft.VisualStudio.SharePoint.Commands.dll.

3) Add the commands project output to the VSIX manifest in the VSIX project as a Custom Content Type with Type= “SharePoint.Commands.v4”. This will include the commands project in the VSIX as custom assembly which can be used by the SharePoint project extensions.

internal class Command

    {

        [SharePointCommand("DeleteWebPartFile")]

        private void DeleteWebPartFile(ISharePointCommandContext context, string webPartFileUrl)

        {

            //Append RootWeb Url

            string fullWebpartFileUrl = SPUrlUtility.CombineUrl(context.Web.Site.RootWeb.Url, webPartFileUrl);

            try

            {

                SPFile file = context.Web.Site.RootWeb.GetFile(fullWebpartFileUrl);

                if (file.Exists)

                {

                    file.Delete();

                    context.Logger.WriteLine(string.Format("Visual Webpart Extension:Deleted file at {0}", fullWebpartFileUrl), LogCategory.Status);

                }

            }

        catch (Exception ex)

            {

                context.Logger.WriteLine(string.Format("Visual Webpart Extension:Exception occured when deleting file at: {0}", fullWebpartFileUrl), LogCategory.Status);

                context.Logger.WriteLine(string.Format("Visual Webpart Extension:Exception occured when deleting file at: {0}; Exception:{1}", fullWebpartFileUrl, ex.Message +       ex.StackTrace), LogCategory.Verbose);

            }

        }

    }

Notice in the above code we are have an attribute SharePointCommand for the method name which will enable it to be recognized and used by the project item extension to call into. Also the first parameter should be ISharePointCommandContext which will have reference to ‘SPWeb’ to take advantage of Server object model.

 You will also see the logger object is also exposed in the context parameter with which we can log back messages to the output window of Visual Studio from vssphost4.exe.

You can now install the extension located in the bin/output folder of the VSIX project after the solution is built. Once this extension is installed the DeploymentStepCompleted event will be raised each time a Visual Web Part project is being retracted after the ‘retractSolution’ step.

To test and debug the extension:

1) Download and open the extension project from MSDN code gallery.

2) Place a breakpoint in the projectItemType_DeploymentStepCompleted event handler in ItemExtension.cs file and press F5 to start debugging. This will install the VSIX extension in the experimental instance of Visual Studio.

3) The experimental instance of Visual Studio will start. Create a Visual Web Part project (select the project template under the SharePoint 2010 node) and use default values in the wizard.

4)  Once the project is created, press F5.

5) Close IE or stop debugging to start executing the retraction steps.

6) Once the retraction steps start executing, you will see the breakpoint being hit after “Retract Solution” step.

7) You will see the file being deleted after the code is executed.

Output Window snapshot

For more information on how to extend the SharePoint project system in Visual Studio you can refer to MSDN topic here or Bing “Visual Studio 2010 Extending the SharePoint Project System“.

Murali Madala.