Get your Visual Studio toolbox in fit


So, it has been a while since I joined the club of those who faced the intimidating

Loading toolbox content from package Microsoft.VisualStudio.IDE.Toolbox.ControlInstaller.ToolboxInstallerPackage
‘{2C98B35-07DA-45F1-96A3-BE55D91C8D7A}’

problem, every time I opened a new instance of Visual Studio and used the XAML designer.

After some search, I found a decent solution. Mind you, do not follow the first workaround described on Microsoft Connect because you will just reset the Toolbox and later the problem will reappear. The solution that worked for me is a combination of two resources I found. The first one, describes the problem. Essentially,  the Toolbox has some invalid entries that cause the delays and there is a specific procedure to find out which these entries are: You have to launch VS by the command line using the parameter /log and then parse the log file to find the time consuming entries. Each of these entries has a GUID that corresponds to registry keys, as well as a description. Judging by the description, you can delete these registry keys and/or reinstall missing components. When you have finish with this, you can force the Toolbox to be regenerated by following the instructions here: http://michaelcrump.net/fixing-a-broken-toolbox-in-visual-studio-2010-sp1

Now, as I said, an important part of all the above is to parse the log and find the time consuming entries. This is not a very easy task, as the XML formatted log file has multiple “entry” elements like this:

<entry>
<record>61</record>
<time>2012/03/19 11:12:50.224</time>
<type>Information</type>
<source>VisualStudio</source>
<description>End package load [Visual Studio Source Control Integration Package]</description>
<guid>{53544C4D-E3F8-4AA0-8195-8A8D16019423}</guid>
</entry>

What you have to do, is to compare the value of <time> element to the value of <time> element of the next <entry> element. I had 1298 entries so searching by scrolling was out of the question, since we can use LINQ to do it for us:

First, I declared a class to represent each <entry>

Class Entry     
    Public Property Record() As Integer
    Public Property Time() As DateTime
    Public Property Source() As String
    Public Property Description() As String
    Public Property Duration() As TimeSpan
End Class
class Entry     
{         
    public int Record { get; set; }
    public DateTime Time { get; set; }
    public string Source { get; set; }
    public string Description { get; set; }
    public TimeSpan Duration { get; set; }
}

Then, I parsed the log file using the following code:

        Dim logFile = "log file path + name here"
        Dim doc = XDocument.Load(logFile)

        Dim entries = doc...<entry>.Select(Function(e) New Entry() With {
                                                        .Record = e.Element("record").Value,
                                                        .Time = CDate(e.Element("time").Value),
                                                        .Source = e.Element("source"),
                                                        .Description = e.Element("description")})

        entries = entries.Zip(entries.Skip(1), Function(e1, e2)
                                                   e1.Duration = e2.Time - e1.Time
                                                   Return e1
                                               End Function).
                          OrderByDescending(Function(e) e.Duration).
                          Take(20)

C# guys might as well use this code:

            var logFile = @"log file path + name here";
            var doc = XDocument.Load(logFile);

            var entries = doc.Descendants("entry").Select(e =>
                new Entry()
                {
                    Record = (int)e.Element("record"),
                    Time = (DateTime)e.Element("time"),
                    Source = e.Element("source").Value,
                    Description = e.Element("description").Value
                });
            entries = entries.Zip(entries.Skip(1), (e1, e2) =>
                {
                    e1.Duration = e2.Time - e1.Time;
                    return e1;
                }).OrderByDescending(e => e.Duration).Take(20);

Now, you can display the entries in question. Alternatively, you can filter the entries collection for descriptions that contain the text “failed”. These entries might or might not have long duration but are useless never the less and represent packages that does not exist for various reasons such as an incomplete uninstall. That was exactly my case, as I had previously uninstalled the Oracle Developer Tools. Obviously (and not surprisingly) Oracle did sloppy job with the uninstaller.


Windows 8 Metro development Train-the-Trainer


Την εβδομάδα που μας πέρασε, είχα την χαρά να παρακολουθήσω ένα Train-the-Trainer course για Windows 8 Metro development στο Amsterdam. Μέσα σε τρεις μέρες είδαμε την ανάπτυξη μιας εφαρμογής end to end καθώς και το πώς σχεδιάζουμε το UX στις Metro εφαρμογές. Όλα ήταν πολύ ενδιαφέροντα ακόμα και για κάποιον που έχει γράψει εφαρμογές σε Windows Phone αφού ναι μεν υπάρχουν αρκετά κοινά στοιχεία, ωστόσο είναι διαφορετικό τόσο το προγραμματιστικό μοντέλο (πλέον παίζουμε με WinRT) όσο και το screen real estate. Είδικά το δεύτερο, οδηγεί σε μια νέα και διαφορετική chromeless φιλοσοφία που δεν έχουμε συνηθήσει εμείς οι .ΝΕΤ developers. Σε λίγο καιρό θα μπορέσουμε να τα πούμε κι από κοντά ωστόσο μέχρι τότε, αυτό που θα πρέπει να κρατήσετε – αν δεν το έχετε κάνει ήδη βλέποντας τα videos του //BUILD – είναι ότι είμαστε στο ξεκίνημα μιας νέας εποχής για τα consumer applications σε μια αγορά που τώρα θα δημιουργηθεί. Όπως θα είδατε όσοι εγκαταστήσατε τα Windows 8, το Windows Store αφήνει πολλά περιθώρια για να βγει κανείς από νωρίς πρώτος και να καλύψει κενά σε εφαρμογές που λείπουν.

Περισσότερα από κοντά λίαν συντόμως. Μέχρι τότε, προετοιμαστείτε γιατί το παιχνίδι γυρίζει και γίνεται πολύ ενδιαφέρον!