Thursday, April 26, 2012

How to take backups within InnoSetup

One of the important requirements for any software installer is to be able to take a backup of the system before new code is updated. Once code is updated, there must be a rollback (or uninstall procedure) as well. The installer must be able to place the code backup in a place where it can easily pick up code from when uninstalled. For software patches where several patches can be installed successively, this can get fairly complex since we only want to rollback specific code which is associated with the patch.

Taking code backups and doing a rollback is not an inbuilt feature in InnoSetup. However, with some customization, this can be easily achieved.

To backup code, a line very similar to code installation can be created when the installer is first created. For example:

Source: {app}\\*; DestDir: "{#InstallHomeDir}\UnInstall\{#MyAppVersion}\Websites\"; Components: Core; Flags: {#UninstallFlags}; Check:TakeBackup;
This line is similar to a code install line, except it copies code from the application folders on  the target machine to a pre-determined backup location. So this line only fires at run-time when code is being installed. For each "Source" line in the installer for code installation, there will be a matching line for backup similar to the one above. Note that a version number is included inside the DesDir to handle multiple patch scenarios. A Check is also used to turn backups on or off. 

Once the backup is done, at un-install time, you can fire the following command from within Inno Setup:

Exec('xcopy', ExpandConstant('"{#InstallHomeDir}\UnInstall\{#MyAppVersion}\Websites" "{app}" /f /c /v /e /r /h /y'), '',SW_SHOW, ewWaitUntilTerminated, ResultCode)
This will copy ALL your folders you have backed up to the {app} folder.

Executing VB Scripts within Inno Setup

While InnoSetup comes with its own programming language and you can use COM or build your own DLLs to do custom tasks, one of the easiest and versatile methods that I have come across is to invoke VB Scripts from within the installer. VB Scripts provide a much more richer set of programming constructs, error handling and are much more documented than Pascal Script (Inno Setups own programming language). While VB Scripts dont come close to what can be achieved by C# or C++ program, then can be a very powerful tool given they are around on all windows systems.

Here is an example of how you can invoke VB Scripts from within Inno Setup:

CommandWithParams := ExpandConstant('{app}\validate.vbs') + ' /Ovalidate.out /D'+ ExpandConstant('{app}') + ' /P"' + DBType;

Exec(ExpandConstant('{sys}\cscript.exe'), CommandWithParams, ExpandConstant('{app}'), SW_HIDE, ewWaitUntilTerminated, ResultCode);

Wednesday, April 25, 2012

Making a Web Request within Inno Setup

Inno Setup is a very easy to use installer for Windows Software. We use it to package and deploy our ASP.NET code, releases, automatically download releases from our website, determine required patches, configure the web.config files etc. A lot of this is achieved by integrating VB Scripts inside the installer instead of writing script code inside Inno Setup. However I recently had a requirement where an external ASMX web service needed to be invoked to encrypt a password entered by the user before it. This could be achieved by using a vb script and invoke that inside the installer but using the Windows WinHTTP inside InnoSetup was fairly easy and this was the first time I directly used COM inside Inno Setup. Here is the code:

WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');

WinHttpReq.Open('GET', MYURL, false);
WinHttpReq.Send();

if WinHttpReq.Status <> 200 then begin

MsgBox('Could not run service to get encrypted password.', mbError, MB_OK);
end else
begin
//MsgBox('SUCCESS', mbInformation, MB_OK);
end;
 
if Length(WinHttpReq.ResponseText) > 0 then begin
index2 := Pos('', WinHttpReq.ResponseText); index1 := Pos('', WinHttpReq.ResponseText) + Length(''); 
EncrPasswd := Copy(WinHttpReq.ResponseText,index1,index2-index1);
end;

Friday, April 6, 2012

Setting up Subversion on Windows

There are a dozen ways to set up Subversion on Windows. I have done it at least three or more time and the last two times, I noticed I used different methods. On the server I used last, I am now stuck with an extra Apache instance so I am writing this blog so that other people don't make the same mistake. In addition, once you set up SVN, you should set up nightly backups as well where the repository is backed up on an external drive. That has saved me at least once when the host Windows OS failed on us once crashing the hard disks with it. One day I know I am going to be back on this page looking through my notes setting up SVN for the fourth time.

In our company we use Windows predominantly as there are many more people who are familiar with managing it, backing it. There is more software which can be re-used as well inside the organization. If I used Linux, which I am obviously more familiar with in terms of using SVN or as a product development box, I am sure the installation, backup and maintenance will be a lot simpler but then I am going to be stuck with it :) 

The first step to installing SVN on Windows is to find an idle server or install one from scratch. A Windows 2008 Server, 32 bit would enough. Make sure you put on some partitions on it to store the repositories since these can become huge. I would say put 250-400 GB in a separate partition or drive and use RAID on this server. In my case when the server crashed, it took down the RAID controller with it making the hard drives unusable. So you must still do backups. 

Second step is to make sure there is no IIS running on this box, since we will use the port 80 for SVN. Also make sure other software which grinds the disk is kept to a minimum (like SQL Server etc). You will possibly install MySQL on this server if you keep reading my blog.

Now you can download SVN binaries from one of the partners - Collabnet or WANDisco. You will need to register on their site before you download the binaries and make sure you dont download a "bundle" which includes other software like Apache. We will install that separately, or at least I did. By downloading it separately, you can get the latest Apache version which will work for you. Dont try to set up SVN as a service or anything since we will be using it with Apache.

On my machine for example, SVN got installed at: C:\Program Files\WANdisco\Subversion. Just note down where it gets installed on your system.

Wednesday, April 4, 2012

Copy Paste not working inside Windows RDP?

You know the solution to the problem! You remote into the Windows server and paste the script, excited. Then you paste it again and then one more time only to find out nothing is getting transferred. Then you go back and try it again. It is frustrating isn't it. Especially since at the same time everyone else is having no issues doing the same thing. Well, next time you face this problem, launch the Task Manager and look for a process called "rdpclip.exe"running under your user id. Kill it and then restart it using the Run prompt. Things should magically start working. 

You should know that this process only runs if someone else is logged onto your computer using remote desktop. It is a server side process. This process has some known issues as well like sometimes it can eat up too much memory and CPU. When you exit out of a remote desktop session with something stuck in your clipboard then you run the chance of confusing this process. In any case it is safe to kill at the end of the remote session before logging off.