I’ve had a right game with this Sharepoint Versioning problem.

Now those of you used to writing .NET but maybe not SharePoint will be used to having AssemblyVersion attributes set in the AssemblyInfo.cs files.

This is something I took into my last SharePoint application for wss3.  Now in SharePoint 2003 I got used to not setting the version number but it slipped my mind for WSS 3.0.

My particular problem was I had some ItemAdding/Updating List events.  These were configured to fire in one of my Assemblies. My build server would automatically increment version numbers in AssemblyInfo.cs and in all associated .xml files in the features, very clever I thought at the time.  Now I needed to update this assembly and modify some code in these events.

I made those changes and installed it and all of a sudden none of the events were firing at all.

This is because when a list is created the EventReceiver details of the feature are not read from the XML file but are stored against the List in the content database.  This makes some sense as if you update the list template then you can update the EventReceivers as well and have different versions of a list definition with different handlers.

In my experience it’s more likely that you will want to modify all the existing lists and template as your probably implementing a fix, especially if using SharePoint as an app platform.

So how to fix my now rogue ItemReceivers.  I could do some fancy coding in Feature activations etc, but I really don’t want to go there and have code left lying about for what will essentially be a one time fix.

To the rescue PowerShell.  Luckily for me we use PowerShell so I  can create a post update installation script that runs just this once.

Here is the gist of it.

###############################################################
# Validate args
###############################################################

    if ($args.Length -ne 1 -or $args[0] -eq "-?")
    {
        Write-Host "Usage: .FixIt.ps1 <SiteUrl>";
        return;
    }
    $SiteUrl = $args[0];
    cls

###############################################################
#Get Base Objects
###############################################################

    [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
    $site = New-Object Microsoft.SharePoint.SPSite $SiteUrl
    $web = $site.RootWeb
    $lists=$web.Lists

###############################################################
#Change List Event Receivers
###############################################################

$list=$lists["BrokenList"]

#I happen to know there are only 4 Receivers really I should use the count
#One of them is named wrong as well hence the 3 cases
#(in the real version I fixed that too)
#You need to count backwards as it deletes and re-inserts so a foreach wont #work.

for ($i=3;$i -ge 0;$i–)
{
    $er=$list.EventReceivers[$i]
    switch($er.Name)
    {
        "BinaryJam BrokenList Receiver ItemUpdating"
        { 
            $er.Assembly="BinaryJam.MySharePointApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1111111111111111"
            $er.Update()
        }
        "BinaryJam BrokenList Receiver ItemAdded"
        {
            $er.Assembly="BinaryJam.MySharePointApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1111111111111111"
            $er.Update()
        }
        "BinaryJam BrokenList Receiver ItemAdding"
        {
            $er.Assembly="BinaryJam.MySharePointApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1111111111111111"
            $er.Update()
        }
    }
}

$list.Update()

 

Advertisements