Uninstalling a Previous Version from an MSI
Like a lot of other developers, I use the Setup & Deployment Projects in Visual Studio 2005 to create MSI files for software installs. Typically, this is a Windows Forms based application. For our in house users, especially those testing new software, there could be many iterations of a piece of software. Of course, this means installing the updated version every time I make a correction or add a new feature. Unfortunately, this has also always meant uninstalling the previous version using the trusty old “Add/Remove Programs” option in the Control Panel. Needless to say, this tends to grate on the users nerves after the first 20 reinstalls.
So, you might be wondering why I did not simply use the RemovePreviousVersions Property of the Deployment Project. The problem was that it never worked. I would set that property to TRUE and still the installer would not proceed until the previous version was uninstalled. While I found this truly annoying, it was never a big enough deal to spend a lot of time trying to figure out why the property was not working as expected… until now…
Have you ever ignored a problem until one day you just say “darn it – I’m going to figure this out no matter what it takes!”? Well, for whatever reason that was my attitude this morning. And fortunately for me, it didn’t take too long to figure out. The key is in the property name itself: RemovePreviousVersions. It is the Version part that somehow managed to elude me all this time, and therein lies the secret: I was never changing the version number. I had always focused on the Previous part before, assuming some kind of temporal meaning, incorrectly assuming that Previous meant Prior. Sometimes, our own brains just get in the way.
Of course, once I read it properly, the solution presented itself: I needed to change the Version number. I think part of my mental block here is that Versioning never occurred to me. If I remember correctly, in Visual Studio 2003, you specified a wild card and versioning happened automatically. That doesn’t appear to be the case now: I’m not saying it isn’t, but I am saying that I’m not going to take the time to investigate it. What I am going to do, from now on, is increment the Version property of the Deployment Project whenever I am preparing to deploy the Installer.
I’m going to chalk this one up as a Homer Simpson “DOH!” [slaps forehead], but hey, we all have them! Maybe this one can help someone else get over the same hurdle.
Quick and Easy Splash Screen
Updated: 10 September 2008 – I added some information about using transparent background images.
I have several applications that take a little while to start up, usually because they are establishing database connections. As we all know, if an application takes longer than 2 seconds for a screen to appear, the user will assume nothing has happened and double click the icon again. I’ve watched users practically clicking with fury because they didn’t get immediate results. Hey, maybe that could be a new movie… Clicks of Fury!
Anyway, the way around this is to provide the user a Splash Screen. That is the little icon or graphic that pops up while an application is loading. This gives the user immediate feedback that something is happening, and can provide something interesting or entertaining to fill the void while they wait. OK, the last may be a stretch, but a Splash Screen is important. For users using your software for the first time, it is also their first impression of you and your product.
Today I’m going to show you a really easy way to incorporate a Splash Screen for your application. Just follow these steps…
Create the Splash Image
This step is actually optional, which will make sense in a minute, but you can get much more impressive results using a Graphic for your Splash. You can use just about any standard image type. You can also use irregularly shaped images (with transparent background) to achieve some pretty cool effects.
Create the Splash Form
I usually call mine FormSplash, so that I can always cut and paste the rest of the code from this article into my Main Form. Follow these steps:
- Set the FormBorderStyle property to None.
- If you created an image in #1 above, set the BackgroundImage property to the image you created. Usually you will also want to set the BackgroundImageLayout property to None. If you chose not to create an image, you can simply set the background color of your form to a color of your choosing and place labels and such on your FormSplash to represent text.
- Adjust the FormSplash size to the same size as the Image or to an appropriate size for your Splash.
- Set the ShowInTaskbar property to False. This is optional but will prevent an extra item from showing up temporarily and unnecessarily in the task bar.
Your Splash Form is now ready to be used.
Using Transparent Background Images
If you are using a Background Image with an irregular shape expecting the transparent parts to actually be transparent, then at this point you may be a little frustrated. For instance, I just created a Splash graphic with rounded borders and saved it as an RGB/A PNG file. When I used it as the background of the Splash Form, you could see the corners as solid Control colored sections. In other words, the transparency only went from the Background Image to the Form BackColor. Naturally, I want the transparency to show all the way through to the Desktop.
The way around this was actually pretty simple: there is a property on the Form called TransparencyKey. Set it to the same color as BackColor. Now, that color is treated as transparent and the corners no longer show. It may be a good idea to pick an uncommon color, like Tomato or Bisque (ummm… lunch!) instead of the default Control.
Show the Splash from your Main Form.
Now that you have FormSplash, you need to instantiate and show it from your Main Form. This is almost like any other Form.Show(), but with a little kick:
FormSplash splash = new FormSplash(); splash.Show(); splash.Update();
The only difference here is the splash.Update() line. This will force the FormSplash to redraw itself immediately, not waiting for the method to finish. I place this code as the first in my Main Form Constructor, immediately preceding the InitializeComponent() call.
Now to finish it all off, just hide the form at the end of the Constructor:
splash.Hide();
And there you have it: a quick and easy Splash Screen. Now whenever the application is starting, it should show your users a lovely Splash Screen while they wait. And hopefully we can hold off the Clicks of Fury!