in

Dot Net Mafia

Group site for developer blogs dealing with (usually) .NET, SharePoint 2013, SharePoint 2010, Office 365, SharePoint Online, and other Microsoft products, as well as some discussion of general programming related concepts.

This Blog

Syndication

Archives

Corey Roth [MVP]

A SharePoint MVP bringing you the latest time saving tips for SharePoint 2013, Office 365 / SharePoint Online and Visual Studio 2013.

How to: Programmatically Activate a Feature

Today, I am continuing my series of posts on how to do basic tasks in SharePoint.  Sometimes there is a need to activate a feature on a site collection or site using code.  There are various reasons why you want to do this, but in my case, I needed to activate multiple features on multiple sites.  The SPFeatureCollection object keeps track of which features are activated on a given site or site collection (not all features available for activation).  There are a number of ways to access it.  You can use the Features property on a given SPWeb or SPSite object.  You can also make use of the WebFeatures or SiteFeatures from SPContext.Current.  To activate a feature, call the Add method and pass it the GUID of the feature.  Be warned that it will throw an InvalidOperationException if the feature is already activated.  As with all SharePoint collections, the only way to determine if it exists is to use the indexer and see if it throws an exception.  Here is an example of activating a feature at the site level.

SPWeb currentSite = SPContext.Current.Web;

{

    currentSite.Features.Add(new Guid("{043C4BDD-9745-441a-A9A7-0BCD9B910319}"));

If you don't know the GUID of the feature but you do know the name of the Feature, you have to the FeatureDefinitions collection off of the SPFarm object.  Unfortunately, you have to iterate through the whole collection and look at the title to find the feature you need.  There is an example of it in the SDK.

Deactivating a feature is just as simple (provided you know the GUID).  In this case I am using the WebFeatures properties off of the current context.

SPContext.Current.WebFeatures.Remove(new Guid("{043C4BDD-9745-441a-A9A7-0BCD9B910319}"));

I know some might consider this a simple topic, but my goal is to help newcomers to SharePoint as much as possible.

Published Feb 22 2008, 10:01 AM by CoreyRoth
Filed under:

Comments

 

Links (2/24/2008) « Steve Pietrek’s SharePoint Stuff said:

Pingback from  Links (2/24/2008) « Steve Pietrek’s SharePoint Stuff

February 24, 2008 7:06 PM
 

willuwait said:

Looking to activate multiple features on multiple sites.  Could you post an example of your solution.

March 27, 2008 2:37 PM
 

Perry said:

SPSite.Features.Add will always appear to succeed, even returning a valid SPFeature return value.

Yet if the calling process identity is not an SCA, it will actually silently and secretly fail.

March 4, 2010 1:54 AM
 

Samuel said:

To obtain the GUID of a solution...

use powershell cmdlet

get-SPSolution

October 1, 2010 3:24 AM
 

Si said:

you shouldnt be wrapping "SPContext.Current.Web" in a using block.

October 4, 2010 2:38 AM
 

CoreyRoth said:

Ack.  Good catch.  I can't believe I did that.  I updated the post.  Thanks.

October 4, 2010 8:46 AM
 

Andreas said:

Hello Si, hello CoreyRoth,

can you please tell me why you removed the using statement for "SPWeb currentSite = SPContext.Current.Web;" as that's the way I'm working right now.

Also topic related, is there a way to activate the Enterprise Site Collection Features at once instead of activating the 10-15 features which are part of the enterprise features?

October 11, 2010 6:38 AM
 

Sam Venables said:

Andreas, he removed the using block because he wasn't the owner of the object. SharePoint instantiated that particular object, SharePoint is responsible for disposing of it - if you instantiate an SPWeb using the constructor then you own it, so you dispose of it (likewise if you use SPSite.OpenWeb(url) for instance).

If you dispose of SPContext.Current.Web then anything later in the page lifecycle that tries to access the object will not be able to find it and will throw an exception.

Roger Lamb's "SharePoint 2007 and WSS 3.0 Dispose Patterns by Example" blog really helped me get my head round this:

blogs.msdn.com/.../sharepoint-2007-and-wss-3-0-dispose-patterns-by-example.aspx

You may also want to look up "stack heap c#" - garbage collection makes it all to easy to develop in c# without understanding memory management!

October 21, 2010 12:37 AM
 

Twitter Trackbacks for How to: Programmatically Activate a Feature - Corey Roth [dotnetmafia.com] on Topsy.com said:

Pingback from  Twitter Trackbacks for                 How to: Programmatically Activate a Feature - Corey Roth         [dotnetmafia.com]        on Topsy.com

February 3, 2011 5:07 PM
 

ericmeister said:

Hi Corey,

If the feature has event receiver attached, shouldn't it also fire during activation?

I've managed to do this only via UI feature activation so far

September 22, 2011 10:31 AM
 

CoreyRoth said:

@Eric you may need to put your event receiver in a separate assembly in this case.  I've seen issues with this before.

September 27, 2011 5:58 PM
 

izzy said:

I wanna activate bbm but how

November 5, 2011 7:39 AM
 

Mike said:

It did indeed help a newbie!

Thanks!

December 15, 2011 3:40 PM
 

Wim Hill said:

Hi Corey,

What if you need to activate a feature (SharePoint Server Publishing Infrastructure)  with a less privileged account. Your code works when I run it as a site collection admin but fails even when I put the following code arround it:

SPSecurity.RunWithElevatedPrivileges(delegate(){          

 SPSite CurrentSite = SPContext.Current.Site;            

CurrentSite.AllowUnsafeUpdates = true;

CurrentSite.Features.Add(new Guid("{f6924d36-2fa8-4f0b-b16d-06b7250180fa}"));

CurrentSite.AllowUnsafeUpdates = false; });

}

The page thows an access denied and I see the following in the logs:

Feature Activation: Activating Feature 'PublishingPrerequisites' (ID: 'a392da98-270b-4e85-9769-04c0fde267aa') at URL

Feature Activation: Threw an exception, attempting to roll back.  Feature 'PublishingPrerequisites' (ID: 'a392da98-270b-4e85-9769-04c0fde267aa').  Exception: System.Threading.ThreadAbortException: Thread was being aborted.    

at System.Threading.Thread.AbortInternal()    

at System.Threading.Thread.Abort(Object stateInfo)    

at System.Web.HttpResponse.End()    

at Microsoft.SharePoint.Utilities.SPUtility.Redirect(String url, SPRedirectFlags flags, HttpContext context, String queryString)    

at Microsoft.SharePoint.Utilities.SPUtility.RedirectToAccessDeniedPage(HttpContext context)    

at Microsoft.SharePoint.Utilities.SPUtility.HandleAccessDenied(HttpContext context)    

at Microsoft.SharePoint.Utilities.SPUtility.HandleAccessDenied(Exception ex)    

at Microsoft.SharePoint.SPSecurableObject.CheckPermissions(SPBasePermissions permissionMask)    

at Microsoft.SharePoint.SPSecurity.ValidateSecurityOnOperation(SPOperationCode code, SPSecurableObject obj)    

at Microsoft.SharePoint.SPFeature.AddRowToFeaturesTable(SPFeaturePropertyCollection props, SPSite site, SPWeb web, Boolean fForce)    

at Microsoft.SharePoint.SPFeature.Activate(SPSite siteParent, SPWeb webParent, SPFeaturePropertyCollection props, Boolean fForce)

January 25, 2012 2:17 AM
 

CoreyRoth said:

@Wim activating the publishing infrastructure feature requires pretty hefty permissions.  I don't think you'll have much luck activating it with a low-privilege user even if you do delegate.

February 6, 2012 11:56 PM
 

Ishai Sagi said:

Actually, @Wim's issue is due to the fact he is getting the SPSite object from the context object inside the SPSecurity delegate. This instantiates the object with default permissions - not with elevated ones. Instead, do something like:

SPSite CurrentSite = SPContext.Current.Site;

SPSecurity.RunWithElevatedPrivileges(delegate(){          

using (SPSite currentSiteElevated = new SPSite(CurrentSite.ID))

{

currentSiteElevated .AllowUnsafeUpdates = true;

currentSiteElevated .Features.Add(new Guid("{f6924d36-2fa8-4f0b-b16d-06b7250180fa}"));

currentSiteElevated .AllowUnsafeUpdates = false; });

}

March 11, 2012 5:44 PM

Leave a Comment

(required)  
(optional)
(required)  
Add

About CoreyRoth

Corey Roth is an Applications Architect at Infusion specializing in ECM and Search.
2012 dotnetmafia.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems