Saturday, December 22, 2007

TimeSpan.Seconds vs .TotalSeconds

The difference between the Seconds property and the TotalSeconds property is (or at least should be) pretty obvious, but based on experience it is a common bug to use .Seconds when you actually mean .TotalSeconds. For the readers out there that hasn't gotten the difference, think of a timespan of value 1 minute 23 seconds - here .Seconds is 23 and total seconds is 83.

As a rule of thumb, most often it's the Total variant you want, and yes, the same applies to all the other members too, (e.g. .Minutes, .Milliseconds vs. the corresponding .Total-prefixed ones)

Friday, December 21, 2007

"Practical Functional C#"

I just found an interesting blog post series about practical functional C#. It starts right here. Maybe I've missed something, but this feels like a fresh breath, being really down to earth and real world. I'm looking forward to future posts.

Friday, December 14, 2007

"Is there a constant for tab like Environment.Newline?"

..was a question a co-worker asked the other day. My first answer was no, as it is not really needed as a tab does not change between platforms as newline might (think Mono).

Then I realized, there actually *is* one, so I gave the following instructions:

  • Add a reference to Microsoft.VisualBasic.dll
  • add a using Microsoft.VisualBasic; statement
  • use Constants.vbTab

(And to avoid any misunderstandings, no, this was not a serious suggestion.)

Tuesday, December 11, 2007

"Thank you for the lasting contribution you made to Microsoft Visual Studio"

..that's what is engraved into the glass cube I got in the mailbox today.


Thursday, November 29, 2007

Dependency Visualizer 1.2.7

Turns out that Dependency Visualizer requires the Visual C++ Runtime version 7.1 (2003), and no-one had noticed (or at least not reported it to me).

The just released 1.2.7 fixes the installer to include the necessary files, otherwise nothing has changed since 1.2.6.

Wednesday, November 28, 2007

Interesting findings ...

What would you say if you found a class with the following interface during a code review?

internal static class Internal
// Methods
private static void CommonlyUsedGenericInstantiations_HACK();
private static T NullableHelper_HACK<T>() where T : struct;
private static void SZArrayHelper_HACK<T>(SZArrayHelper oSZArrayHelper);

Suspicious to say the least ...

The 'interesting' part here, is that the class actually exists, and not just anywhere but as System.Internal in mscorlib !

Monday, November 26, 2007

Dependency Visualizer now supports VS 2008

The just released 1.2.6 version of Dependency Visualizer now supports Visual Studio 2008 solutions/projects.

Monday, November 19, 2007

Visual Studio 2008 RTM released

Visual Studio 2008 just released (to MSDN subscribers) and the Express versions to the rest of you.

Get it now (or wait a few days to get better download speeds).

Friday, November 16, 2007

Stepping through properties in the debugger

Ever stepped through code in the debugger and ended up in N+1 trivial property getters before you got to the "real code" and felt frustrated?

Enter the DebuggerStepThroughAttribute. MSDN says the following: "For example, the Visual Studio 2005 debugger does not stop in a method marked with this attribute but does allow a breakpoint to be set in the method."

Basically, if you need a breakpoint in there, you'll get there, otherwise Visual Studio won't bother stepping there and just steps over it, which is exactly what we want.

So how do you apply the attribute to a property as its attribute usage states the following?

AttributeTargets.Method, Inherited=false)]

The point is to realize that while the property itself isn't a method, both the getter and the setter actually are.

So you can do the following:

        public int Foo
get { return m_foo; }
set { m_foo = value; }

..and now the getter has the attribute, while the setter does not.

Thursday, November 15, 2007

Programmatically enumerate WCF endpoints defined in app.config

For various reasons you might want to enumerate all client endpoints defined in the application configuration file.

For future reference, this is one way to do it:

// Automagically find all client endpoints defined in app.config
ClientSection clientSection =
ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;

ChannelEndpointElementCollection endpointCollection =
clientSection.ElementInformation.Properties[string.Empty].Value as ChannelEndpointElementCollection;
List<string> endpointNames = new List<string>();
foreach (ChannelEndpointElement endpointElement in endpointCollection)
// use endpointNames somehow ...

..obviously this is not production quality code.

Wednesday, November 14, 2007

Comparing DateTime structs ...

Consider the following code:

DateTime localTime = new DateTime(2007, 11, 14, 12, 0, 0, DateTimeKind.Local);
DateTime utcTime = new DateTime(2007, 11, 14, 12, 0, 0, DateTimeKind.Utc);

System.Diagnostics.Debug.Print("Is equal ? {0}", localTime == utcTime);

What do you expect the answer to be?

...and you probably guessed wrong as .NET actually considers them to be equal !?!

MSDN is "somewhat fuzzy" on the subject:

"Calculations and comparisons of DateTime objects are only meaningful if the objects represent times in the same time zone. For that reason, if no time zone is specified for the objects, it is assumed that the developer has some external mechanism, such as an explicit variable or policy, that can be used to determine the time zone in which a DateTime object was created."

Monday, November 05, 2007

Visual Studio 2008 release imminent

S. Somasegar (Corporate Vice President, Developer Division) just announced at Teched Barcelona that Visual Studio 2008 (and .NET 3.5 Framework) will be shipped before the end of November 2007.


Sunday, November 04, 2007

Google translation

Niklas Jansson pointed out that Google managed to screw up the translation of the Calendar print dialog.

The orientation combo box in Swedish has the choices "Bil", "Stående" and "Liggande", the last two makes sense but the first one translating to Car obviously does not. (The original version says auto.)

Funnily enough, they managed to screw up the Finnish version too, where they for the same alternative provided "Autot" which means "the cars", (while auto might actually have been somewhat acceptable).

Well, you can't always win... :)

Integrating Help2 files into VS 2005 - part 2

The other workaround I hinted in the previous post involves a bit of manual labor the first time (or if you ask nicely, I might just provide the needed parts), if used more than once it is IMO less painful than the ORCA route.

This solution takes advantage of <CustomTable> feature of WiX. By "reverse engineering" the needed table schemas out of the relevant merge module MSHelp2_RegTables__RTL_---_---.msm we can author these tables as <CustomTable>:s and then just add <Row>:s as appropriate.

Next time just edit the row data and you're set.

For brevity, I just post one table here, but the rest can be made available upon request.

The tables I've used are HelpFile, HelpFileToNamespace, HelpNamespace and HelpPlugin.

      <CustomTable Id="HelpFileToNamespace">
HelpFileToNamespace table definition -->
Description="Foreign key into HelpFile table (required)." />
Description="Foreign key into HelpNamespace table (required)."/>

data -->
Data Column="HelpFile_">YourHelpFileKey</Data>
Data Column="HelpNamespace_">YourHelpNamespaceKey</Data>

Saturday, November 03, 2007

Integrating Help2 files into VS 2005 - part 1

For various reasons (curiosity among others) I've been playing with integrating custom API documentation into Visual Studio, this turned out to be rather laborious.

For future reference I thought I'd document the process here.

- Create the code to be documented, use xml comments and turn on the generate xml comments switch in the project settings.

- Install Visual Studio SDK (yes, really ...)

- Install Sandcastle

- Install Sandcastle Help File Builder

- Open SHFB and create a Help2 project and customize appropriately.

- When the project builds successfully, open all the various .Hx? files (except .HxS) and remove the DTD reference, and from the .HxC file also the <CompilerOptions> element including contents. (For further info refer to the helpware site.)

- Now Microsoft wants you to use the Help Collection Integration Wizard, or manually edit merge files with Orca, neither of which is any fun.

- WiX has a WixVSExtension that among other thing has <HelpFile>, <HelpFileRef>, <HelpCollection> and <PlugCollectionInto> elements which sound promising.

- The problem: the WixVSExtension is currently broken, specifically bug 1588180 

- The bug comments include a suggested fix that involves recompiling WiX. Due to dependency issues this seems like a PITA.

- There is however also another workaround ... stay tuned!

Sunday, October 28, 2007

Dependency Visualizer - now on CodePlex

I finally released Dependency Visualizer as open-source on CodePlex. It's new home is now there.

Thursday, October 04, 2007

Microsoft to release the source code for the .NET Framework Libraries


I'm definitely not the first (and probably not the last) one to blog about this, but Microsoft is about to release the source code for a big part of the .NET framework. Yay! Even though Reflector is nice, having the actual source code with comments is nicer.

Read more here:

Releasing the Source Code for the .NET Framework Libraries - ScottGu's Blog

Thursday, September 27, 2007

Ironic, isn't it?

Microsoft Windows

The screenshot says it all ...

Tuesday, September 18, 2007

Installing Ubuntu

I just installed Ubuntu feisty 64bit on one of the computers. For those of you who happen to know the story about that particular computer it might seem somewhat ironic, but that's not the point of this post.

The installation was *smooth*, I just entered:

  • partitioning info (yes, use all available disk)
  • keyboard layout
  • timezone
  • user account info

and that's all. After a few minutes I asked to reboot out of the livecd and into the new installation and everything just worked! (Well except for my slightly odd screen resolution of 1440x900, but I can live with that)

Anyone can manage such an installation, and excessive OK button clicking.

Kudos Ubuntu!

Thursday, September 13, 2007

Enumerating XAML (BAML) files in an Assembly

I wanted to play around with XAML Pages, and wanted an application that automagically showed me a list of all included (embedded) XAML files in an assembly without me doing more than adding the XAML file to the project.

This turned out to be tricky until you got it...

Well, it is simple when you know how to do it, but until then you'll have some googling to do. (At least that is  my experience)

Basically, a XAML file with a build action of Page or Resource ends up in a .resources file named <assemblyname>.g.resources. This .resources file contains the binary version of the XAML file (BAML).

Enumerating the contents of a .resources file can be done using the System.Resources.ResourceReader class as follows:

using (ResourceReader reader = new ResourceReader("Foo.g.resources"))
foreach (DictionaryEntry entry in reader)

So all that's left to do is to create the application, (and no, it ain't pretty but it works):


<Window x:Class="AutoToc.MainForm"
Title="AutoToc" Height="400" Width="600" Loaded="FormLoaded"
HierarchicalDataTemplate DataType="{x:Type sys:Uri}">
BulletDecorator VerticalAlignment="Center">
Ellipse Fill="BlueViolet" Width="5" Height="5"
TextBlock Text="{Binding Path=OriginalString}"
Margin="5,0,0,0" VerticalAlignment="Center" />
ColumnDefinition Width="200"/>
ColumnDefinition Width="Auto"/>
ColumnDefinition Width="*"/>
TreeView Grid.Column="0" Name="tocTree"
GridSplitter Grid.Column="1" Width="2" HorizontalAlignment="Left"
Frame Name="contentFrame" Grid.Column="2" NavigationUIVisibility="Hidden"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>

and the interesting parts of the code behind:

private void FormLoaded(object sender, RoutedEventArgs e)
// UriCollection inherits ObservableCollection<Uri>
UriCollection pages = new UriCollection();
Assembly asm = Assembly.GetExecutingAssembly();
Stream stream = asm.GetManifestResourceStream(asm.GetName().Name + ".g.resources");

DataContext = pages;
using (ResourceReader reader = new ResourceReader(stream))
foreach (DictionaryEntry entry in reader)
// for some curious reason, we get "cannot locate resource"
// if we leave the .baml extension, it needs to be .xaml !?!
pages.Add(new Uri(((string)entry.Key).Replace(".baml", ".xaml"),


private void tocTreeSelectedItemChanged(object sender, RoutedEventArgs e)
contentFrame.Source = tocTree.SelectedItem as Uri;

That was easy, wasn't it?

Obviously this is not production quality code but more a proof of concept, and yes, I do use it for playing around with the 3D samples...

Obviously, it would be better to filter out non-Page xaml files, such as mainform ...

Thursday, September 06, 2007

DiffuseMaterial.Color vs DiffuseMaterial.Brush

I've been getting my feet wet with 3D in WPF lately, as I've been reading the new Petzold book 3D Programming for Windows.

It's too early to give any review of the book yet, but back to the subject matter:

As I was trying the examples out I was just getting emptiness !?! I suspected I had screwed up either the MeshGeometry.Positions and/or camera directions so those I checked first, and found no differences.

I looked at my code, and nothing jumped out as wrong.

When I looked closer I noticed that I'd been using DiffuseMaterial.Color instead of DiffuseMaterial.Brush

According to MSDN:

Brush: "Brush to be applied as a Material to a 3-D model."

Color: "The color allowed to emit from the Material. The default value is #FFFFFF. Since all colors make up white, all colors are visible by default."

Obviously? .Color was the wrong choice.

It seems I've got plenty to learn ...

Tuesday, June 26, 2007 » Blog Archive » Asshole driven development

Nowadays with all kinds of development methodologies, it's refreshing to revisit some real-world ones (in a slightly cynical manner..) » Blog Archive » Asshole driven development

Wednesday, June 20, 2007

Playing around with Powershell

For those living under a rock the newish command shell from Microsoft called Powershell (aka 'Monad') is quite nice.

Get Powershell

It treats everything as object that you can pipe around and you play around with file system, registry, wmi, .net objects, com objects, custom stuff all in the same way.

Let's say you want to play around with WMI and look at your computer.

PS C:\Users\Simon> Get-WmiObject Win32_ComputerSystem

Domain              : WORKGROUP
Manufacturer        : System manufacturer
Model               : System name
Name                : REBORN
PrimaryOwnerName    : Simon
TotalPhysicalMemory : 1609498624

or let's say that you want to find the description of the 3 processes that currently uses the most CPU:

PS C:\Users\Simon> Get-Process |
>> sort-object -property CPU -descending |
>> select-object -first 3 -property Description

Windows Media Player
Desktop Window Manager

Or if you for some reason feel the need to show a messagebox (and yes, the messagebox did show and I hit yes):

PS C:\> [void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
PS C:\> [Windows.Forms.MessageBox]::Show("Hello World")

Extension methods and Collection<T>

Visual Studio Code Analysis / FxCop says in rule CA1002 not to expose List<T> but instead something like Collection<T>.

Now List<T> has some nice features such as

List<T> List<T>.FindAll(Predicate<T> match) 

among others, not to mention

void List<T>.AddRange(IEnumerable<T> collection)

Now, we could go implementing these on our own base class and return that, or go back to C style object orientation and write a static CollectionUtilities class with methods such as

static void AddRange<T>(ICollection<T> collection, IEnumerable<T> items)

Neither of these makes me really happy.

Enter C# 3.0 extension methods:

public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> items)

{ /* implementation */ }

Now due to some compiler magic we can use this method just as it had beed implemented directly in Collection<T>... Neat!

Another interesting tidbit is that it is in fact possible to do things like

            Thing foo = null;
if (foo.IsNull())
Console.WriteLine("foo is null!");

and NOT get a NullReferenceException due to an extension method along the lines of:

        public static bool IsNull(this object value)
return value == null;

unfortunately, as they are called extension methods it's only possible for methods and not properties and such.

Wednesday, June 13, 2007

Microsoft embedding nerdy photo in Vista DVDs? - Engadget

 It seems some guys at Microsoft thought it would be cool to get their pictures on the Vista DVDs, and they seem to have gotten away with it!

Well, obviously I don't know what their managers thought of their ploy...

Microsoft embedding nerdy photo in Vista DVDs? - Engadget

Thursday, June 07, 2007

XAML as a better C#

That was the title of Chris Anderson's talk today. Very different, and very interesting. He explained how CLR and XML fits together in XAML and as a demonstration implemented a "poor-man's Workflow Foundation".

The talk also had it's fair share of humorous moments, when the his computer had a mind of its own.

Conclusion was that although XAML is very powerful, it's not necessarily the best tool for all jobs.

Tuesday, June 05, 2007

TechEd, day 1

Surprisingly, our bags *did* arrive during the night, so we got our clothes, that's nice!

First impression, this event is HUGE.

The keynote was more directed towards IT professionals, so not much interesting stuff to get there.

Orcas seems to have gotten its official name Visual Studio 2008, but release date should still be the end of this year.

You'll get as much SWAG as you want...

Saturday, June 02, 2007

Going to Orlando/TechEd

The bags are packed, hopefully I didn't forget anything too important.

Tomorrow we fly from Turku to Orlando via Copenhagen and Chicago. If everything goes according to plans, we'll land 10.47 PM in Orlando. (With 7 hours of time difference that is if it was 05.47 back home...)

It's gonna be a loong day...

On monday TechEd starts! 

Thursday, May 31, 2007

Windows Live Writer beta 2

Just noticed that WLW beta 2 is out, and I'm trying it out right now..

As far as I understand, it should support Blogger labels, and that has been one of the IMO biggest limitations with the previous beta.

Hopefully this works out properly, and this will be the blogging application of choice when I'll be blogging random stuff from TechEd. Yay!

Technorati Tags:

Monday, May 28, 2007

Speech Recognition isn't really there yet..

It seems we cannot really throw away our keyboards just yet, and only use speech recognition, as the following video clearly shows:

(Perl, is perhaps not the most "speakable" language there is, but nevertheless...)

Technorati : ,

Tuesday, May 08, 2007

Different signing options depending on configuration

There was a question in the MSBuild newsgroup about the possibility to have different signing settings depending on configuration.

Basically, let's pretend pretend that what we want is the following:

  • Debug: Delay sign using

  • Release: Sign using KeyPair.pfx

From within Visual Studio it seems impossible, due to the fact that the configuration boxes are grayed out. All is not lost though, by moving the code signing options into the appropriate configurations (by directly editing the project file).


<PropertyGroupCondition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">



<DelaySign> true</DelaySign>




<PropertyGroupCondition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">





And there you go!

(The obvious? drawback with this method is that the signing behavior isn't directly visible from within the Visual Studio project properties.)

Technorati : ,

Monday, May 07, 2007

Editing a Visual Studio 2005 project file

[This is not really news, just wanted to publish it somewhere so I can refer to it]

So how do you do it then?

It is simple actually:

  • (If the project file is under a locking source control provider e.g. Microsoft SourceSafe, you probably want to check out the project file first, as Visual Studio isn't smart enough to do it for you when you edit the file directly.)

  • Right-click a project in the solution explorer

  • Choose "Unload project"

  • Right-click the same project, that now is grayed out and suffixed with (unavailable)

  • Choose "Edit <filename>"

  • Edit away ...

  • Right-click the project, still suffixed with (unavailable)

  • Choose "Reload project"

There you go!

Caveat: This doesn't work under the Express versions of Visual Studio. That is, the "Unload Project" menu item is absent, you can still use the editor with schema support.

Technorati : ,

Thursday, May 03, 2007

Where's the QA when you need them?

Where is the QA when you need them? See the following image for clarification:

It listens to the name of ASUS ACPI Cneter (sic!) ... Product version, File version

It makes me wonder how something like this have slipped through?

Wednesday, May 02, 2007

Visual Studio dependencies

I figured I'd walk through the details on how to find out dependencies of a Visual Studio solution/project. (For those who haven't figured it out yet, this is a description how Dependency Visualizer does it)

1) For MSBuild compatible project types, it's dead simple, just use the following XPaths, where msbuild stands for the MSBuild schema:

Assembly references: /msbuild:Project/msbuild:ItemGroup/msbuild:Reference/@Include

Project references: /msbuild:Project/msbuild:ItemGroup/msbuild:ProjectReference/msbuild:Project/text() returns a relative path to the project file.

2) There are project types that aren't MSBuild compatible (most notably C++ ones), and due to popular demand, I had to add support for these also to Dependency Visualizer.

Assembly references are simple: /VisualStudioProject/References/AssemblyReference/@AssemblyName

Project references: Here is where it starts getting nasty..

/VisualStudioProject/References/ProjectReference/@ReferencedProjectIdentifier gives... you guessed it, a GUID identifying the referenced project. This means we have to parse the freeish text format of the solution file, to find out what project hides behind the GUID. But it gets uglier still, turns out that there's actually dependencies and dependencies. If you go to "Project Dependencies..." window (in VC++) and check a project, then you end up with a reference that's only existing in the solution file like so:

Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProjectName",
"ProjectName\ProjectName.vcproj", "{769945FD-50DC-49E4-B93E-54250D7BF541}"
ProjectSection(ProjectDependencies) = postProject
{A4583937-88F4-4C1D-B5A9-E711C3951E3A} = {A4583937-88F4-4C1D-B5A9-E711C3951E3A}

Where the GUID:s fit together like so: the first one is the type, the one on the second row is the project identifier, the thwo on the fourth row is the identifier of the referenced project.

Technorati : , ,

Tuesday, April 24, 2007

Adobe Reader on Vista Ultimate x64

After a lot of work and googling I finally managed to get Adobe Reader to install. The funny thing is that Adobe says that version 8 is Vista compatible. I'd like to question that, at least regarding the installer..


Adobe Reader 8 for Windows Vista

Started the installer, got the downloaded file warning but not the UAC dialog, then... absolutely nothing happened.

Then I tried "Run as administrator", still the same... absolutely nothing happened.

Googled around and found indication that running in XP SP2 compatibility mode might help. It did..

But come on Adobe, get your act together and produce an installer that Joe Average can use without extra fuzzing about!

Tuesday, April 03, 2007

Somasegar's WebLog : Listening to your feedback - Expression and MSDN

It seems a miracle has happened. Microsoft revaluated their decision about not including Expression Blend in MSDN subscription. Now it seems both Web and Blend (after its release) are included. Whoohoo! 

Link to Somasegar's WebLog : Listening to your feedback - Expression and MSDN

Simple properties

What do you prefer?


private int m_foo;
public int Foo
get { return m_foo; }
set { m_foo = value; }

public int Foo { get; set; }

int Foo;

The first is C#, the second C# 3.0 and the third one is C++/CLI

Monday, April 02, 2007

Nullable in C++/CLI

I was recently working on a C++/CLI project (which I only rarely do, as you'll soon find out)where there was a need to have a method returning a nullable DateTime.

I look up Nullable in the help, I see "ref class Nullable", think that the following will do it.

Nullable<DateTime>^ GetStuff();

I implement the thing and am a happy camper until I try to use it from a C# project. The intellisense says ValueType GetStuff(), WTF !?!

I take a look once again and find out that Nullable<T> is "public value class", so the correct incantation should have been:

Nullable<DateTime> GetStuff();

oh, and to return a null value you just do:

return Nullable<DateTime>();

(Anyone else finds the C# ? syntax for nullable types more easily digested?)

Monday, March 26, 2007

Dependency Visualizer 1.2.0

Just released at

Whats new:

  • Optionally hide .NET 2.0 references
  • Optionally hide .NET 3.0 references
  • Generate svg and/or png
  • Configurable (the above mentioned items)
  • Support for vcproj:s

Thursday, March 22, 2007


Jag har tydligen också lyckats bli utmanad (av trion)

Här är några lagom intressanta påståenden i ingen speciell ordningsföljd:

1. Jag hatar allt som liknar kedjebrev (därmed tänker jag inte heller utmana någon fler..)

2. Har nästan lyckats kapa benet av mej medelst motorsåg..

3. Har deltagit i skönhetstävling.

4. Har blivit halvt korsfäst (ja eller i alla fall blivit spikad i ena handen...)

5. Har diplom i komjölkning

6. Kanin är gott...

Tuesday, February 20, 2007

const (in C++/CLI) considered harmful

Today I found the following "gotcha" in combining C++/CLI and C#.
Create a C++/CLI dll containing something along the lines of:

public ref class Foo
static const int BAR = 42;
Use that from C#, maybe like so:
int temp = Foo.BAR;
= -1;
string.Format("The answer is: {0} ...or {1}",
temp, Foo.BAR),
Wait, that should not be possible! We just said that BAR was const in the C++/CLI code didn't we?

The problem is that it is possible (and gives the following screenshot):

Digging deeper reveals that C++/CLI const turns into an ordinary field with an optional modifier IsConst that languages are free to ignore, (which e.g. C# does).

If you in fact want a "constant" constant (which is probably why you wrote const in the first place?), then you will need to use literal in C++/CLI to get the same result as a C# const.

Thursday, February 15, 2007


The second version of Dependency Visualizer was just uploaded. This time it might actually work :) And in the case it does not, the possibilities to get traces for me should be infinitely better than the first version.

Wednesday, February 14, 2007

Dependency Visualizer released

I just put up the first public version of the Dependency Visualizer. You might want to try it out..

Tuesday, February 13, 2007

Extend right-click menu in Explorer in WiX installer

I just had the need to make an installer that created a right-click menu item for Visual Studio solution files (.sln)

The easiest way to accomplish this would have been to use the WiX built in support for registering extensions:

<Extension ContentType="text\plain" Id="sln">
<Verb Id="Visualize" Command="Visualize dependencies"

However, I soon found out that this was a Bad Idea, in the sense that then my software took over as the default handler for .sln files. Not exactly what I wanted...

Turns out that I needed to manually install the registry keys/values in the appropriate place to get it to work:

<Component Id="DependencyVisualizerComponent" Guid="PUT-GUID-HERE">
<File Name="DependencyVisualizer.exe" Id="DependencyVisualizerExe"
<RegistryKey Action="createAndRemoveOnUninstall" Root="HKCR"
<RegistryValue Action="write" Value="Visualize Dependencies" Type="string" />
<RegistryKey Action="createAndRemoveOnUninstall" Key="Command">
<RegistryValue Action="write" Type="string"
="&quot;[#DependencyVisualizerExe]&quot; "%1""/>

Oh, and the tool I'm working on is a tool for visualizing inter-project dependencies...

Wednesday, January 31, 2007

BackgroundWorker and exceptions

Got a bit confused at work today when a piece of software seemingly halted in a place where it should not have been possible.

After looking at the code for a while I found something like the following:

BackgroundWorker bgw = new BackgroundWorker();
+= new DoWorkEventHandler(bgw_DoWork);

where bgw_DoWork was (basically) implemented thusly:

void bgw_DoWork(object sender, DoWorkEventArgs e)
// ...
throw new Exception("things went bad");

If you try it out (outside the debugger) you'll notice that the exception is silently swallowed !?!

The moral of the story:

If you use Background worker, either implement a catch all handler within the DoWork method or, hook the RunWorkerCompleted event and check RunWorkerCompletedEventArgs.Error for non-null value.

Tuesday, January 30, 2007

Browsing old books

Doesn't sound like much fun does it? Well, consider that the books in questions were hand written by Leonardo da Vinci or that one of the books were Alice under ground or something other like that, then it seems much more interesting. The British library has done just that, published a few selected books in a WPF showcase application that feels close to reading a real book. See for yourself!

Prerequisites: .NET 3.0, Internet Explorer and a reasonably modern computer.

Technorati tags: ,

Saturday, January 06, 2007

Anti-commercial for two products..

I have two products that I'm annoyed with from time to time.

1) Samsung CLP-500

It tells me that the waste toner tank is full (now and then) and that I need to replace it. However I can clearly see that it is nowhere near full. The problem seems to be with stupid design, there is an optical sensor right under one of the inlets that detects if it can see through the waste toner tank (made of clear plastic), to make matters worse, it seems that a tiny toner particle in the sensors way and the tank "is full". Samsungs FAQ entry for the error message is also somewhat funny.


"Waste Toner Tank Full/Not Install" is displayed.

First, replace the waste toner tank.  
If the same message is displayed continually after replaced.
- Check whether that replaced waste toner tank is the new.
- If it is the new, the printer may require repair. 

2) Logitech MX-1000

  • Cursor occasionally jumping all over the place
  • Buttons behave if they are pressed
  • Tilt wheel get stuck tilted

..need I say more?

Tuesday, January 02, 2007

Happy New Year, and a late christmas present..

The break is over and tomorrow back to work again. Meanwhile, it seems that I've been a awarded with a 1-year MSDN subscription with all the bells and whistles thanks to my activity at


(The announcement is here)