Szymon Kobalczyk's Blog

A Developer's Notebook

  Home  |   Contact  |   Syndication    |   Login
  84 Posts | 5 Stories | 164 Comments | 380 Trackbacks

News

View Szymon Kobalczyk's profile on LinkedIn

Twitter












Article Categories

Archives

Post Categories

Image Galleries

Blogs I Read

Tools I Use

Tuesday, September 16, 2008 #

Some time ago I got very strange situation on my development SQL Server 2005. Immediately after starting the process it went up to 100% CPU and stayed there for hours. There were no external connections, and I couldn't figure out what was causing this so I asked for help our best SQL geek Paweł Potasiński. With his help we were able to figure out that this was caused by service broker running on one of the databases although we didn't find the root cause for this.

Fast forward few months, and last week I got into the same trouble after upgrading the database. Of course I didn't recall how exactly we fixed it last time. So today I had to gave up and ask for Paweł's help again. I wrote this post mostly because I don't want to bother him again on this.

So first you use this to see which databases have service broker enabled:

SELECT * FROM sys.databases WHERE is_broker_enabled = 1
Then you can use ALTER TABLE ... SET DISABLE_BROKER but this would only work

when database is not locked. Therefore the best way to do this is like this:

ALTER DATABASE ... SET SINGLE_USER WITH ROLLLBACK IMMEDIATE
GO
ALTER DATABASE ... SET DISABLE_BROKER
GO
ALTER DATABASE ... SET MULTI_USER
GO

Note that this will kick off all users connected to this database.

Thanks for help Paweł - I owe you one more time :-)


Monday, September 08, 2008 #

Last Friday Managed Extensibility Framework Preview 2 (MEF) was published on CodePlex. MEF is a new library in .NET that will simplify adding extension points to your applications. It enables discovery, loading and composition of the extensible components. You can now download the source code, samples and find more information on the project site: http://www.codeplex.com/MEF

I was playing with the bits over the weekend and chatted with Glenn Block (Program Manager on the .NET FX team that does MEF), who explained to me what MEF can do for us. I thought it would be beneficial to share this information, so I created a sample to demonstrate how MEF can be hosted in your application. Please note that this covers only a single scenario where I found MEF might be useful, but MEF probably can do much more for you.

Before we go any further you might want to download the sample project, so you can browse the source code while I walk through it:

Download MefNavigationWindow project

Sample scenario

So here is my sample scenario: Let's say you are building a Windows Forms application where you want to add browser like navigation capabilities. This means that your window contains a placeholder where you can load other "pages" be specifying only the page name. Sounds familiar? Yes, WPF supports this out of the box with then NavigationWindow and Pages. So in short we would like to build a NavigationWindow for Windows Forms.

Let's assume that our pages would be simply UserControls. Actually it is quite easy to load user control dynamically - you simply instantiate the control's type and add it to parent's Controls collection. The real problem here is how to map page name (string) to it's type.

For example we could create a section in app.config file that lists all available views and map their names to the corresponding types. This could look similar to this:

<pageMappings>
  <page name="Page1" type="MefNavigationWindow.Page1" />
  <page name="Page2" type="MefNavigationWindow.Page2" />
  <page name="Page3" type="MefNavigationWindow.Page3" />
</pageMappings>

Then our NavigationWindow would load these mappings and construct the pages using reflection. But I can see two potential problems here.

  1. In case of a client applications the configuration file is easily available to users to mess with, and doing so it would likely break the application.
  2. Because the definition of class and mapping are kept in two separate places developers can easily forget to update the mappings when adding new pages to our solutions.

Therefore a better solution could be to create a custom attribute that is used to assign page name to a given user control:

[PageMetadata(PageName = "Page1")]
public partial class Page1 : UserControl
{
    //...
}

Then we can scan the current assembly for all types that have this attribute (using reflection), construct a dictionary of all pages, and when requested create instances of a specified page (with reflection again).

But guess what... MEF already does all this for us with much less code. Let me show you how.

Exports

First let's look at the PageMetadataAttribute:

[MetadataAttribute]
public class PageMetadataAttribute : Attribute
{
    public string PageName { get; set; }
}

Very simple. Only odd thing is that this attribute itself need to be tagged with MetadataAttribute so MEF knows to expose it as metadata in the parts catalog (and we will use it in just a moment). Now we can use it on any UserControl to assign the page name, but we need to use it together with the Export attribute. Type discovery in MEF is based on attributes and Export indicates that the attributed class should be exported as ComposablePart and specifies the contract it implements (it is Page in our case):

[Export("Page")]
[PageMetadata(PageName = "Page1")]
public partial class Page1 : UserControl
{
    // ...
}

Notice that in MEF contract is specified as string. There is additional overload on the Export attribute that consumes a Type, but internally it would be converted to a fully qualified name of that tape. On the side note, even when you use a typed contract the attributed class doesn't really need to implement it - the contract type is used only as a key in the container.

CompositionContainer and Catalogs

Now we can start implementing our NavigationWindow and first thing to do is to configure the CompositionContainer:

private void InitializeCompositionContainer()
{
    var catalog = new AttributedAssemblyPartCatalog(typeof (NavigationWindow).Assembly);
    var container = new CompositionContainer(catalog.CreateResolver());

    container.AddPart(this);
    container.Compose();

    _container = container;
}

Because we want MEF to discover all the pages in the current assembly we use the AttributedAssemblyPartCatalog that will search for all types that were attributed as exports. Catalogs are responsible for creating a Resolver that is then passed to the CompositionContainer so it can query for available ComposableParts (you can learn about the other two types of catalogs from the programming guide). Next we also register the NavigationWindow itself as a ComposablePart in the container. After doing so we need to call the Compose method to resolve dependencies (note that you don't need to call Compose to user parts exposed from catalogs). But for this to work properly we need to add Export attribute on NavigationWindow too:

[Export("NavigationWindow")]
public partial class NavigationWindow : UserControl

Imports

Ok, it's about time to talk about the dependencies, aka imports. For the NavigationWindow this will be the list of all available page types and we can get this by declaring following collection:

[Import("Page")]
private ExportCollection<UserControl, IPageMetadata> _pages;

The Import attribute indicates that container should resolve this dependency for us by assigning a collection of all exports with Page contract (this happens when you call container's Compose method). It will also expose the PageMetadataAttribute through IPageMetada interface:

public interface IPageMetadata
{
    string PageName { get; set; }
}

Notice that we didn't implement this interface earlier on the attribute itself. At runtime MEF will be able to create dynamic proxy to it with a magic thing called duck typing. Isn't that cool!

The _pages field is private and normally it wouldn't be resolved, but we can ask MEF to handle it by adding the assembly level AllowNonPublicComposition attribute (add it to AssemblyInfo).

Now we are ready to implement the GoTo method that will do the navigation:

public void GoTo(string pageName)
{
    var newPage = _pages.SingleOrDefault(e => e.MetadataView.PageName == pageName);

    Controls.Clear();

    if (newPage != null)
    {
        var control = newPage.GetExportedObject();
        control.Dock = DockStyle.Fill;
        Controls.Add(control);
    }
}

In the first line it will search the _pages collection for one with specified page name (MetadataView property implements our IPageMetada interface). Later when the page was found we request the instance of UserControl with call to GetExportedObject(). I told you this would be easy!

Now we can put the NavigationWindow on any Form and call navigationWindow1.GoTo("Page1") to get this:

image 

I assume that we would like to navigate from one page to another by clicking the link. Therefore the page needs to know the NavigationWindow it is hosted in – in other words it has a dependency on the NavigationWindow.

[Import("NavigationWindow")]
public NavigationWindow NavigationWindow { get; set; }

private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
    NavigationWindow.GoTo("Page2");
}

This is why earlier we registered the NavigationWindow itself as a ComposablePart, so now we can import it from any other part. This would get us to the second window:

image

Object lifetime

To make this exercise more interesting here we have a TextBox and we want to pass its value to the third window. But first let's talk briefly about part's lifetime. By default all the exported parts are treated as singletons. For us this means that there would be only a single instance ever created of each page (as soon as you call Export.GetExportedObject method). Of course this is not always the desired scenario, and you can change this behavior using the CreationPolicy property of the CompositionOptions attribute. Here is Page1 revisited:

[CompositionOptions(CreationPolicy = CreationPolicy.Factory)]
[Export("Page")]
[PageMetadata(PageName = "Page1")]
public partial class Page1 : UserControl

The CreationPolicy enumeration has only two values: Singleton (default), and Factory.

Looking back to our scenario we want to make the second page a singleton so it can be accessed from the third page. To access it would also need to get a reference to the Container – and again we do this by adding another dependency in Page3:

[Import("Container")]
public CompositionContainer Container { get; set; }

Now, this dependency won't be available just yet. As we've seen before the container was created by the NavigationWindow. We could register it manually as we did with the NavigationWindow, but I would like to show you one more capability that MEF has – you can declare Exports not only on types but also on the class members:

[Export("Container")]
private CompositionContainer _container;

So when we add this field to NavigationWindow we now not only export the NavigationWindow itself but also the value in the it's _container field. I can imagine that this capability would be handy if you need to export one of the built-in system types or type from a third-party library when you can't add the Export attribute directly on the given type.

Finally here is the code from Page3 to get the reference to previous page and read the value entered in the TextBox:

private void PageLoaded(object sender, EventArgs e)
{
    var page = Container.GetExports<IAskNamePage>(p => p.ContractName == "Page" && string.Equals(p.Metadata["PageName"], "Page2")).Single();
    nameLabel.Text = "Helo " + page.GetExportedObject().FullName;
}

This time we used one of container's GetExports methods to query for a page (ComposablePart with contract "Page") and with page name of "Page2" (through Metadata dictionary). The query capability on metadata is one of the big things in MEF and it allows you to get detailed information about available parts even before you instantiate them. I've also added IAskNamePage interface so we can get the text entered on Page2:

public interface IAskNamePage
{
    string FullName { get;  }
}

It simply returns the text from TextBox:

public string FullName
{
    get { return textBox1.Text; }
}

Here is the last page:

image

Summary

I hope that this example gives you some idea where MEF fits and will help you get started. Let me know if you have any questions about this. For more advanced scenario check out the three samples that shipped with the current drop on CodePlex:

  • MEFlook - Outlook like client
  • MEFTris - Tetris like game with shapes as plug-ins
  • Extensible File Explorer - File explorer with extensible views, favorite file viewers and shell services

  • Friday, August 29, 2008 #

    InterKnowlogy is always on the cutting edge of the Microsoft Platform so its not surprise that we were among first to build applications in WPF, Silverlight and now on Microsoft Surface (a touch screen computer embedded in a coffee table). I'm excited to show you two applications that we released recently.

    VitruView

    VirtuView is a collaborative environment for viewing and annotating patient's examination results on anatomic 3D models. This application is evolution of our earlier Angiographer that we build for InterMountain Healthcare together with our partner Zygote (world's leader in 3D human anatomy models and textures). VirtuView lets users zoom and rotate the 3D heart models with your hands. You can use your fingers to draw arteries, place Stents and add annotations. And because this is multitouch you can use more than one finger or many people can work at once. This application is done in WPF and uses Microsoft HealthVault to securely store patient's data.

    Check out this video demonstration from Tim Huckaby and Kevin Kennedy:

    Update: Here you can watch another video with Tim and Dr. Peter Kuhn from Health User Group Conference.

    History at your fingertips

    This amazing application was built in conjunction with Microsoft and the Library of Congress. It chronicles the history of the republican and democratic national conventions in interactive Surface experience. The application is featured LIVE on Surface units at both upcoming conventions, and it was shown on the ABC National News this week and you can watch it on the ABCnews.com website (move forward to approximately 01:18).

    Here is a more technical demonstration from Rodney Guzman:

     

    What about me?

    Meanwhile I've been working with great team at Colonial Life & Accident Insurance Company that built the Harmony solution. We helped them built a WPF offline version of the Web based Harmony self-enrollment system that will be used by insurance agents. You can find more details in this Microsoft case study.


    Thursday, May 22, 2008 #

    codecamp-logo Some time ago I wrote that there is a wave of HCL events sweeping through Poland. Today I'm happy to announce that we opened registration for the Code Camp in Kraków. This is the first such conference organized by the members of KGD UG for the .NET developer community.

    We will meet on June 7th for the chance to listen to sessions from five great speakers:

    • The world has changed… What are the dilemmas of designing software solutions in the year 2008? - Tadeusz Golonka
    • Reach End-Users With Next Generation Web Applications - Chris Koenig
    • Addressing non-functional requirements with PostSharp - Gael Fraiteur
    • SQL Server 2008 Integration Services - Grzegorz Stolecki
    • Developer's role in an agile project - Bartosz Pampuch

    Follow this link to register. The conference is free but the number of seats is limited so make sure to register early.

    Along the conference we organized a little programming contest. The first round is over but you still have a chance to win one of the cool prizes (including XBox 360) in the second round. It's quite simple - you just need to implement a single method. More details on this page.

    Hope to see you soon at CodeCamp.pl


    Tuesday, March 18, 2008 #

    [PL] Dzisiaj o 10:38 urodził się mój drugi synek Antoś. Duży chłopak z niego bo waży ponad 3,5 kg i ma 58 cm "wzrostu". Oboje mama i dzidziuś są zdrowi i czują się dobrze. Tatuś też jeszcze się trzyma i jest strasznie szczęśliwy :-)

    [EN] Today at 10:38 (GMT+1) my second son Anthony was born. He is a big boy, weighting 3.5 kg and 58 cm "tall". Both mommy and baby feel well. Daddy is the happiest man in the world!

    Updated 19/03/2008

    New photos:

     

    Updated 20/03/2008

    First Contact... with older brother:

     

    Monday, March 17, 2008 #

    Honestly, I still don't know how I did it. The LAB49 WPF in Finance Innovation Contest was announced back in December and I think I first read about it on Tim Sneath blog. With all the cool prizes I was very inclined to participate, but it quickly turned out that its available only to US citizens. However that changed in the first week of February, so I started considering it again, but still didn't had any clue what to do. You see the goal of this contest was to create a WPF application that visualizes a set of provided financial data in some interesting way. While the first part was easy (writing the app in WPF) the hardest part was to figure out what to do with the data. Only after "last call to action" email from Daniel Chait I decided its about time to start coding.

    Because I started working late on this project, initially I wanted to create only a charting control capable of displaying the line and candlestick plot of stock prices. But after the contest deadline was extended I started thinking of a better way to visualize the stock prices for a given day – something that goes beyond a simple listbox or a datagrid. The next option I considered was to create a heatmap – i.e. use color gradients to denote the change in stock prices relative to the previous day. But in all samples I’ve seen these symbols were placed on a regular grid and the placement didn’t correspond in any particular way with the data. I started thinking about how to sort the symbols so that those that experienced similar data change would be close to each other, and those with different data change remain further apart. This finally led me to the idea of applying Craig Reynolds’ flocking algorithm to perform this clustering.

    Here is a screenshot from my final entry called Stock Information Boids:

     Stock Information Boids WPF Application

    Also you can already download the source code for this application from my resource page at MSDN Code Gallery. Make sure to read the user guide that describes how the algorithm works and how to use the application.

    Turns out that for some reason the judges liked my solution, because last week at the closing keynote of 2008 Microsoft Financial Services Developer Conference in New York, Daniel Chait announced that I won the grand prize in the contest!

    The two finalist were Jacob Carpenter and Jobi K Joy, while the honorable mention went to Paul Hounshell. Congratulations guys, great work! You can download their very cool applications from here:

    In following weeks I will try to share some details on my implementations (in particular about the Timeline and Flock controls). I was already told that Jobi K Joy and Jacob Carpenter plan to do the same, so make sure to subscribe to their blogs too.

    I would like to thank the judges for selecting my entry. And last but not least, big kisses for my wife Joanna for letting me work on the project all nights and weekends considering her present condition (L)


    Saturday, March 15, 2008 #

    Last Wednesday I had the privilege of representing the KGD.NET user group at the Heroes Happen Here launch event in Kraków. It's hard for me to say anything about the presentations because I actually didn't see even a single one (but others already blogged about it here and here). Instead I spent the whole day backstage chatting with my good friends: Asia Grzywna, Mateusz Kierepka, Paweł Potasiński, Bartosz Pampuch, Tadeusz Golonka, Grzegorz Kolarz, Paweł Łukasik, and Michał Brzozowski just to name the few.

    Paweł Potasiński & Joanna Grzywna Paweł Potasiński, Mateusz Kierepka & Joanna Grzywna 

    After the event Michał Żyliński and Barbara Sokólska invited us to a geek dinner where I had opportunity to meet great guys from Insys - company that build the first commercial website in Poland using Silverlight 1.0 (Lech Poznań TV).

    For me this was the ultimate geek day so thank you all for taking your time to hang out with me!


    There are so many good things happening right now in the Polish .NET Community that I thogh it would be best to put it together in one post. So here you have it:

    Communities2Communities 2008

    C2C'08 is a first ever countrywide IT conference organized by community of Microsoft .NET and SQL Server professionals. On April 5th 2008 eleven speakers will have opportunity to show the most wanted topics, and answer the most desired questions. The list of speakers looks very impressive and includes celebrities like Dino Esposito and Matin Kulov, along with best speakers selected by members of Polish user groups.

    Here are the key facts:

    • Purpose: learning, sharing knowledge and interacting with other professionals and geeks
    • Topics: two tracks - .NET and SQL Server
    • Number of attendees: 200
    • Date: April 5th, 2008
    • Place: Microsoft, Al. Jerozolimskie 195A, Warsaw, Poland
    • Pricing: free
    • Website: www.c2c2008.pl

    Although the official Heroes Happen Here product launch wave is over, there is still opportunity to learn about the new exciting products and other Microsoft technologies. Very soon user groups around the globe will begin executing the Heroes Community Launch events delivering deep technical training on Microsoft Windows Server 2008, Visual Studio 2008, and SQL Server 2008. Here is the current schedule for Polish user groups:

    Our group, KGD.NET will organize the conference on Saturday, June 7th 2008. We plan to have 5-6 sessions and about 200 attendees. To make this happen and to bring you some great speakers we are joining forces with Wroc.NET. I will post the details here in following weeks.

    SharePoint training in Kraków

    Besides the regular meetings (the next is scheduled on 26th March) in next few weeks KGD will organize a SharePoint training for group members. It will cover both WSS and MOSS and will be deliveried by Michał Gołda, certified SharePoint expert from Making Waves. We don't have the date set yet but if you are interested register now.

    Speaking

    On personal note; I received several invitations to speak on some of these events. Here is my current schedule:

    • I was invited to speak at the event called "Discover the Next Web" that will be held on March 31st at Microsoft's Polish Office in Warsaw. My session is titled "User Interface 2.0", and as you could guess I will by speaking about WPF and showcase some of the cool projects that we've done at InterKnowlogy
    • I'm also helping my friends Marcin Celej and Michał Brzozowski build the coolest app ever to showcase during their session at the C2C conference on April 5th.
    • I accepted the invitation to speak at the Warsaw .NET UG in April but we need to work out the exact date.
    • And finally I will be speaking at the Heroes Community Launch event in Wrocław on June 2nd.

    I'm looking forward to meet you there!


    Tuesday, February 19, 2008 #

    When I started blogging here on GeeksWithBlogs it turned out that if want to publish any code samples I have to find yet another place to host the source code. I didn't own any web servers that I could use for this, so I started looking how other bloggers do this, and came across ProjectDistributor.net. It did exactly what I was looking for:

    ProjectDistributor is a web application for distributing small pieces of software - such as tools, components, widgets and controls. Users create groups to store projects against and visitors can login to download those projects or to leave feedback about bugs or to request new features.

    Although it's quite simple and didn't offer many features it did a decent job hosting my samples. The projects can be grouped by author and category.

    However recently I got several comments that the download links don't work, and the site was down for some time (now it's up again). To fix this I decided to move my files to Windows Live SkyDrive. It's a generic service for hosting any files on internet. When you sign up you get 1GB of free space. The UI is very simple: you can create folders, setup the permissions (private, shared or public) and you then quickly upload your files.

    The nice addition is that when you publish a file on SkyDrive, it creates a nicely formatted HTML snippets that you can embed in your page (there is even a Windows Live Writer plugin that helps you with this):

    image

    These nice emblems is the only thing I really miss abut SkyDrive. They were just easier to find on the page then a simple download link.

    But as I said, SkyDrive is a generic service not really targeted to host programming samples. You don't get any ways to categorize, tag or search the projects. You don't even get the number of downloads or any other statistics. In addition some of my friends reported that they get redirected to Sign In page for Windows Live whenever they open my blog.

    That's why when I heard about CodePlex's younger brother – MSDN Code Gallery on recent .NET Rocks! interview with Matthew Manela I decided to give it a try and this weekend I moved all my samples there:

    image

    Here is the link to my resources page: http://code.msdn.microsoft.com/KobushCode

    My experience so far was very positive. It's basically a CodePlex (even shares the same codebase from what I heard) but without the TFS integration - so you don't get version control or project management features. But when you create a resource page you still get:

    • Home page that you can edit with wiki syntax and supports comments. You can also create subpages to publish your articles or documentation. You can also tag your project so it would be easier to find for others.
    • Rleases tab where you publish your source code, binaries or stand alone documentation (and it has a downloads counter).
    • Discussions forum that your readers can use to publish questions or comments.
    • You can even run an Issue Tracker to record bugs or feature requests if you need to (it's optional and you can turn it on in the Resource Page Settings).
    • If you find someone to help you out with the project you can manage your team on the People tab.
    • License tab shows the terms and conditions the user needs to agree when downloading your code. Note that currently it's the Microsoft Public License (Ms-PL) and you cannot change it (you can do this on CodePlex though). It's a basic "use it how you want - no guarantee" type of license, and personally I don't have any objections to it but you need to judge it for yourself.

    Also note that while I decided to publish all my samples on a single resources page, nothing prevents you from creating more than one. You can then link them together using Related Resource Pages sections.

    For me the site offers all I really need to host my code samples. But if your project eventually grows and you need more features you can move it to CodePlex (I wonder if there will be any migration path for doing this). Also note that in many aspects it replaces now retired GotDotNet site and some popular samples were migrated from it.

    Probably most bloggers that write about programming face the same problem that I had, and MSDN Code Gallery does a good job solving it. So if you are looking for a place to put your samples I strongly recommend to give it a try.


    Wednesday, January 30, 2008 #

    About two weeks ago Daniel Biesiada (who is ISV DE here in Poland) announced on his blog a little programming contest. The goal was to build a .NET application that would check if the the theory of Six Degrees of separation applies to two given topics in Wikipedia. In order words to find a path from the source page to destination with no more then six links. At the time I had not much else to do (apart from setting up website for the C2C Conference, helping out with the European Silverlight Challenge, and preparing for the WPF Beta Exam) so I decided to give it a try.

    Fast forward two weeks and I present you my WikiSpider:

    image

    As usual building this took me much more time than I initially anticipated (including few sleepless nights). And still I didn't make it before the deadline, so this even didn't count as a contest entry anymore (sigh!). However this was mainly because my personal goal was to throw in there every new piece of .NET 3.5 I could find fit - and most of them I never used before.

    Here are some key technologies I managed to put into this:

    • The UI is done in WPF (and this was the only thing here I knew a bit about). However I borrowed the graph control from the excellent Kevin's WPF Bag-o-Tricks.
    • The caching is done using SQL Server Express. Initially I wanted to do this using SQL Compact but I run into performance issues and had to switch to full SQL in order to run the queries in profiler. But since this was fixed (with big help from Paweł Potasiński) I could try with SQL Compact again.
    • Of course data-access is done using LINQ to SQL. And of course this was the main source of my problems, as it was first time I've done anything in it, and so far I only read the Scott Gu's tutorials. Still, I'm already in love with it.
    • Speaking of LINQ. Initially we were screen scrapping the HTML pages to get all the links.  But turns out that Wikipedia has a little known about Query API that enables to get the page content in XML. So the obvious move was to rewrite this part with LINQ to XML.
    • The path-finding algorithm was borrowed from Eric Lippert. The nice thing about it is that it uses lots of C# 3.0 language features, so it is a great resource to learn from. The new C# syntax is so addictive that I already miss it in my other project.
    • Finally, I wanted to publish the app with ClickOnce but run out of time. So maybe later.

    I learned many interesting things and tried out some new stuff that I wanted to check out anyway. I will try to share my discoveries in the next few days, but in the meantime feel free to download and take a look at may code (I know it's not prettiest piece of code you've seen but I was in a rush to finish this on time):

    Download the source code

    Here you can also download the entries from other participants: Łukasz Sowa, Maciej Rutkowski, and Arkadiusz Benedykt. Congratulations to all of you!

    Installation

    1. Download the code from the above link and extract it.
    2. The application uses local SQL database for caching and unfortunately you need to create it yourself (now you know why I wanted to use SQL Compact). Simply launch SSMS and create empty database called WikiCache.
    3. Run the Create_WikiCacheDB.sql script from the data folder to create the database schema.
    4. By default the app is configured to look for the WikiCache database on the local SQLEXPRESS instance. If you installed it somewhere else update the connection string in app.config accordingly.
    5. Run the build.bat or open solution in Visual Studio 2008 and run from there.

    Usage

    1. Enter the name of the Wikipedia page in the address bar at the top and press the Go! button. The entered topic and the pages it links to will be displayed as graph.
    2. Clicking on any topic will make it currently selected (put it in the center of the graph).
    3. Right-click on any topic to open the context menu. Select "Open in browser" to.... load the page in browser.
    4. Select "Set as source" or "Set as destination" to put the topic name in appropriate field on the sidebar
      [Note: Currently it's the only way to show the sidebar]
    5. You can also enter the source/destination topics manually.
    6. When both are set click on the Start button to begin searching for the path. Few statistics are displayed on the bottom of the sidebar.
    7. During the search you can still use the graph or navigate to other pages (thanks to the BackgroundWorker magic).
    8. When path is found it is displayed on the sidebar, and you can click on each topic to center it on graph.

    Have fun!