I’ve had my Vista PC running for quite some months now without problems, as well as Adobe Acrobat Professional and Adobe Photoshop. But not anymore…
Yesterday I plugged in the Zune that I bought on a trip to the US in january. I got the installer / driver software from zune.net. During the installation the installer requested me to update my Zune firmware, which I did. Everything went smooth.
I then left my PC for some hours to go to work. When I got back I was shown a dialog saying that my hardware configuration had changed and that I needed to reactivate Vista, hmmm. I tried the automatic activation but it said my key was already in use. After calling the automatic activation service phone number I got Vista reactivated, weird stuff.
Then suddenly Adobe Acrobat said that my current license was invalid and that I had to reactivate the software. I had to do this twice as I got the exact same message the next time I started Acrobat:
And now today I just started Photoshop, and Guess what came up:
Did me plugging in my Zune cause all of this? I have not made any other hardware changes for months, but how in the world would plugging in an MP3 player cause such a mess?
If you have ever deployed .NET windows applications, you have without doubt tried the Visual Studio Install project type. The Install project will create .MSI install applications for you, they’re great for basic installations, but nothing more than that. The .NET bootstrapper is quite lacking, at times it won’t be able to find the framework download file as it’s changed it’s location, at other times it’s not able to download it. And finally, if it does determine that the user needs the framework, it’s shown in an ugly uncustomizable GUI.
I’ve looked for an alternative, I’d prefer not to pay for using some of the well established installers such as Wise, InstallShield, ActiveInstall and so forth. What I found is a remnant of WinAmp, the NSIS (Nullsoft Scriptable Install System) project.
NSIS is both free and open source and it’s very much community driven. There are a plethora of plugins available for all sorts of different tasks, and of course you can write your own plugins for special needs.
I won’t delve too deeply into why you should choose NSIS over any of the competitors, instead I’ll show you a step by step guide of how to create an NSIS installer that bootstraps the .NET 2.0 framework as well as running custom install and uninstall actions in .NET code.
Let’s first create the simple application that we will be installing. It doesn’t really matter what it is, in this example I’ve made a single Windows Forms Application:
Now let’s start up HMNE. Click File -> New Script From Wizard. Fill in the relevant application date on the first page.
You may choose a custom icon for the installer, the default icon is an NSIS standard icon. You can also choose the resulting installation files name as well as it’s output location. If no location is specified, it will be outputted to the location that contains our script file. A great feature of NSIS is that it’s got localized versions for a lot of different languages built in, simply select the languages that the user should be able to select and the installer will automatically be localized. You can choose a couple of different GUIs, I personally prefer the Modern one. As for compression, in my tests the LZMA compression works the best, though compression time and CPU usage might be a factor for very large projects.
Now you specify where you want your application to be installed, notice the general use of variables like $PROGRAMFILES, $NSISDIR, $INSTDIR and so forth. You can also optionally choose a license file that the user must accept to continue the installation.
Now you can setup the actual files that will be installed as part of the project. You cannot select a whole project output as you can in the Visual Studio Install project, instead you must manually select the files that should be installed, usually from the Debug/Release directories of your project(s).
Optionally you can select which links you want to be placed in the application program group in the start menu, if such one should be created at all.
When the installation is done, the user can choose to view the Readme file and/or start the application - that is, if you specify an application and/or a readme file.
Finally we can choose to include an uninstaller, as well as specifying our custom uninstallation confirmation and report texts. If no custom text is specified, the default texts will be used.
When the wizard finishes, make sure to click “Save script” and “Convert file paths to relative paths”.
Finally the install script is made and ready to run. Press Ctrl+9 to compile the script. If everything succeeds, you’ll see the Setup.exe file in the same directory as the one where you saved the install script. I will not be going over the various commands and settings that are being set in the script, for that I strongly recommend the excellent built in help documents, as well as the WinAmp NSIS forums. Instead I’ll focus on how to bootstrap the .NET Framework 2.0 and how to run custom install and uninstall actions.
Add these three lines to the top of your nsi file, they include some functions that we will need:
Add this line right above the .onInit function, it makes a variable (untyped) that’ll contain a Yes/No value, depending on whether we need to install the .NET Framework or not.
Now modify the .onInit function so it matches the below, as well as adding the GetDotNETVersion function. First we ask the user what language they want to continue in (!insertmacro MUI_LANGDLL_DISPLAY). After that we initialize the InstallDotNET variable to “No”. Depending on the result of the GetDotNETVersion we tell the user that we need to install the framework, either because the user does not have the framework at all, or because the version is less than 2.0. We won’t actually install the framework yet, we’ll just remember whether we have to or not.
Now find the “MainSection” section (depending on what you called it in the wizard).
Modify the section so it looks like the below. Your file names and amount may vary, the primary part of our concern is the first part. It will test whether the $InstallDotNET variable implies that we have to install the framework. If it does, it’ll hide the usual GUI elements of the installer and start the download of the .NET Framework from any URL you specify, this could be the official download URL or a location you host yourself. If the user cancels the download we’ll delete the half-finished file and abort. Otherwise we’ll execute the dotnetfx.exe file and wait for it to complete (hence we’ll now have the .NET Framework 2.0). After having installed the framework we delete the dotnetfx.exe file again. Finally we show the GUI again.
Now comes the part where I’ll introduce our custom .NET install and uninstall actions. Create two new Console Application projects in the solution called Uninstall and Install, like the following:
Add the below function to your code, it’ll run the Install.exe file after the installation has successfully completed:
Locate the “Section Uninstall” part and add the following line as the very first:
Make sure to add both Install.exe and Uninstall.exe to the list of files that will be installed, in the Main Section. It will run the Uninstall.exe application before anything else, and wait for it to finish before continuing. After it’s done we’ll delete all the installed files, including the Install and Uninstall.exe applications - remember to add those to file deletions manually, following the syntax of the other file deletions.
Now press Ctrl+9 to build the installer, and look at it run in all of its awesomeness:
After having downloaded the .NET Framework 2.0, it’ll start the .NET installer and run it through as usual, the installation will continue as soon as the .NET installer finishes. There is currently no check for whether the user cancels the .NET installation midways or if it fails. A simple check could be made right afterwards by simple calling the GetDotNETVersion function again like we did just before, if it fails, the user hasn’t installed .NET for some unknown reason and we’ll have to abort.
In Photoshop we often work with multiple windows open. They can be cascaded to more easily be able to view the different windows and tell them apart. There’s an API function that does the same to any windows you specify, you can even define the rectangle where they should be cascaded within.
And the result:
Having three monitors generates quite a large screenshot so I’ll leave this one up for you to try / your imagination :)
Let’s be a bit more graphic. This time I’ll show you how to use the Windows API to make your forms fade in/out, slide in from the side or do various other animations. For this example we’ll have to use a Windows Forms project as we have to utilize a Form object in the example.
Now we’ll see how to activate windows and sending them to the foreground. I will be using the WindowFinder class that I introduced in the blog Finding specific windows.
Last time we saw how to obtain a windows location and size. This time I’ll show how to change a windows size and location. I will be using the WindowFinder class that I introduced in the blog Finding specific windows.
Last time I made an example of how to enumerate windows. This time I present to you a class that greatly simplifies the process of searching for specific windows, types of windows, windows belonging to a specific process, having a specific text. You can search for any number of these parameters at the same time, using regular expressions for all string matches to provide optimal flexibility.