Deploying features with activation dependencies
-
Tuesday, February 15, 2011 8:53 AM
I have a problem in Visual Studio when deploying a solution with activationdependencies. The scenario is as follows:
I have two features A and B, both are site scoped. A has an activation dependency on B and B is hidden. When deploying the solution Visual Studio tries to activate both features. First it activates A. This automatically activates B since it's hidden. Then when Visual Studio tries to activate B it failes with the error: "Error occurred in deployment step 'Activate Features': Feature 'B' (ID: <feature id>) is already activated at scope '<site url>'."
I solved this by installing Mavention Activate Selected Features and selecting only feature A for activation.
The next problem arises when trying to retract or do a second deploy. Visual Studio will again try to deactivate both features. First A is deactivated and because of the activation dependency and that feature B is hidden this will simultaneously deactivate B. When Visual Studio then tries to deactivate B it fails with the error: "Error occurred in deployment step 'Retract Solution': Feature '<feature id>' is not activated at this scope."
Possible solutions that I can think of:
B is deactivated before A. (I have not found a reliable way of controlling the order of deactivation)
B is never deactivated directly by Visual Studio. (I have not found an equivalent of Mavention Activate Selected Features for feature deactivation)
Visual Studio ignores the error caused when the feature is not activated.Does anyone have a solution for this?
- Edited by JensOtto Tuesday, February 15, 2011 12:34 PM Wrong error message on activate feature
All Replies
-
Tuesday, February 15, 2011 9:20 AM
Hi!
Have you tried not to activate solution B from the project parameters in Vistual Studio and deploy the solution like this?
In the project menu select "your project name" properties and then the SharePoint tab, here you can set the behavior of your project, expecially Active Deployment Configuration. You can specify if activate or not the feature at deploy time.
I whould say not to activate (and not deactivate it at retract time) feature B since solution A is going to automatically activate and deactivate B.
It could be this because you are trying to decativate or activate a feature, but during deploy it has already been done.
Nicola.
-
Tuesday, February 15, 2011 9:49 AM
Hi
I have already configured the deployment so that feature B is not activated during the feature activation procedure (made possible by the Mavention Activate Selected Features Extension).
It's the Retract Solution step that does the feature deactivation, and this is not configurable as to which features to deactivate. It appears that it queries the SharePoint site for the active features that are part of the solution and deactivates all that are already activated. Visual Studio will then fail when trying to deactivate a feature that is not activated (feature B). The feature is deactivated because of the feature dependency and that the dependent feature is hidden.To clean the solution I guess I need to keep the Reatract Solution step in the Deployment Configuration. So it's not an option to remove that step.
J.O.
-
Tuesday, February 15, 2011 11:09 AM
Can you build two different packages/solutions?
B -> no activation -> deploy it
A -> deploy it
A will find B and will activate it
as you retract A it will deactivate B
then retract B.
Anyway it's a developing scenario, plan it for production too.
-
Tuesday, February 15, 2011 11:18 AM
Yes, that would work but I don't want to have two wsp files or two projects for that matter.
This is only an issue when deploying from Visual Studio. Solution deployment works just fine in a production environment.
J.O.
-
Tuesday, February 15, 2011 12:03 PM
ok,
do not activate/deactivate your project automatically at deploy/retract time, turn it on manually from sharepoint...
-
Tuesday, February 15, 2011 12:23 PM
That is unfortunately not possible. Removing the Retract step from the Deployment Configuration will cripple the development experience. Activating/deactivating manually will create a major development overhead.
The closest I have come to a solution is to do the deploy twice. The first deploy failes, and the second deploy completes. The problem with this is that a deploy can take a long time to complete for large solutions, and features that should have been deactivated after the failing deactivation does not get deactivated.
I have to see to other solutions or wait for a fix in Visual Studio SharePoint Developer Tools that remedies this issue.
Thanks for trying to help.
J.O.
-
Tuesday, February 15, 2011 5:08 PM
Why not override featureactivation, and first check to see if the required supporting feature is activated, if not, activate it?
Something like:
class FeatureReceiver : SPFeatureReceiver { public override void FeatureActivating(SPFeatureReceiverProperties properties) { SPWeb web = (SPWeb)properties.Feature.Parent; SPFeatureCollection _features = web.Site.Features; bool featureActive = false; SPFeatureDefinition myFeatureDef = web.Site.FeatureDefinitions["FeatureName"]; foreach (SPFeature feature in _features) { if (feature.Definition == myFeatureDef) { featureActive = true; } } if (!featureActive) { web.Site.Features.Add(myFeatureDef.Id, true); } } }
- Proposed As Answer by Ryan T Mann Tuesday, February 15, 2011 5:44 PM
- Unproposed As Answer by JensOtto Tuesday, February 15, 2011 6:44 PM
-
Tuesday, February 15, 2011 5:48 PM
Why not override featureactivation, and first check to see if the required supporting feature is activated, if not, activate it?
Something like:
class FeatureReceiver : SPFeatureReceiver { public override void FeatureActivating(SPFeatureReceiverProperties properties) { SPWeb web = (SPWeb)properties.Feature.Parent; SPFeatureCollection _features = web.Site.Features; bool featureActive = false ; SPFeatureDefinition myFeatureDef = web.Site.FeatureDefinitions["FeatureName" ]; foreach (SPFeature feature in _features) { if (feature.Definition == myFeatureDef) { featureActive = true ; } } if (!featureActive) { web.Site.Features.Add(myFeatureDef.Id, true ); } } }
This is the only way I've found that you can depend on a feature that isn't part of your visual studio project. The problem is visual studio isn't smart enough to know the dependent feature is outside of the project. As such it doesn't know to deactivate it in line with it's usualy Retract Deploy pattern. And when it activates FeatureA it's oblivous to the fact that FeatureA is going to Activate Feature B because it's dependent, and tries to activate it but it's already activated so it errors out.
Using MaartenSundman's example is how I handle all my OOTB feature dependencies in my custom WSP's. Actually the way I do it, is I create a new Feature in my project called "PreRequisites". In the PreRequisites feature I check if all the OOTB dependencies are activated. I also check that necessary service appication proxies are associated with the Site Collection. Then I set that as a Feature.Xml Dependency of all my other features in the project so you can't activate any my features if "PreRequisites" hasn't been activated.
-
Tuesday, February 15, 2011 6:44 PM
Hi
Thansk for the suggestions.
What you propose is similar to what is done in the PublishingPrerequisites feature in SharePoint. This feature is automatically activated through activationdependency when activating the PublishingSite feature. This is also more or less the same as what I try to do.
The reason that it works for you is that you do not mark the PreRequisites feature (corresponds to my feature B) as hidden. SharePoint doesn't automatically activate/deactivate dependent features that are visible. Visual Studio will therefore not fail when deploying/retracting the solution. This also defeates the purpose of what I try to do, because as a user you should not need to care about nor need to manually activate the PreRequisites feature.
ActivationDependencies also provides mechanism to automatically deactivate the dependent feature. The power with this is that the feature is not automatically deactivated until the last feature that is dependent upon it is deactivated. This can't easily be implemented and enforced in custom code.
Both solution that you have presented can work but have its limitation and is not as powerfull as activation dependencies.
J.O.
-
Tuesday, February 15, 2011 6:55 PM
You have all features activated from a single feature and hide the others, this solution does exactly what you suggest it doesn't do. It depends on method of implementation as with all things. But you can do the exact scenario you outline above with the featurereceiver Activating and Deactivating events. While it's not as simple as setting a dependency in visual studio it is far more powerful.
For the second part you have that you can't easily deactivate, but this code works fine with only 3 lines of code different for doing exactly that:
FeatureActivating -> FeatureDeactivating
if(featureActive) {
web.Site.Features.Remove(myFeatureDef.Id, true);
}
simple :)
-
Tuesday, February 15, 2011 7:12 PM
Yes, thats true, but this will deactivate feature B even if another activated feature also depends upon it. This is one of the things that feature dependencies guards against (unless you deactivate B manually).
I guess I need to state again that this is a development issue only, and not a problem in the final solution deployed to production. Activation dependencies works just great in SharePoint, but there seems to be a flaw in Visual Studio that results in deployment and retraction issues. I've almost overcome these issues except when deactivating the features (in the retract step).
No need to make a workaround for something that works. The problem is Visual Studio and not SharePoint.
J.O.
-
Tuesday, February 15, 2011 7:24 PM
Ativate your dependency in a feature reciver of the feature that depends on it. if you check SPWeb.Features to see if it exists first, and only activate it if SPWeb.Features['featureguidhere'] returns null, then visual studio will deploy it without issue. And it won't get deactivated when visual studio retracts the solution because you haven;t coded a Deactivating Method in the feature receiver.
Make sense?
-
Tuesday, February 15, 2011 7:25 PM
Actually, post the Guid of the feature your depending on, and I'll write you an exact solution just to demonstrate MaartenSundman's above suggestion.
If you create a feature called 'PreRequisites' and activate your dependencies with proper code checks like in the above example. You can have your feature depend on PreRequisites instead of the Actual OOTB (out of project) feature. Visual studio will deactivate prerequisites (that doesn't mean it deactivates the features prerequisites activated, those will stay activated) , Prerequisites is a wrapper dependency activator, think of it that way. As long as you don't implement "Deactivating" in PreRequisites Feature Receiver visual studio will activate PreRequisites and by doing so Activate your dependent features, but it won't deactivate your dependent features when visual studio activates PreRequisites.So heres a run down pseudo example,
Feature A depends On Feature B,1. Create a new Feature in your project Called PreRequisites or (FeatureBDependency) etc.
2. Add code to PreRequisites Event receiver to check if FeatureB Is activated on the Site the feature is being deployed to (SPSite site = FeatureProperties.Feature.Parent as SPSite)
3. If FeatureB is not activated use PreRequisites Activated Event in it's feature receiver to Activate FeatureB on the site.
4. If FeatureB is already activated, Do nothing, just exit
5. Don't implement prerequisites Deactivating event in it's feature receiver, leave it commented out.
6. Add Remove the dependency of FeatureB from FeatureA.
7. Add PreRequisites as a dependency of FeatureA (thus inadvertently adding FeatureB as a dependency via a proxy feature 'A term I invented' might be a better way of labeling this that has already been in use.).
8. Deploy your project. (assume this is the first deploy)
9. Visual studio will deploy the solution
10. Then it will activate features., Because Feature A depends on PreRequisites it will activate PreRequisites first.
11. Prerequisites Feature receiver will activate Feature B if it's not already activated.
12. Then visual studio will activate Feature A
Now, when you redeploy your solution.
Repeat all the above, but when Visual studio activates PreRequisites, it won't do anything because FeatureB was already activated by a previous activation of the PreRequisites feature.
-
Tuesday, February 15, 2011 7:29 PM
Hi,
Thanks, but this has already been discussed and does not provide an equivalent alternative to activation depenencies.
J.O.
-
Tuesday, February 15, 2011 7:43 PM
Anyway the PublishingFeature is already deployed, that is what I was telling you. If you retract a solution that needs the Publishing Feature you do not retract it too.
If other features or sites need to relay on your feature B, deploy it before as a separate feature, then all the others that need to use it.
I doesn't make sense that you deploy a feature that could be needed by other solutions in a solution that you know you might retract from Visual Studio...
-
Tuesday, February 15, 2011 7:47 PM
Well, the only other solution,
Open your Feature in visual studio's feature editor.
Then in the properties window, Set "Always Force Install" to true.
This will force visual studio to activate the feature. So if it errors out it will ignore it and keep on marching through the rest of the activations.
In your example, this shouldn't be a problem, because the feature is already activated, so skipping that error won't cause any harm.
However, if your FeatureA has code in it, and that code errors out, it will skip that error as well. The feature will show up in ManageFeatures.aspx as being activated, but because it errored out w/e that code was doing didn't happen.
If your feature doesn't have code and is just deploying some schema files, assuming those schema files are error free, setting Always Force Install to true should be an acceptable solution to this problem.
I use the activation method above, because I don't want my features pretending like they activated when they really didn't.
-
Tuesday, February 15, 2011 7:51 PM
Yes, I see. Rather clever approach with the proxy feature. There is however one flaw with it that I can't see an easy solution for. What happens when the user deactivates the feature in SharePoint. Feature B (activated by the proxy feature) will stay activated. It should have been deactivated in order to remove the functionality and do feature cleanup/unprovisioning.
Close but still not quite there.
J.O.
-
Tuesday, February 15, 2011 7:55 PM
It is not deployment that is the issue, but activation. Having a solution reuse another solutions feature makes total sense if you make reusable code.
There are also an option to create solution activation dependencies, so that solutions cant be deployed unless dependent solutions already are installed and deployed. But that's another story
J.O.
-
Tuesday, February 15, 2011 7:57 PM
Actually, as far as I know, deactivating a feature that depends on another feature doesn't deactivate the dependency unless it's hidden. And even then, only if no other activated features depend on it.
E.g. if FeatureA Depends on FeatureB, but FeatureOOTBZ depends on FeatureB, and FeatureOOTBZ is activated, then deactivating FeatureA won't deactivate Feature B, if I understand that process correctly.
If Feature B is hidden, then they won't see the feature to deactivate it. And Feature A is dependent on PreRequisites feature. You could add the Deactivating Event to the prerequisites feature to deactivate FeatureB. Then Make prerequisites a hidden feature. Then deactivating FeatureA should Deactivate Prerequisites, which in turn deactivates FeatureB. And all of this just so Visual Studio can deploy your stuff without erroring out and without having to set Always Force Install to true.
Heres a link to the feature Dependency Process on MSDN
http://msdn.microsoft.com/en-us/library/aa543162.aspx
So yeah, as long as any feature that depends on FeatureB is activated, sharepoint won't deactivate FeatureB.
So in the PreRequisites Feature Deactivating event you would need to do something like
foreach (SPFeature feature in Web.Features)
{
//If this feature depends on FeatureB, don't deactivate prerequisites.
}
-
Tuesday, February 15, 2011 8:02 PM
Hi,
I'm aware of that property, but as you pointed out I don't think that's a usable workaround.
J.O.
-
Tuesday, February 15, 2011 8:12 PM
That is the same as my initial configuration (feature B is hidden). Automatic activation/deactivation will only happen when the dependent feature is hidden.
Your proposal is essentially the same as my configuration and will also fail in Visual Studio when deploying.
Again, the problem is not SharePoint and how activation dependencies work. The problem is how Visual Studio deploys dependent features.
J.O.
-
Friday, February 18, 2011 6:04 PM
Just wanted to update everyone with information that I got after reporting this problem at Microsoft Connect.
This is a bug that has been verified in Visual Studio 2010 SharePoint Developer Tools, and will be fixed in the next release of Visual Studio (hopefully in SP1)
Posted by Microsoft on 17.02.2011 at 22:55Hi there,
Thanks for reporting the issue! We've noticed this bug and fixed it in next release of Visual Studio. If you have further comments, please feel free to let me know.
Thanks,
Xiaoying Guo
Program Manager, Visual Studio Business Applications ToolingJ.O -
Friday, July 08, 2011 5:13 PM
Hi
I have found a workaround for this issue.
It's importand to understand that this issue only appears while deploying from Visual Studio and will not be a problem when deploying the solution to a production environment. Therefor this workaround should only be used on the development system, and not on any other environments.
Visual Studio will try to deactivate all features in the solution while retracting. First all features that contains dependencies (activation dependencies). Then it will deactivate all remaining features. This will be a problem if you have dependent features that are hidden. These will already be deactivated when the feature that has the dependency on the hidden feature is deactivated.
The clue here is that a dependent feature will only be automatically deactivated if no other features have a dependency on that feature. The dependent feature can be deactivated directly even if another feature has a dependency on it. This is a SharePoint specific functionality, and that is the basis for my workaround.
Workaround:
1. Add a new Blank SharePoint project to your solution.
2. Add one or more features.
3. Add all the hidden dependent features that you have as an activation dependency for at least one of the new features that you created in step 2. (You can use the features to seperate different dependent features if desired)
4. Deploy the project from step 1 (Make sure that all dependent features already are deployed).
5. Future deploys (in the retract step) of the projects that contains your real projects/solution will no longer fail.
6. If you create new hidden dependent feature in your solution then you need to repeat step 3 and 4. Step 2 can be done again if needed.
Remember that this will not impact your finished solution. The project from step 1 should not be deployed as part of the final production solution.
Regards
Jens Otto
- Marked As Answer by JensOtto Friday, July 08, 2011 5:13 PM
-
Monday, April 02, 2012 7:48 PMRan into this. Deploying a feature, containing a timer job, to my dev box using VS2010. Using the default deploy scripts of vs2010, all deployments after the first would give the "error in deployment scope....feature already activated in scope". To resolve the issue, 1) retract the package in CA, 2) delete the package in CA 3) open the SP2010 Management Shell and run the "disable-spfeature" cmdlet. Error goes away.

