Skip to main content

Upgrading to SharePoint 2010: In the field experience

sharepoint1Last week I was able to upgrade BB&D’s internal intranet site from SharePoint 2007 to SharePoint 2010! So you can properly understand what happened let me cover a little bit about the intranet first. Our intranet is a small deployment, just a single server deployment however it is kept up to date with technology so it is running on SQL Server 2008 with SP1, Windows 2008 R2 on a 64bit virtual machine. We have also not gone with heavy customisation, rather focusing on small tweaks and adjustments. A good example is we do not have a customised master page but rather use the theme options to get the colour scheme we want.

The first step I did was to download the pre-requisites for SharePoint 2010, and using the option on the installer this was a breeze. I’ve seen this before with Dynamics CRM and once again I am impressed by how a very simple feature makes such a big difference. Next step was the install, which was pain less and quick.

Once installed the configuration manager had to run and this is where I had two issues. The first problem was that I got stuck on task 1! The cause here is that a dialog box had appeared behind the main window (telling me to do the same to all servers in the farm) and won’t go until I clicked OK. This annoying little bug cost me a few minutes.

The second issue was that the SharePoint 2010 install needs to do some Active Directory queries and this meant my user account was not good enough. Not having a good enough user means that the installer produces a very unhelpful error at step 3:

System.ThrowHelper.ThrowKeyNotFoundException()
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Microsoft.SharePoint.Utilities.SPUtility.GetUserPropertyFromAD(SPWebApplication webApplicaiton, String loginName, String propertyName)
   at Microsoft.SharePoint.Administration.SPManagedAccount.GetUserAccountControl(String username)
   at Microsoft.SharePoint.Administration.SPManagedAccount.Update()
   at Microsoft.SharePoint.Administration.SPProcessIdentity.Update()
   at Microsoft.SharePoint.Administration.SPApplicationPool.Update()
   at Microsoft.SharePoint.Administration.SPProcessIdentity.UpgradeToV4ManagedAccount()
   at Microsoft.SharePoint.Administration.SPConfigurationDatabase.ResolveObjectAndClassVersions(SPLog log)
   at Microsoft.SharePoint.Upgrade.SPConfigurationDatabaseSequence2.Upgrade()
   at Microsoft.SharePoint.Upgrade.SPUpgradeSession.Upgrade(Object o, Boolean bRecurse)

sharepoint2It took ages to figure this out, mostly because it is not a documented requirement. To get the correct permissions you need to get a domain admin to do the following on the domain controller:

  1. Open up Active Directory Users and Computer.
  2. Select Advanced Features from the View menu. Failing to do this means that the tab in step four won’t be visible.
  3. Right-click the your AD account and select Properties.
  4. Select the Securities Tab.
  5. Select Authenticated Users in the Group or user names field.
  6. Allow Full permissions in the Permissions for Account Operators.
  7. Repeat this process for any SharePoint service accounts you may have created.
  8. Next make sure this change replicates to all domain controllers.
  9. Now connect to your SharePoint server, and open the command prompt (cmd.exe) and type gpupdate /force. This will force the changes to the machine as it may have a cached version.
  10. Finally reboot the SharePoint server and start the configuration wizard again.

After all that was done the configuration wizard completed and the upgrade process started in central admin. The upgrade process also took a while to do, but once done everything just worked.

Lastly we applied some theme tweaks and a quick run through of testing it and it was done. One thing that is important to remember about this process is that the entire time it was happening the current intranet was done so plan your deployment accordingly. This is easily the best experience I’ve ever had installing or upgrading SharePoint and shows that the product is maturing.

Find Results Tweak - Now with less suck

extensionmanager I posted the other day about a Visual Studio add-in which I developed. When developing it, I used the add-in model which has a nasty side effect, it needs to be installed with a MSI. Visual Studio 2010 can also be extended with packages and these can be deployed using the VSIX format.

What is this magical new VSIX format? It is basically a ZIP file which contains everything you need plus a manifest which tells VS how to use it. What makes this much better is that VS handles the install itself, so no MSI is needed. It is also then listed in the Extension Manager and so can take advantage of the features there by being disabled/uninstalled easily, not that you would want to.

A great side effect of this is that the new extension model let me add a little more error handling to the tool to help out debugging it. To get the new version go to http://findresultstweak.codeplex.com

Death of a SharePoint Developer

Originally from :http://rawsocket.org/pf/arquivos/2004_11_01_index.html I have had to explain many times in the last year why I, a normal developer, am involved with Information Worker which is (mostly) a SharePoint group? I am involved because I believe that the idea of a SharePoint Developer is a fast dying one and soon, people who call themselves a SharePoint Developer will be using it just as a way to justify higher consulting costs more than anything else.

I do not think this is because SharePoint usage is dying, rather the growth (maturity and adoption) of SharePoint is causing SharePoint developers to die off. This is not because SharePoint is so user friendly we no longer need custom code, because we still need custom code in SharePoint. The two reasons for my thinking this is based on two questions, “What SharePoint development really is?” and secondly “What Microsoft is doing about SharePoint development?”.

What is SharePoint development really? In SharePoint versions past (2007 and before) you would develop code for SharePoint using development concepts unique to SharePoint. Now that SharePoint has matured, development of the code for SharePoint involves concepts that are universal to development. There are two examples which come to mind which highlight the maturity of development concepts. First is web parts, which are now the same as ASP.NET web parts, and secondly is web services (and OData if you have SharePoint 2010). Both of these concepts are the exact same as used by many other products made by Microsoft and other companies. For example if you understand how to get data from Twitter, with OData in SharePoint 2010 you will understand how to get data from SharePoint. Yes, you will have some specific bindings/API’s/code that are SharePoint specific but the concepts, which is the difficult part to learn, are the same.

I mentioned two questions and the second is about Microsoft and it’s strategy for SharePoint development, in particular their 2010 strategy (Visual Studio 2010 + SharePoint 2010). A SharePoint developer used to have to go and download special files, install them, fixed issues, try installing again, fix more issues, have special machines or virtual machines to run SharePoint on and so on. The actual process of just writing code for SharePoint meant that you became elite because you had to go through a ritual of fire before you could start. Microsoft have really made SharePoint 2010 development simple and more importantly easy to start with, both by making SharePoint run natively on Windows 7 and also by including everything you need for development within Visual Studio 2010 from day one. It is as hard start wring code for SharePoint now as it is to make a WPF application!

What I am trying to convey is that previously a SharePoint developer had “paid their school fees” by learning so much that was so specific to the process of SharePoint development that they actually had earned a special title. Now that all those barriers have been removed, the title of SharePoint developer no longer applies, we are all just developers now!

Tweaking the Find Results window in Visual Studio 2010

Visual Studio is filled with goodness and happiness and a lot of that is available for tweaking, so you can get the maximum goodness, via the Tool -> Options menu. One of the things which doesn’t have any visible options is the formatting of the way the results are displayed:

findresults1

The problem, as indicated above, is a ton of white space, long file paths, no column information etc… Wouldn’t it be great to tweak how that can be displayed? Thankfully Sara Ford found a way to do exactly that via the registry. So you could tweak it to actually display the way you want it!

findresults2

In my tweaked way it is far more condense with just the filename (no more path), less whitespace (since I am showing only a summary of results) and I also included the column info. The problem is that editing the registry is not user friendly :( This gave me a chance to write my first Visual Studio add-in, which gives you an option inside Visual Studio to set it.

usage2

What is really nice is that while you configure the format, the preview window will update and show you how it looks so you do not get any surprises when you save it! If you would like to find out more about it you can go to the site on CodePlex at http://findresultstweak.codeplex.com/

Installing TFS 2010 Basic on a Laptop

I decided that I would like show how easy it is to install TFS 2010 on a laptop in an upcoming presentation, but I also want to use that TFS installation for demo’s which is a worry – what happens if the install fails? So what I decided to do was create a video of me installing TFS, this way I can show the video and not worry about my demos not working because of some demo failure. As I am such as nice guy, I decided to share it with everyone on YouTube, so here is the video:

Article in the BB&D Newsletter

After being at BB&D for almost two years, I finally managed to get an article in the BB&D newsletter! The article is about my trip in January to Canada and US for the ALM Rangers work! This was a different experience than writing for my blog, because this had to go through an editor and a copywriter before it was included. They made enough changes to the article that reading it myself, it felt strange because it sounds like me, just a different me. This article will now be shipped off to the BB&D offices around the world so that should be very exciting!

article

Click the image for a bigger view of it.

Thanks to Martin for spotting that the clicking of the image didn't give a bigger view, which is now fixed up.

Downloaded PowerPoint files need repairs?

I download a lot of PowerPoint presentations and recently I am seeing more and more are stating they need repairs when opened!

image

Unfortunately repairing does not work and downloading them again doesn't help either! What is happening is that Windows is detecting that these files are from the Internet and enabling a block on them for your protection. To remove this block, you need to right click the file, select Properties, click the Unblock button and click OK.

image

You will then be able to open them successfully.

Thanks Joseph for spotting the type-o in the original post.

Reading and writing to Excel 2007 or Excel 2010 from C# - Part V: Full source for reading

[Note: See the series index for a list of all parts in this series.]

Clipboard08

A few people have battled with getting all the bits of code scattered in the series together to actually work. This is not only due to the fact they are scattered, but part III for example was not showing the code correctly and there was a bug in part IV. I have gone back and fixed those issues and to help further here is the full code in one big view (click read more if needed to see it).

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

namespace ReadFromExcel
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Cell> parsedCells = new List<Cell>();
            string fileName = @"C:\Users\bbdnet0758\Desktop\Demo.xlsx";
            Package xlsxPackage = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite);
            try
            {
                PackagePartCollection allParts = xlsxPackage.GetParts();

                PackagePart sharedStringsPart = (from part in allParts
                                                 where part.ContentType.Equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml")
                                                 select part).Single();
                
                XElement sharedStringsElement = XElement.Load(XmlReader.Create(sharedStringsPart.GetStream()));

                Dictionary<int, string> sharedStrings = new Dictionary<int, string>();
                ParseSharedStrings(sharedStringsElement, sharedStrings);                

                XElement worksheetElement = GetWorksheet(1, allParts);

                IEnumerable<XElement> cells = from c in worksheetElement.Descendants(ExcelNamespaces.excelNamespace + "c")
                                              select c;

                foreach (XElement cell in cells)
                {
                    string cellPosition = cell.Attribute("r").Value;
                    int index = IndexOfNumber(cellPosition);
                    string column = cellPosition.Substring(0, index);
                    int row = Convert.ToInt32(cellPosition.Substring(index, cellPosition.Length - index));
                    int valueIndex = Convert.ToInt32(cell.Descendants(ExcelNamespaces.excelNamespace + "v").Single().Value);

                    parsedCells.Add(new Cell(column, row, sharedStrings[valueIndex]));
                }
            }
            finally
            {
                xlsxPackage.Close();
            }

            //From here is additional code not covered in the posts, just to show it works
            foreach (Cell cell in parsedCells)
            {
                Console.WriteLine(cell);
            }
        }

        private static void ParseSharedStrings(XElement SharedStringsElement, Dictionary<int, string> sharedStrings)
        {
            IEnumerable<XElement> sharedStringsElements = from s in SharedStringsElement.Descendants(ExcelNamespaces.excelNamespace + "t")
                                                          select s;

            int Counter = 0;
            foreach (XElement sharedString in sharedStringsElements)
            {
                sharedStrings.Add(Counter, sharedString.Value);
                Counter++;
            }
        }

        private static XElement GetWorksheet(int worksheetID, PackagePartCollection allParts)
        {
            PackagePart worksheetPart = (from part in allParts
                                         where part.Uri.OriginalString.Equals(String.Format("/xl/worksheets/sheet{0}.xml", worksheetID))
                                         select part).Single();

            return XElement.Load(XmlReader.Create(worksheetPart.GetStream()));
        }

        private static int IndexOfNumber(string value)
        {
            for (int counter = 0; counter < value.Length; counter++)
            {
                if (char.IsNumber(value[counter]))
                {
                    return counter;
                }
            }

            return 0;
        }                         
    }

    internal static class ExcelNamespaces
    {
        internal static XNamespace excelNamespace = XNamespace.Get("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
        internal static XNamespace excelRelationshipsNamepace = XNamespace.Get("http://schemas.openxmlformats.org/officeDocument/2006/relationships");
    }

    public class Cell
    {
        public Cell(string column, int row, string data)
        {
            this.Column = column;
            this.Row = row;
            this.Data = data;
        }

        public override string ToString()
        {
            return string.Format("{0}:{1} - {2}", Row, Column, Data);
        }

        public string Column { get; set; }
        public int Row { get; set; }
        public string Data { get; set; }
    }
}

Free Visual Studio and TFS training?

Blue Einstein Man Pointing a Stick at a Presentation of a Flying Saucer Clipart Illustration S.A. Architect will be offering FREE training covering Visual Studio and TFS in both 2008 and 2010 versions! This will be done in real life, so you will need to travel to somewhere in Johannesburg and so to figure out where, all you need to is click Yes on the S.A. Architect home page.  Once some numbers have been worked out a venue can be found and it can be arranged!

The only catch is you will need to give up a Saturday for this, and myself and fellow Team System MVP, Zayd Kara, will be there to help or annoy you ;)