public void FeatureCollectionRemoveTest() { FeatureCollection collection = new FeatureCollection(this.identifier, this.mockAttributes, this.mockFeatures.Take(1)); collection.Remove(this.mockFeatures[0]).ShouldBeTrue(); collection.Count.ShouldBe(0); collection.Contains(this.mockFeatures[0]).ShouldBeFalse(); Should.Throw <ArgumentNullException>(() => collection.Remove(null)); }
private static bool RemoveFeatureFromWeb(ClientContext userContext, Guid featureDefinitionId) { try { FeatureCollection features = userContext.Web.Features; ClearObjectData(features); userContext.Load(features); userContext.ExecuteQuery(); //DumpFeatures(features, "web"); Feature targetFeature = features.GetById(featureDefinitionId); targetFeature.EnsureProperties(f => f.DefinitionId); if (targetFeature == null || !targetFeature.IsPropertyAvailable("DefinitionId") || targetFeature.ServerObjectIsNull.Value) { Logger.LogInfoMessage(String.Format("Could not delete Feature {0}; feature not found in web.Features", featureDefinitionId.ToString()), false); return(false); } features.Remove(featureDefinitionId, true); // commit the changes userContext.Load(features); userContext.ExecuteQuery(); return(true); } catch (Exception ex) { Logger.LogErrorMessage(String.Format("RemoveFeatureFromWeb() failed for Feature {0} on web {1}; Error={2}", featureDefinitionId.ToString(), userContext.Web.Url, ex.Message), false); return(false); } }
private static bool RemoveFeatureFromSite(ClientContext userContext, Guid featureDefinitionId) { try { FeatureCollection features = userContext.Site.Features; ClearObjectData(features); userContext.Load(features); userContext.ExecuteQuery(); //DumpFeatures(features, "site"); Feature targetFeature = features.GetById(featureDefinitionId); targetFeature.EnsureProperties(f => f.DefinitionId); if (targetFeature == null || !targetFeature.IsPropertyAvailable("DefinitionId") || targetFeature.ServerObjectIsNull.Value) { Logger.LogInfoMessage(String.Format("Could not delete Feature {0}; feature not found in site.Features", featureDefinitionId.ToString()), false); return(false); } features.Remove(featureDefinitionId, true); // commit the changes userContext.Load(features); userContext.ExecuteQuery(); return(true); } catch (Exception ex) { Logger.LogErrorMessage(String.Format("[DeleteMissingFeatures: RemoveFeatureFromSite] failed for Feature {0} on site {1}; Error={2}", featureDefinitionId.ToString(), userContext.Site.Url, ex.Message), true); ExceptionCsv.WriteException(Constants.NotApplicable, userContext.Site.Url, Constants.NotApplicable, "Feature", ex.Message, ex.ToString(), "RemoveFeatureFromSite", ex.GetType().ToString(), String.Format("RemoveFeatureFromSite() failed for Feature {0} on site {1}", featureDefinitionId.ToString(), userContext.Site.Url)); return(false); } }
/// <summary> /// Activates or deactivates a site collection or web scoped feature /// </summary> /// <param name="features">Feature Collection which contains the feature</param> /// <param name="featureID">ID of the feature to activate/deactivate</param> /// <param name="activate">True to activate, false to deactivate the feature</param> /// <param name="scope">Scope of the feature definition</param> /// <param name="pollingIntervalSeconds">The time in seconds between polls for "IsActive"</param> private static void ProcessFeatureInternal(FeatureCollection features, Guid featureID, bool activate, FeatureDefinitionScope scope, int pollingIntervalSeconds = 30) { if (activate) { // Feature enabling can take a long time, especially in case of the publishing feature...so let's make it more reliable bool cancel = false; features.Add(featureID, true, scope); if (pollingIntervalSeconds < 5) { pollingIntervalSeconds = 5; } // Kick off a thread that checks for the feature activation to be complete Task.Run(() => { while (!cancel) { Thread.Sleep(TimeSpan.FromSeconds(pollingIntervalSeconds)); if (!cancel) { cancel = IsFeatureActiveInternal(features, featureID); Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureActivationState, cancel, featureID); } } }); // Kick off a thread that enables the feature Task.Run(() => { try { features.Context.ExecuteQueryRetry(); Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureActive, featureID); } catch (Exception ex) { Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureException, ex.ToString()); } finally { cancel = true; } }).Wait(); } else { try { features.Remove(featureID, false); features.Context.ExecuteQueryRetry(); } catch (Exception ex) { Log.Error(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_FeatureActivationProblem, featureID, ex.Message); } } }
public void DeactivateFeature() { if (this.Definition != null) { FeatureCollection.Remove(this.Definition.Id, true); this.SPObject = null; this.Activated = false; } }
public void RemoveTest() { IFeature feature = new Feature(); FeatureCollection target = new FeatureCollection(new Collection <IFeature> { feature }); const bool expected = true; bool actual = target.Remove(feature); Assert.AreEqual(expected, actual); Assert.AreEqual(0, target.Count); }
private static void DeActivateFeatureInCollection(ClientContext clientContext, GtFeature featureInfo, FeatureCollection featureCollection) { clientContext.Load(featureCollection); clientContext.ExecuteQuery(); if (DoesFeatureExistInCollection(featureCollection, featureInfo.FeatureId)) { Console.WriteLine("Deactivating feature " + featureInfo.FeatureName); featureCollection.Remove(featureInfo.FeatureId, true); clientContext.ExecuteQuery(); } }
public void RemovedInterfaceIsRemoved() { var interfaces = new FeatureCollection(); var thing = new Thing(); interfaces.Add(typeof(IThing), thing); Assert.Equal(interfaces[typeof(IThing)], thing); Assert.True(interfaces.Remove(typeof(IThing))); object thing2; Assert.False(interfaces.TryGetValue(typeof(IThing), out thing2)); }
/// <summary> /// Activates or deactivates a site collection or site scoped feature /// </summary> /// <param name="web">Web to be processed - can be root web or sub web</param> /// <param name="featureID">ID of the feature to activate/deactivate</param> /// <param name="activate">True to activate, false to deactivate the feature</param> private static void ProcessFeature(this Web web, Guid featureID, bool activate) { FeatureCollection clientSiteFeatures = web.Features; web.Context.Load(clientSiteFeatures); web.Context.ExecuteQuery(); // The original number of active features...use this to track if the feature activation went OK int oldCount = clientSiteFeatures.Count(); if (activate) { // GetById does not seem to work for site scoped features...if (clientSiteFeatures.GetById(featureID) == null) // FeatureDefinitionScope defines how the features have been deployed. All OOB features are farm deployed clientSiteFeatures.Add(featureID, true, FeatureDefinitionScope.Farm); web.Context.ExecuteQuery(); // retry logic needed to make this more bulletproof :-( web.Context.Load(clientSiteFeatures); web.Context.ExecuteQuery(); int tries = 0; int currentCount = clientSiteFeatures.Count(); while (currentCount <= oldCount && tries < 5) { tries++; clientSiteFeatures.Add(featureID, true, FeatureDefinitionScope.Farm); web.Context.ExecuteQuery(); web.Context.Load(clientSiteFeatures); web.Context.ExecuteQuery(); currentCount = clientSiteFeatures.Count(); } } else { try { clientSiteFeatures.Remove(featureID, false); web.Context.ExecuteQuery(); } catch (Exception ex) { LoggingUtility.LogError(string.Format(MSG_PROBLEM_REMOVING, featureID), ex, EventCategory.Features); } } }
/// <summary> /// Activates or deactivates a site collection or site scoped feature /// </summary> /// <param name="site">Site to be processed</param> /// <param name="featureID">ID of the feature to activate/deactivate</param> /// <param name="activate">True to activate, false to deactivate the feature</param> public static void ProcessFeature(this Site site, Guid featureID, bool activate) { FeatureCollection clientSiteFeatures = site.Features; site.Context.Load(clientSiteFeatures); site.Context.ExecuteQuery(); // The original number of active features...use this to track if the feature activation went OK int oldCount = clientSiteFeatures.Count(); if (activate) { // GetById does not seem to work for site scoped features...if (clientSiteFeatures.GetById(featureID) == null) // FeatureDefinitionScope defines how the features have been deployed. All OOB features are farm deployed clientSiteFeatures.Add(featureID, true, FeatureDefinitionScope.Farm); site.Context.ExecuteQuery(); // retry logic needed to make this more bulletproof :-( site.Context.Load(clientSiteFeatures); site.Context.ExecuteQuery(); int tries = 0; int currentCount = clientSiteFeatures.Count(); while (currentCount <= oldCount && tries < 5) { tries++; clientSiteFeatures.Add(featureID, true, FeatureDefinitionScope.Farm); site.Context.ExecuteQuery(); site.Context.Load(clientSiteFeatures); site.Context.ExecuteQuery(); currentCount = clientSiteFeatures.Count(); } } else { try { clientSiteFeatures.Remove(featureID, false); site.Context.ExecuteQuery(); } catch (Exception ex) { throw; } } }
/// <summary> /// Activates or deactivates a site collection or web scoped feature /// </summary> /// <param name="features">Feature Collection which contains the feature</param> /// <param name="featureID">ID of the feature to activate/deactivate</param> /// <param name="activate">True to activate, false to deactivate the feature</param> private static void ProcessFeatureInternal(FeatureCollection features, Guid featureID, bool activate) { features.Context.Load(features); features.Context.ExecuteQueryRetry(); // The original number of active features...use this to track if the feature activation went OK int oldCount = features.Count(); if (activate) { // GetById does not seem to work for site scoped features...if (clientSiteFeatures.GetById(featureID) == null) // FeatureDefinitionScope defines how the features have been deployed. All OOB features are farm deployed features.Add(featureID, true, FeatureDefinitionScope.Farm); features.Context.ExecuteQueryRetry(); // retry logic needed to make this more bulletproof :-( features.Context.Load(features); features.Context.ExecuteQueryRetry(); int tries = 0; int currentCount = features.Count(); while (currentCount <= oldCount && tries < 5) { tries++; features.Add(featureID, true, FeatureDefinitionScope.Farm); features.Context.ExecuteQueryRetry(); features.Context.Load(features); features.Context.ExecuteQueryRetry(); currentCount = features.Count(); } } else { try { features.Remove(featureID, false); features.Context.ExecuteQueryRetry(); } catch (Exception ex) { Log.Error(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_FeatureActivationProblem, featureID, ex.Message); } } }
void DeActivateMenuItem_Click(object sender, EventArgs e) { Cursor.Current = Cursors.WaitCursor; FeatureCollection.Remove(Definition.Id, true); FeatureCollectionNode nodeCollection = (FeatureCollectionNode)this.Parent; this.ImageIndex = nodeCollection.UnInstalledIndex; this.SelectedImageIndex = nodeCollection.UnInstalledIndex; this.IsInstalled = false; //Program.Window.Explorer.SelectedNode = null; //Program.Window.Explorer.SelectedNode = this; Cursor.Current = Cursors.Default; }
/// <summary> /// Activates or deactivates a site collection or web scoped feature /// </summary> /// <param name="features">Feature Collection which contains the feature</param> /// <param name="featureID">ID of the feature to activate/deactivate</param> /// <param name="activate">True to activate, false to deactivate the feature</param> /// <param name="scope">Scope of the feature definition</param> private static void ProcessFeatureInternal(FeatureCollection features, Guid featureID, bool activate, FeatureDefinitionScope scope) { features.Context.Load(features); features.Context.ExecuteQueryRetry(); // The original number of active features...use this to track if the feature activation went OK int oldCount = features.Count(); if (activate) { // GetById does not seem to work for site scoped features...if (clientSiteFeatures.GetById(featureID) == null) // FeatureDefinitionScope defines how the features have been deployed. All OOB features are farm deployed features.Add(featureID, true, scope); features.Context.ExecuteQueryRetry(); // retry logic needed to make this more bulletproof :-( features.Context.Load(features); features.Context.ExecuteQueryRetry(); int tries = 0; int currentCount = features.Count(); while (currentCount <= oldCount && tries < 5) { tries++; features.Add(featureID, true, scope); features.Context.ExecuteQueryRetry(); features.Context.Load(features); features.Context.ExecuteQueryRetry(); currentCount = features.Count(); } } else { try { features.Remove(featureID, false); features.Context.ExecuteQueryRetry(); } catch (Exception ex) { Log.Error(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_FeatureActivationProblem, featureID, ex.Message); } } }
/// <summary> /// Activates or deactivates a site collection or web scoped feature /// </summary> /// <param name="features">Feature Collection which contains the feature</param> /// <param name="featureID">ID of the feature to activate/deactivate</param> /// <param name="activate">True to activate, false to deactivate the feature</param> /// <param name="scope">Scope of the feature definition</param> /// <param name="pollingIntervalSeconds">The time in seconds between polls for "IsActive"</param> private static async Task ProcessFeatureInternal(FeatureCollection features, Guid featureID, bool activate, FeatureDefinitionScope scope, int pollingIntervalSeconds = 30) { if (activate) { // Feature enabling can take a long time, especially in case of the publishing feature...so let's make it more reliable features.Add(featureID, true, scope); if (pollingIntervalSeconds < 5) { pollingIntervalSeconds = 5; } try { string clientTag = $"{PnPCoreUtilities.PnPCoreVersionTag}:ProcessFeatureInternal"; if (clientTag.Length > 32) { clientTag = clientTag.Substring(0, 32); } features.Context.ClientTag = clientTag; // Don't update this to ExecuteQueryRetry await features.Context.ExecuteQueryAsync(); Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureActive, featureID); } catch (Exception ex) { Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureException, ex.ToString()); // Don't wait for a "feature not found" exception, which is the typical exception we'll see if (ex.HResult != -2146233088) { int retryAttempts = 10; int retryCount = 0; // wait and keep checking if the feature is active while (retryAttempts > retryCount) { Thread.Sleep(TimeSpan.FromSeconds(pollingIntervalSeconds)); if (await IsFeatureActiveInternal(features, featureID, true)) { retryCount = retryAttempts; Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureActivationState, true, featureID); } else { retryCount++; Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureActivationState, false, featureID); } } } } } else { try { features.Remove(featureID, false); await features.Context.ExecuteQueryRetryAsync(); } catch (Exception ex) { Log.Error(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_FeatureActivationProblem, featureID, ex.Message); } } }
private void ProcessFeature( object modelHost, ClientRuntimeContext context, FeatureCollection features, FeatureDefinition featureModel, Microsoft.SharePoint.Client.FeatureDefinitionScope scope) { var currentFeature = GetFeature(features, featureModel); var featureActivated = IsFeatureActivated(features, featureModel); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioning, Object = currentFeature, ObjectType = typeof(Feature), ObjectDefinition = featureModel, ModelHost = modelHost }); if (!featureActivated) { Feature tmpFeature; if (featureModel.Enable) { tmpFeature = features.Add(featureModel.Id, featureModel.ForceActivate, scope); context.ExecuteQuery(); } else { tmpFeature = GetFeature(features, featureModel); } InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioned, Object = tmpFeature, ObjectType = typeof(Feature), ObjectDefinition = featureModel, ModelHost = modelHost }); } else { if (featureModel.Enable && featureModel.ForceActivate) { var f = features.Add(featureModel.Id, featureModel.ForceActivate, scope); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioned, Object = f, ObjectType = typeof(Feature), ObjectDefinition = featureModel, ModelHost = modelHost }); context.ExecuteQuery(); } else if (!featureModel.Enable) { features.Remove(featureModel.Id, featureModel.ForceActivate); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioned, Object = null, ObjectType = typeof(Feature), ObjectDefinition = featureModel, ModelHost = modelHost }); context.ExecuteQuery(); } else { var tmpFeature = GetFeature(features, featureModel); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioned, Object = tmpFeature, ObjectType = typeof(Feature), ObjectDefinition = featureModel, ModelHost = modelHost }); } } }
private void ProcessFeature( object modelHost, ClientRuntimeContext context, FeatureCollection features, FeatureDefinition featureModel, Microsoft.SharePoint.Client.FeatureDefinitionScope scope) { var featureId = featureModel.Id; var currentFeature = features.GetById(featureId); features.Context.ExecuteQueryWithTrace(); var featureActivated = IsFeatureActivated(currentFeature); TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Is feature activated: [{0}]", featureActivated); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioning, Object = currentFeature, ObjectType = typeof(Feature), ObjectDefinition = featureModel, ModelHost = modelHost }); if (!featureActivated) { Feature tmpFeature; if (featureModel.Enable) { TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Enabling feature"); tmpFeature = SafelyActivateWebFeature(context, features, featureModel, scope); } else { TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Fetching feature by ID"); tmpFeature = features.GetById(featureId); features.Context.ExecuteQueryWithTrace(); } InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioned, Object = tmpFeature, ObjectType = typeof(Feature), ObjectDefinition = featureModel, ModelHost = modelHost }); } else { if (featureModel.Enable && featureModel.ForceActivate) { TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Feature enabled, but ForceActivate = true. Force activating."); var f = SafelyActivateWebFeature(context, features, featureModel, scope); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioned, Object = f, ObjectType = typeof(Feature), ObjectDefinition = featureModel, ModelHost = modelHost }); } else if (!featureModel.Enable) { TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Removing feature."); features.Remove(featureModel.Id, featureModel.ForceActivate); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioned, Object = null, ObjectType = typeof(Feature), ObjectDefinition = featureModel, ModelHost = modelHost }); context.ExecuteQueryWithTrace(); } else { TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Fetching feature by ID"); var tmpFeature = features.GetById(featureId); features.Context.ExecuteQueryWithTrace(); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioned, Object = tmpFeature, ObjectType = typeof(Feature), ObjectDefinition = featureModel, ModelHost = modelHost }); } } }
static void Main(string[] args) { // Request Office365 site from the user string siteUrl = GetSite(); /* Prompt for Credentials */ Console.WriteLine("Enter Credentials for {0}", siteUrl); string userName = GetUserName(); SecureString pwd = GetPassword(); /* End Program if no Credentials */ if (string.IsNullOrEmpty(userName) || (pwd == null)) { return; } // Get access to source site using (var ctx = new ClientContext(siteUrl)) { ctx.AuthenticationMode = ClientAuthenticationMode.Default; ctx.Credentials = new SharePointOnlineCredentials(userName, pwd); Web web = ctx.Web; var allProperties = web.AllProperties; ctx.Load(web); ctx.Load(allProperties); ctx.ExecuteQuery(); UploadAssetsToHostWeb(web); // Actual code for operations // Set the properties accordingly // Notice that these are new properties in 2014 April CU of 15 hive CSOM and July release of MSO CSOM web.AlternateCssUrl = ctx.Web.ServerRelativeUrl + "/SiteAssets/spe-seattle-responsive.css"; // Ensure proper meta tag for viewport is set // Make sure that hardware devices scale CSS definitions properly // More details can be found http://www.n8d.at/blog/how-to-add-viewport-meta-without-editing-the-master-page/ // Check if SEO is enabled and property for custom meta tags exists // This can be enabled on any team site based site collection by enabling // the site collection feature "Publishing Infastructure" // No other publishing related feature needs to be activated // Enable custom meta tags if (allProperties.FieldValues.ContainsKey("seoincludecustommetatagpropertyname")) { allProperties["seoincludecustommetatagpropertyname"] = true.ToString(); } // Add value of custom meta tag if (allProperties.FieldValues.ContainsKey("seocustommetatagpropertyname")) { allProperties["seocustommetatagpropertyname"] = "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\" />"; } web.Update(); web.Context.ExecuteQuery(); // get features collection on web FeatureCollection features = web.Features; web.Context.Load(features); web.Context.ExecuteQuery(); // disable the 'Mobile Browser View' web feature Guid featureId = new Guid("d95c97f3-e528-4da2-ae9f-32b3535fbb59"); if (Enumerable.Any(features, feature => feature.DefinitionId == featureId)) { features.Remove(new Guid("d95c97f3-e528-4da2-ae9f-32b3535fbb59"), false); web.Context.ExecuteQuery(); } /// Uncomment to clear // Removes alternate CSS URL //web.AlternateCssUrl = ""; // Clear viewport meta tag form SEO settings //if (allProperties.FieldValues.ContainsKey("seoincludecustommetatagpropertyname")) //{ // allProperties["seoincludecustommetatagpropertyname"] = false.ToString(); //} // Add value of custom meta tag //if (allProperties.FieldValues.ContainsKey("seocustommetatagpropertyname")) //{ // allProperties["seocustommetatagpropertyname"] = "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\" />"; //} //web.Update(); //web.Context.ExecuteQuery(); } }
/// <summary> /// Activates or deactivates a site collection or web scoped feature /// </summary> /// <param name="features">Feature Collection which contains the feature</param> /// <param name="featureID">ID of the feature to activate/deactivate</param> /// <param name="activate">True to activate, false to deactivate the feature</param> /// <param name="scope">Scope of the feature definition</param> /// <param name="pollingIntervalSeconds">The time in seconds between polls for "IsActive"</param> private static void ProcessFeatureInternal(FeatureCollection features, Guid featureID, bool activate, FeatureDefinitionScope scope, int pollingIntervalSeconds = 30) { if (activate) { // Feature enabling can take a long time, especially in case of the publishing feature...so let's make it more reliable features.Add(featureID, true, scope); if (pollingIntervalSeconds < 5) { pollingIntervalSeconds = 5; } try { string clientTag = $"{PnPCoreUtilities.PnPCoreVersionTag}:ProcessFeatureInternal"; if (clientTag.Length > 32) { clientTag = clientTag.Substring(0, 32); } features.Context.ClientTag = clientTag; // Don't update this to ExecuteQueryRetry features.Context.ExecuteQuery(); Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureActive, featureID); } catch (Exception ex) { Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureException, ex.ToString()); // Don't wait for a "feature not found" exception, which is the typical exception we'll see if (ex.HResult != -2146233088) { int retryAttempts = 10; int retryCount = 0; // wait and keep checking if the feature is active while (retryAttempts > retryCount) { Thread.Sleep(TimeSpan.FromSeconds(pollingIntervalSeconds)); if (IsFeatureActiveInternal(features, featureID, true)) { retryCount = retryAttempts; Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureActivationState, true, featureID); } else { retryCount++; Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureActivationState, false, featureID); } } } } } else { try { features.Remove(featureID, false); features.Context.ExecuteQueryRetry(); } catch (Exception ex) { Log.Error(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_FeatureActivationProblem, featureID, ex.Message); } } }
/// <summary> /// Activates or deactivates a site collection or web scoped feature /// </summary> /// <param name="features">Feature Collection which contains the feature</param> /// <param name="featureID">ID of the feature to activate/deactivate</param> /// <param name="activate">True to activate, false to deactivate the feature</param> /// <param name="scope">Scope of the feature definition</param> /// <param name="pollingIntervalSeconds">The time in seconds between polls for "IsActive"</param> private static void ProcessFeatureInternal(FeatureCollection features, Guid featureID, bool activate, FeatureDefinitionScope scope, int pollingIntervalSeconds = 30) { if (activate) { // Feature enabling can take a long time, especially in case of the publishing feature...so let's make it more reliable bool cancel = false; features.Add(featureID, true, scope); if (pollingIntervalSeconds < 5) { pollingIntervalSeconds = 5; } // Kick off a thread that checks for the feature activation to be complete Task.Run(() => { while (!cancel) { Thread.Sleep(TimeSpan.FromSeconds(pollingIntervalSeconds)); if (!cancel) { cancel = IsFeatureActiveInternal(features, featureID); Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureActivationState, cancel, featureID); } } }); // Kick off a thread that enables the feature Task.Run(() => { try { features.Context.ExecuteQueryRetry(); Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureActive, featureID); } catch(Exception ex) { Log.Info(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_ProcessFeatureInternal_FeatureException, ex.ToString()); } finally { cancel = true; } }).Wait(); } else { try { features.Remove(featureID, false); features.Context.ExecuteQueryRetry(); } catch (Exception ex) { Log.Error(Constants.LOGGING_SOURCE, CoreResources.FeatureExtensions_FeatureActivationProblem, featureID, ex.Message); } } }
private static void DeActivateFeatureInCollection(ClientContext clientContext, ShFeature featureInfo, FeatureCollection featureCollection) { clientContext.Load(featureCollection); clientContext.ExecuteQuery(); if (DoesFeatureExistInCollection(featureCollection, featureInfo.FeatureId)) { Log.Info("Deactivating feature " + featureInfo.FeatureName); featureCollection.Remove(featureInfo.FeatureId, true); clientContext.ExecuteQuery(); } }