SharePoint Server Explorer is a new addition to Visual Studio 2010 along with the Visual Studio Tools for SharePoint.

It is a very good tool if you want to browse the contents (site columns, content types, features etc.,) of the SharePoint site from Visual Studio. By default, it doesn’t do nothing much than showing what are available in the site.

As you can see, the context menu has very fewer items. Below is the Properties pane for the Holds list in the screenshot. The properties are stored in Annotations. To understanding what Annotations are, it is best to consider them as a Class with Properties. Those properties is what you see in the Properties pane below.

Again, its read only.
Can I Extend?
So, the next obvious question you would ask yourself (if you are a SharePoint developer) is – Can I extend this and add my own commands or nodes to the SharePoint Server Explorer?
Yes, you can extend the SharePoint Server Explorer to:
1) Create new nodes
2) Extend existing nodes
Give me an example?
Lets take the Features node

The Features node displays all the active features in the site. If you right click on a feature, you get very less options

How cool would be to add Deactivate option to the context menu and deactivate the selected feature? :)

[ By the way, the above screenshot is an actual extension built and not a Photoshop trick :) ]
Understanding the SharePoint Server Explorer
Before you start writing an extension, you should get to know the different types of SharePoint Server Explorer nodes.

The node that we are interested in is the FeatureNode.
Getting Started
MSDN has excellent articles explaining how to extend the Visual Studio Tools for SharePoint
Here is a pictorial representation of what we would be doing:

1. Create a class that implements IExplorerNodeTypeExtension
2. Handle the events
3. Access the properties of that node using Annotations
4. Perform SharePoint operations using Client Object Model
Step 1
Create a Windows Class Library project and add references to
-
Microsoft.VisualStudio.SharePoint
-
Microsoft.VisualStudio.SharePoint.Explorer.Extensions
-
System.ComponentModel.Composition
Step 2
Create a class and implement IExplorerNodeTypeExtension:
internal class FeatureNodeExtension : IExplorerNodeTypeExtension
{
}
Step 3
As we are interested in adding an item to the context menu, handle the NodeMenuItemsRequested. This is done in the Initialize method:
public void Initialize(IExplorerNodeType nodeType)
{
nodeType.NodeMenuItemsRequested +=
new EventHandler<ExplorerNodeMenuItemsRequestedEventArgs>
(nodeType_NodeMenuItemsRequested);
}
And here is the event handler:
void nodeType_NodeMenuItemsRequested(object sender, ExplorerNodeMenuItemsRequestedEventArgs e)
{
IMenuItem deactivateMenu = e.MenuItems.Add("Deactivate");
deactivateMenu.Click +=
new EventHandler<MenuItemEventArgs>(deactivateMenu_Click);
}
We add the new menu item in the event handler above and also handle its own click event.
Step 4
As we want to deactivate a feature, we need to know the Feature Definition Id. They are already available in the Properties pane for a feature:

To access the Properties we need to access it via the Annotations object. Here is the code to access the Feature properties:
IFeatureNodeInfo fn = e.Node.Annotations[typeof(IFeatureNodeInfo)] as IFeatureNodeInfo;
definitionId = fn.Id;
featureName = fn.Name;
Next thing is to get the site at which this feature is installed. As the Server Explorer has already established the connection to the site, we can get it from its current context.
IExplorerNodeContext siteContext = e.Node.Context;
Here is how my event handler looks:
void nodeType_NodeMenuItemsRequested(object sender, ExplorerNodeMenuItemsRequestedEventArgs e)
{
siteContext = e.Node.Context;
IFeatureNodeInfo fn = e.Node.Annotations[typeof(IFeatureNodeInfo)] as IFeatureNodeInfo;
definitionId = fn.Id;
featureName = fn.Name;
IMenuItem deactivateMenu = e.MenuItems.Add("Deactivate");
deactivateMenu.Click += new EventHandler<MenuItemEventArgs>(deactivateMenu_Click);
}
Step 5
We can now write code to deactivate the feature in the new menu item’s event handler using the Client Object Model:
void deactivateMenu_Click(object sender, MenuItemEventArgs e)
{
if (MessageBox.Show(confirmationMessage,String.Format("Deactivate {0} feature",featureName),
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation) == DialogResult.Yes)
{
IExplorerNode parentFeatureNode = e.Owner as IExplorerNode;
IExplorerNode featureNode = parentFeatureNode.ParentNode;
ClientContext clientContext = new ClientContext(siteContext.SiteUrl.AbsoluteUri);
Web site = clientContext.Web;
FeatureCollection siteFeatures = site.Features;
clientContext.Load(site, s => s.Title, s => s.Features);
siteFeatures.Remove(definitionId, false);
clientContext.ExecuteQuery();
clientContext.Dispose();
featureNode.Refresh();
}
}
Very simple indeed. Query and get only the Web and Features object, and then remove (deactivate) the feature from the site.
You can also do this asynchronously using the Asynchronous Pattern for Client OM.
Deploying the Extension
To deploy the extension, we need to include it in a .vsix package.
You can use the VSIX template to create the .vsix package.

Include the extension in the manifest file.

Chose the content as MEF Component and select the extensions project as your source.
Build the project to generate the .vsix package and install the package.
‘Deactivate Extension’ for FeaturesNode done
And here is our menu item in the context menu:

When you click on it, you will get a confirmation message:

Clicking Yes will deactivate the feature and refresh the Features node.
You can download the source code and VSIX package below: