May 20, 2010

Visual Studio 2010 extension for helping SharePoint 2010 debugging

Visual Studio 2010 has – of course, among others – a great new feature that is VSIX and MEF-based extensions. Built on that technology you can extend the out of the box SharePoint toolset in Visual Studio.

There is a lot of useful resources on the theory and practice of VS SharePoint tools extensions, so I will not cover it now. If you need the background, you can easily pick that up from these sites:

In this post I would like to introduce an extension I’ve created to make my life a bit easier. These tools are always “under construction”, but I’ve tried to create a consistent release to be able to share it with fellow developers.

I have published the project on CodePlex here. If you want to build it yourself, don’t forget to install the Visual Studio 2010 SDK.

The extension adds six new menu items to the SharePoint project menu:

Attach debugger to OWSTIMER: If you would like to debug timer jobs, e-mail event receivers or other code that runs in the context of the SharePoint Timer Service, you can click this menu item instead of bothering with the Attach to Process dialog box (Debug / Attach to Process…).

Attach debugger to VSSPHOST4: The vssphost4.exe process is responsible for running SharePoint commands started by Visual Studio 2010. If your code runs in this context, that is the case for example when you create feature event receivers, and would like to debug that code, you can use this menu. In the current version the tool assumes that the process is already running. If this assumption is false, the action will fail.

Attach debugger to W3WP: Although Visual Studio attaches the debugger to the current web application pool process if you start and deploy the project, but deployment sometimes takes extra time (for example, the code did not change and already deployed) and would be easier just to simply attach to the worker process.

Recycle W3WP: Yes, there is a similar deployment step that recycle the current application pool process, but as I wrote, I don’t want to always deploy my project. This menu item helps me in this case.

Restart OWSTIMER: The reason for that is similar than the former one.

Start timer jobs: If you want to debug your timer jobs, you should start them first. You can wait for the jobs to start by their schedule or start them manually one-by-one in Central Admin, but it would be the best if you were able to start the from the Visual Studio IDE, where you want to debug them. So I extended the SharePoint projects with a custom property where you can specify the jobs you want to restart frequently when working on the project. This menu item will try to restart the jobs for you.

The following is an output of the job restart. You can see that there is a job that does not exist in my system. In this case you get an alert. Similarly, if the job is already in the running state, you get another kind of warning.

In the project extension I add new menu items and properties to the project:

We get the name of the current application pool by the following SharePoint command:

[SharePointCommand("PHolpar.GetAppPoolName")]

publicstaticString GetAppPoolName(ISharePointCommandContext context)

{

SPSite site = context.Site;

SPWebApplication webApp = site.WebApplication;

SPApplicationPool appPool = webApp.ApplicationPool;

return appPool.Name;

}

The RestartService method is used to restart the specified service, in this case the SharePoint timer. You can see from the miRestartOwsTimer_Click introduced above that this method is called with the “SPTimerV4” as service name (that is the internal name of the timer service in SharePoint v4) and 10 seconds as the hard-coded timeout to service stop and start.

internalstaticbool RestartService(String serviceName, int timeOut)

{

try

{

TimeSpan timeOutSpan = TimeSpan.FromSeconds(timeOut);

ServiceController sc = newServiceController(serviceName);

if (sc.Status == ServiceControllerStatus.Running)

{

sc.Stop();

sc.WaitForStatus(ServiceControllerStatus.Stopped, timeOutSpan);

}

sc.Start();

sc.WaitForStatus(ServiceControllerStatus.Running, timeOutSpan);

returntrue;

}

catch

{

returnfalse;

}

}

The RecycleW3wp method is a bit more tricky. Since there is already a built-in method in a deployment step to recycle the application pool for a project, I re-used that internal method using Reflection.

internalstaticvoid RecycleW3wp(ISharePointProject project)

{

try

{

// hack to get the private Microsoft.VisualStudio.SharePoint.Project assembly

The extension also adds three new deployment steps to the existing ones. These new steps are three of the above mentioned menu items. I feel the Attach debugger to VSSPHOST4 step useful when you work with feature event handlers and would like to capture the first activation of the feature that happens when the project is deployed by Visual Studio. In this case you should include this step in your custom deployment configuration before the Activate Features step.

Since these steps utilize the same helper methods as the menu items do, there is nothing new in their code. I just show one of them to illustrate the structure of the deployment steps for those of you not very familiar with that:

Sorry to say, but my Visual Studio 2010 SharePoint extensions are created for SP 2010 only, and I don’t think I have time to implement it for WSS 3.0 / MOSS 2007 even if MEX and VS add-in infrastructure would make that theoretically possible. Anyway, the source code is available for you to use for such modifications as well.

Thanks for your comment, you might be right. There are almost 3.000.000 hits for “there are a lot of resources” when you search the web, but there are also > 500.000 for “there’s a lot of resources”, so it may be not so wrong. Unfortunately, I’m sure you can find even more serious grammar errors on my blog. I just can hope it was not the most important thing you learnt from this post. If you would like to discuss this question further, I suggest to do that on forums like this. In case you have a more technical question regarding VS 2010 extensions for SharePoint I try to answer that.