FeatureActivated not called?

March 07, 2011

Today I was trying to figure out an issue that has been an issue with switching to a powershell-based deployment for a SharePoint project.  Without going too much into it, we have feature EventReceivers that do a bunch of useful stuff when a feature is activated.  SharePoint handles calling the receiver, we do our stuff, everyone wins right?

When deploying through VS, the EventReceiver would be called.

When activating through the UI, the EventReceiver would be called.

When deploying with Enable-SPFeature, the EventReceiver wouldn't be called.

Wait, wat?  That doesn't sound right - I didn't entertain the thought that this could even be the case for a while, and wound up hunting down issues in our code that simply don't seem to be there (the availability of an SPContext, HttpContext etc might explain why the functionality of the event receivers was not being called).  We'd had similar behavior previously when an exception was being thrown from an EventReceiver, so my natural response was to add logging / throw an exception and wait for it to appear in the ULS log.

Anyways, long story short, I double checked that the receiver was hooked up correctly (if it wasn't VS / UI deployment wouldn't work anyways, but I was really scratching my head on this one).  I eventually boiled the code down to something like the following:

    [Guid("FC9092AF-8EDE-43DE-9D34-F077A4A0B144")]
    public class FooEventReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            File.AppendAllText("C:\\Temp\\log.txt", 
                "--- " + DateTime.Now.ToLongTimeString() + " " + 
                DateTime.Now.ToShortDateString() + 
                Environment.NewLine + "Success");
            base.FeatureActivated(properties);
        }
    }

And messed around with things in PowerShell, but none of the flags did anything, it didn't matter if I forced the install, if I removed the old one first, redeployed the new (same) wsp.  Then it dawned on me to check stsadm.

Moral of the story?  I'll be using:

stsadm -o activatefeature -id "FC9092AF-8EDE-43DE-9D34-F077A4A0B144" -url "http://foobarspwfe"

Instead of:

Enable-SPFeature -identity "FC9092AF-8EDE-43DE-9D34-F077A4A0B144" -url "http://foobarspwfe"

For the time being.

If you're here because you're experiencing the same issues, then maybe it'll work for you too.  My first impression is that it's a permission issue at PowerShell's end - that it's PowerShell that can't actually load/run the EventReceiver code for some reason, but changing the featurereceiver code isn't really an option, and I needed to fix this on a pretty tight deadline (one of these days I'll get around to messing with CAS and might even learn if it comes into play here), so unfortunately I don't have a deep and complete explanation of what's going on under the hood here.

I do have a workaround though, which is always nice.

UPDATE (June 2011): I discovered what I believe is the source of this behavior a little while ago but never got around to investigating it fully or updating this post... I think that it has to do with assemblies getting loaded into powershell when you use Enable-SPFeature, and being loaded externally when you use STSADM.  Because assemblies can't be unloaded from AppDomains, you could be running the same FeatureActivated code every time you're running an assembly with the same version etc from a powershell window.  This shouldn't happen in a non-development scenario though (even using assembly versions with build numbers should have fixed the issue I was experiencing).  Anyways, next time I'm around a SharePoint machine I'll take a closer look and add more detail in another post if this is indeed the case.

UPDATE #2: I came across this post by Eric Bartels which found that the root problem in his environment was UAC, and that running the powershell environment as administrator allowed Enable-SPFeature to work successfully.