Select or Focus, Which One to Use?

Quite a few Windows Forms controls have both Focus() and Select() methods available. This presents unique challenge - which method to use?

While they both offer same result (ok, almost same) there is subtle difference. Focus is intended only for control authoring, e.g. when you have some composite UserControl. For all other scenarios, Select should be used. Probably nothing bad will happen (or maybe some kittens will die) if you use Focus on controls that behave. However, small differences might force you to use Select on some other controls and that leads to code with uses Focus half of time and Select another half. Kinda hard to read.

It might improve actual readability if Select is used all the time.

Nullable Fields in Database

Duty of every decent Data Access Layer is to convert data types that we have in database to data types of our favorite programming language (C# in this case). And this is easy in case of “normal” data types. Great example here is humble integer. Database and C# have 1 to 1 mapping here. It is as easy as “var x = (int)dr["field"];”.

However, database can have one more trick up it’s sleeve. Every data type can be “nullable”. That is, it can be integer but it can also have special state which signifies lack of data. C# also has same possibility with his nullable types. Intuitive code “var x = (int?)dr["field"];” will not work properly.

While we can make wrapper function for any nullable data type that we need, there is simpler way. All that we need is:

private static Nullable<T> ToNullable<T>(object value) where T : struct {
    if (value == null) { return null; }
    if (System.Convert.IsDBNull(value)) { return null; }
    return (T)value;
}

Now conversion can proceed with “var x = ToNullable(dr["field"]);”. That doesn’t look that ugly, does it?

Update Kills VHD Boot (Temporarily)

Some windows update that got installed on my VHD-based Windows in week from 2011-06-12 to 2011-06-19 killed possibility to boot from them. Instead of normal startup procedure I was greeted with Repair Windows.

Fortunately I had another Windows installation on same machine so I was able to check boot parameters:

bcdedit

 Windows Boot Manager
 --------------------
 identifier              {bootmgr}
 device                  partition=D:
 description             Windows Boot Manager
 locale                  en-US
 inherit                 {globalsettings}
 default                 {current}
 resumeobject            {fa179570-87b4-11e0-b0a7-da74dade416b}
 displayorder            {current}
                         {fa179565-87b4-11e0-b0a7-da74dade416b}
 toolsdisplayorder       {memdiag}
 timeout                 1

 Windows Boot Loader
 -------------------
 identifier              {current}
 device                  partition=C:
 path                    \Windows\system32\winload.exe
 description             Windows 7 (x64)
 locale                  en-US
 inherit                 {bootloadersettings}
 recoverysequence        {fa179566-87b4-11e0-b0a7-da74dade416b}
 recoveryenabled         Yes
 osdevice                partition=C:
 systemroot              \Windows
 resumeobject            {fa179564-87b4-11e0-b0a7-da74dade416b}
 nx                      OptIn

 Windows Boot Loader
 -------------------
 identifier              {aa179565-87b4-11e0-b0a7-da74dade416b}
 device                  partition=E:
 path                    \Windows\system32\winload.exe
 description             My VHD installation
 locale                  en-US
 inherit                 {bootloadersettings}
 recoverysequence        {fa179572-87b4-11e0-b0a7-da74dade416b}
 recoveryenabled         Yes
 osdevice                partition=E:
 systemroot              \Windows
 resumeobject            {fa179570-87b4-11e0-b0a7-da74dade416b}
 nx                      OptIn

There was my problem - somehow update has changed VHD boot device to nonexistent partition E:.

Solution lies in two commands:

bcdedit /set "{aa179565-87b4-11e0-b0a7-da74dade416b}" device "vhd=[C:]\VHDs\Windows7.vhd"
 The operation completed successfully.

bcdedit /set "{aa179565-87b4-11e0-b0a7-da74dade416b}" osdevice "vhd=[C:]\VHDs\Windows7.vhd"
 The operation completed successfully.

P.S. My best is that one of following updates is the killer:

Detection of Executing Program in Inno Setup

Illustration

When upgrading your application it is very good practice to let your setup program know whether your application is running. This way setup will tell you to close your application instead of requiring Windows restart.

Solution comes in form of Mutex synchronization primitive. Application will create it and hold it until it is closed. If setup notices that application already has mutex under control, it will “complain” to user. It is then user’s task to close application. It is not as comfortable as closing application automatically but it does the job.

Since we need a global mutex for this purpose, we should not use something that could get used in other application for other purpose. To me best format of name is MyCompany_MyApplication. It is highly improbable that anybody else would use it. If you want to be (almost) sure getting random string is also a possibility.

For this to work we need to tell InnoSetup which mutex we plan on holding:

[Setup]
...
AppMutex=Global\MyCompany_MyApplication
...

In application we need to use same Mutex name:

namespace MyNamespace {
    internal static class App {
        private static readonly Mutex SetupMutex = new Mutex(false, @"Global\MyCompany_MyApplication");

        [STAThread]
        internal static void Main() {
            //do some great stuff.

            Application.Run(new MainForm());

            SetupMutex.Close(); //notice that it HAS to be after Application.Run
        }
}

P.S. Why do we MUST put SetupMutex.Close() after Application.Run() is exercise left to user. I will just note that it has something to do with garbage collection.

P.P.S. While this was written with InnoSetup in mind it is also applicable to virtually all setup systems out there.