Sunday, April 27, 2008

Codeplex, IE, and Firefox

Ok, maybe my system was completely screwed up and that's why it didn't work. But to the best of my knowledge I have a Vista Ultimate installation including IE 7 maintained by Microsoft Update. It has the latest and greatest patches installed. Today I went to - Microsoft's answer/contribution to the open-source community - and tried to download a few Sandcastle bits. I used Internet Explorer for it since I thought "It's a Microsoft site so the Microsoft browser should be fine." Well, it wasn't. When I clicked one of the two download links for Sandcastle I was presented with an overlay window (no pop-up) containing some licensing information. Before I was able to click the "Accept" buttone the overlay disappeared, and .... nothing happened. I restarted IE, and tried multiple times, eventually I got fast enough that I could actuall click the "Accept" button. Still it didn't work. Despite my recent experience with a different Microsoft Site that serves IE only, I thought it is at least worth a try to use Firefox. From there it was a breeze. Everything was straight forward, working flawlessly. Which leaves me wondering whether the guys who maintain the Codeplex site test mainly on Firefox.... (Onto my soap box: Microsoft - in my opinion - has started to move in the right direction. At the same time I believe it has still a long way to go until it competes on merits and great products and services only.)

Saturday, April 26, 2008

Accessing Installation Properties in Custom Actions

Assume you have a custom action for your installer and you'd like to access a parameter (or call it a variable or property) from within your installer. That property might have been set by another installer, e.g. a file search, or it could be part of the set of properties that are standard during installation, e.g. "TargetDir". Let's take TargetDir as an example. When you work on your setup project within Visual Studio (2005) it offers a number of macros for properties. E.g. when you want to specify the location for a folder that you'd like to create during install you can use [PersonalFolder] and others to specify the actual location. In order to pass such a variable to your custom action, simply open the Custom Actions editor for your setup project. Then select the custom action and then add the parameter in the "CustomActionData" property using the following syntax:
Please note the trailing backslash, which you only need to use when you surround the property in double quotes. However, as a safety measure I suggest making it a habit to always add the double quotes and the backslash. Remember paths can and will contain spaces! In some examples on the internet the backslash may be mentiond in the text but not be included in the code sample. If you leave the backslash out you'll see a message box containing "error code 2869". However, this article makes it clear that you must add the trailing backslash if you use the double quotes. Also, if you want to pass more than one property separate them by a single space, e.g.
/TargetDir="[TARGETDIR]\" /UserDir="[PersonalFolder]\"
Then in your custom action implementation - a class derived from System.Configuration.Install.Installer - you can access it in the following way (C# here, but similar in other .NET languages):
string targetDir = Context.Parameters["TargetDir"];
That's all.

Two More Tips for Debugging Custom Actions

As I mentioned in my previous post one of the options you have to ensure you have sufficient rights to attach to a process, I'd like to share two more suggestions for how you can debug custom actions in your setup project. At various places you will find the tip to use MessageBox.Show() to stop execution of your custom action. Then when the message box is displayed you can attach the debugger. When I tried this the list of processes showed me three instances of msiexec.exe and I couldn't identify which one I should connect to. So I decided to select all of them and attach to all of them. Then I set a break point in a line after the message box and hit F5 to continue execution. Result: Setup continued happily and the break point was ignored. So this didn't help, but here are two simple suggestions that should make your life easier: Tip 1: For the message box make sure you give it a title or caption. For instance if you use MessageBox.Show() then use the overload that takes two strings as parameters. The first is the message in the message box. The second parameter is the caption. That's the important one since this is the string that you will find in the list of processes when you want to identify the right process. Tip 2: In the dialog box for attaching the debugger to a process make sure you tick "Show processes from all users" as it might be that the msiexec.exe instance you are interested in is not displayed.

Visual Studio: Access denied when attaching debugger to process

The other day when I was working within Visual Studio 2005 on Vista, I encountered the problem that I couldn't attach the debugger to some of the processes that I wanted to run in the debugger. The solution that worked for me was pretty simple: I closed Visual Studio and then selected "Run as administrator" from the context menu for the shurtcut to the application. This is certainly not the recommended way of bypassing security but on the other hand it may come in handy when needed. Prerequisite is that you have access to an account that has administrative rights. If you don't you may need to have a nice chat with your system administrator...

Thursday, April 17, 2008

MySQL closed-source: What's the alternative?

An anonymous writer posted on Slashdot that Sun Microsystem has announced that parts of MySQL will be closed-sourced, e.g. backup solutions and some more advanced features. The post is refering to Jeremy Cole's blog entry on the subject. The decision is certainly Sun Microsystem's business, and I'm sure it makes a lot of sense from their executive view. However, the users have an opportunity to help Sun Microsystem's understand the consequences of their decision. For instance, if you want to continue using an open-source database, PostgreSQL might be an alternative worth looking at. Developing for the Microsoft platform, it offers native interfaces for C, C++, and .NET, and even the "good old" (?) ODBC is available.

Wednesday, April 16, 2008

ReSharper 3.1: More Details

I promised to provide more details about my ReSharper experience as I go. So here is an item that I perceive as a nuisance. Sometimes, when you type in code, it displays the information above the line of code, and parameter info below the line of code. As a result in some cases almost all code is covered by those nice pop-ups. That can be very challenging at times. What I definitely like is the light bulbs ReSharper shows in the left margin. It's color indicates whether a suggestion is more serious (color is red) or if it is more optional (color is yellow). When you click on the light bulb a menu with useful next actions is displayed, e.g. "Optimize Usings" or "Qualifier is redundant" or "Make readonly". Although the fun stops after a while because you have used up all the light bulbs in the code base, it definitely helps improving the code, in particular making it more readable by removing all the "noise" from the stream of information that hits your eyes. Well done! I do have the impression though that Visual Studio responds slightly slower. This is not really surprising given the functionality ReSharper provides and given the a lot of elements need to be updated as you edit your code. I think, though, that the performance hit is a good investment since you get the improved code in return. Please be aware that this applies to version 3.1. JetBrains may decide to release newer versions that exposes a different behavior. Note: I paid in full for my license, and I have no financial or other interest in JetBrains the company behind ReSharper.

Tuesday, April 15, 2008

What's next for csUnit?

Since the March '08 release of csUnit we have thought about what area we should focus on next. We have improved the performance, we have added data-driven testing, and we there were always a few features that csUnit provided first. The next area we are looking at is usability. We'd like to improve usability significantly. For instance, as test suites grow it may become more and more time consuming to locate a particular test or test fixture. The next version of csUnit will therefore feature an easy to use search capability, available for both the stand-alone GUI and the addin for Visual Studio. We are also putting quite some effort into improving the test tree view. We believe that all users will benefit from improvements in this area. And finally, csUnit has become very feature rich over time. Some people prefer a simpler UI. We want to serve both groups of users the ones who prefer the rich functionality, and the ones who prefer to keep it simple. The idea is to add some configurability to the UI so that depending on your preference more or less elements become visible. Stay tuned! And if there is a feature you'd like to see, don't hesitate to visit csUnit's web site and follow the link to "Suggest a feature" that you can find on most pages.

ReSharper 3.1 in Visual Studio

For quite some time I have been using ReSharper now, currently version 3.1. Bottom line it helps creating better code and it has features that are beyond Visual Studio's capabilities. This is good mostly but has some side effects, too. I like for instance all the suggestions with regards to improving the code. It's a bit odd when you insert some code, e.g. a declaration of a variable of a type that is part of System, that ReSharper adds the fully qualified name including the name of the namespace. A few seconds later it may suggest to remove the namespace name is thinks that it is not necessary. Feels a bit like the fireman who wanted to be a hero, so he set a house on fire in order to being called for fighting the fire.... One thing that can be challenging if you use formatting features. ReSharper may decide to format items differently than Visual Studio. So depending on whether you have the settings for the two in sync you may end up with code that looks the same or that looks inconcistent. It certainly would be great if ReSharper would do some form of synchronization. There are other minor subtleties about which I'll blog as I encounter them. But by and large the product is a good complement to Visual Studio's feature set. Note: I paid in full for my license, and I have no financial or other interest in JetBrains the company behind ReSharper.

Tuesday, April 08, 2008

ControlPaint and Vista

What's ControlPaint for? Well, you can use it for different purposes, e.g. for printing a form including the controls on it properly rendered. Another reason why you would want to use ControlPaint is when you want to do some customization to controls that support ownerdraw, e.g. the TreeView control. Be aware, however, that ControlPaint doesn't support visual styles. So for instance if you use ControlPaint.DrawCheckBox you will notice that under Vista it will render the checkboxes with the XP style. That's not hat you want. In those cases where you want support for visual styles use classes such as the CheckBoxRenderer and similar classes in System.Windows.Forms. So for the checkbox you would use CheckBoxRenderer.DrawCheckBox. The difference will be that the CheckBoxRenderer supports visual styles. Your checkboxes will look as expected on Vista as well. I have tested this, and it works on Vista with .NET 2.0. Don't necessarily rely on the online information. Give it a try on your development and your target platform. Also give it a try on the .NET version you are using. The described technique should be available for all versions between 2.0 and 3.5. The online documentation is contradictory on this. It doesn't seem to be supported on the compact framework. But who runs Vista on his portable device....

Wednesday, April 02, 2008

Property Getters with Bad Manors

In the sources of a 3rd party library that I'm using I found the following code:
public static int Counter {
   get {
      int cnt = counter;
      counter = 0;
      return cnt;
Ok, the documentation says that calling this getter will reset the counter. However... Still, in my opinion this is bad coding practice. Getters shouldn't modify the object. The reason for that is that some IDE's use the getters for displaying object data in debugging sessions. As a consequence debugging code and looking at the member of this object influences the outcome of the debugging session. I call this bad manors of that getter. The better approach would have been to use a method with a more intuitive name for example "ReadAndResetCounter()". That would a) avoid accidental modification during debugging sessions, b) follow the good coding practice of getters being non-modifying accessors, and c) would express the actual functionality of the code in a more understandable way. Some recommendations as a take-away:
  • Don't implement getters that modify the object
  • Instead use a method with a descriptive name

That way you will make it easier for other engineers to use your code and/or library.

(Now I'm wondering how long it will take until Charlie reads this. I'm sure he will agree with me!)