May 25, 2010

Where is the ICON for Add/Remove shortcut is stored?

Most of the product owners prefers to use Custom / Product specific icons for Add / Remove Programs (ARP) entry instead of using the default InstallShield or Windows Installer icon. Though we have an option to specify the ARP icon while creating the installer, we always wonder where this icon is stored after installation. This article details about that.

Once the product is installed, the following registry key is created.
  • HKEY_CLASSES_ROOT\Installer\Products\0CBC24CEC944140453282975376B5482   
ProductIcon - C:\WINDOWS\Installer\{EC42CBC0-449C-4041-3582-925773B64528}\ARPPRODUCTICON.exe
  • The Custom ARP icon is stored in the form of ARPPRODUCTION.exe under C:\WINDOWS\Installer\<ProductGUID>. This is just a few kb file which has the Custom icon set for it. Please note that C:\WINDOWS\Installer is a hidden folder.
  • Now you will wonder where does the key - 0CBC24CEC944140453282975376B5482 comes from. Being the developer you can easily conclude that this code is neither a Product Code nor a Package Code nor an Upgrade Code. There is a small trick involved in forming this code from Product Code and here is the steps to arrive the same
    • Remove the curly braces and write the Product Code
      EC42CBC0-449C-4041-3582-925773B64528
    • Reverse each piece of the Product Code
      0CBC24CE-C944-1404-5328-2975376B5482
    • Remove the spaces and -'s between the above code and you will get
      0CBC24CEC944140453282975376B5482This is used under HKEY_CLASSES_ROOT\Installer\Products.

April 28, 2010

InstallScript - Reversing Input String

Here is the InstallScript function to reverse the input string and return the reversed string.

///////////////////////////////////////////////////////////////////////////////

// StrReverse()
// Description: This function reverses the input string
//////////////////////////////////////////////////////////////////////////////
function STRING StrReverse(svStr)
         string szReversedString;
         number nLen, nCnt;
begin
         nLen = StrLength(svStr) - 1;
         for nCnt = 0 to nLen
                szReversedString[nCnt] = svStr[nLen - nCnt];
         endfor;
         return szReversedString;
end; // End of StrReverse

April 13, 2010

Deploying 32-bit Applications on 64-bit that requires 32-bit ASP.NET

This article focuses on how to deploy 32-bit .Net applications that are customized to work on 64-bit machine (NOT applicable for Native 64-bit application / Installer).

A 32-bit .Net Application would need 32-bit version ASP.NET 2.0 as a prerequisite and hence it might look for WOW64 registry entry (‘RootVer’ under HKLM\SOFTWARE\WOW6432node\Microsoft\ASP.NET)

• On Windows 2008 R2 64-bit machine, by default both 32-bit & 64-bit ASP.NET are registered and hence the application / installer that is looking for 32-bit registry path will work by default.

• On Windows 2003 64-bit machine, by default only 64-bit ASP.NET is registered and you will have to follow the Microsoft KB, to register 32-bit version of ASP.NET 2.0.

You will have to re-run the 32-bit installer after completing the steps in the Microsoft KB. We have tested the same on a Windows 2003 64-bit machine.

[Note: Though the MS KB talks about switching between the 32-bit versions of ASP.NET 1.1 and the 64-bit version of ASP.NET 2.0 on a 64-bit version of Windows, its applicable for 32-bit versions of ASP.NET 2.0 and 64-bit version of ASP.NET 2.0.]

Please refer here for more details on 32-bit version ASP.NET registration.

Recommended Reading:
How to switch between the 32-bit versions of ASP.NET 1.1 and the 64-bit version of ASP.NET 2.0 on a 64-bit version of Windows?

March 31, 2010

Creating New Custom Actions! Some tips to define Custom Error Messages...

Windows Installer has a long list of predefined error messages and there are many scenarios in which we would need to define Custom error messages for Custom Actions.

Windows Installer suggests the following Tips while creating Custom Error Messages.

  • The error number must be a non-negative integer.
  • The range from 25000 to 30000 is reserved for errors from custom actions. Authors of custom actions may use this range for their custom actions.
However InstallShield users have to be extra carefull to exclude the error codes ranging from 27500 to 27554, which is already being used by recent versions of InstallShield (verified in IS 12, 2009 & 2010) for IIS, Database, COM+, XML etc., related functionality.

March 10, 2010

How to register a .Net assembly into GAC using VBScript CA?

This article focuses on registering .Net assembly into GAC using VBScript Custom Action. We generally use the two approaches detailed here to register .Net Assembly into GAC. In case, if both the approach does not seem to work for your .Net DLL and you observe the following, then VBScript CA detailed below can be used to register the assembly.
  • When building the InstallShield project with .Net COM Interop property set to 'YES' (along with Destination Path to [GlobalAssemblyCache]), if you get the error =>
    Error -6210: An error occurred building COM .NET Interop information for Component [1].
    [1] indicates the part of your installation that is causing this error.
  • When .Net COM Interop property is set to 'NO', building the InstallShield project would succeed but running the installation does not register the .Net assembly into GAC.
Steps to Register .Net Assembly into GAC:
• Add the .Net Assembly to be registered under Support directory.
• Add a VBScript Custom Action (stored in binary table - MSI Type Number : 3078)– RegisterAsmToGAC with the below mentioned code snippet.

Function RegisterAsmToGAC
on error resume next
' Declaration
Const IDABORT=3
Dim szCommand, szCommand1, szCommand2, szCommand3
Dim PropArray, szSupportDir, sProductName,sAssemblyName
' Reading & Parsing the property values in Deferred CA
PropArray = Split(Session.Property("CustomActionData"), ";")
szSupportDir = PropArray(0)
sProductName = PropArray(1)
sAssemblyName = PropArray(2)
'Display Debug Message
'MsgBox szSupportDir, ,sProductName


' Using GACInstaller.exe utility downladed from http://www.codeproject.com/KB/install/GAC_Installer.aspx
szCommand1 = Chr(34) & szSupportDir & "\GacInstaller.exe" & Chr(34)
szCommand2 = " i "
szCommand3 = Chr(34) & szSupportDir & sAssemblyName & Chr(34)
szCommand = szCommand1 & szCommand2 & szCommand3
'MsgBox szCommand, ,sProductName
Set wshShell = WScript.CreateObject ("WScript.Shell")
rc = wshshell.Run(szCommand, 0, True)
if rc <> 0 then
       MsgBox "Error Registering the Assembly", ,sProductName
       wscript.quit
end if

if Err.Number <> 0 then
       MsgBox Err.Number & " - " & Err.Description, ,sProductName
       RegisterAssemblyGAC = IDABORT
End If
End Function

• The RegisterAsmToGAC CA uses 3 MSI Properties (say SUPPORTDIR, ProductName and .Net Assembly to be  registered). By default the MSI properties will not be available to the Custom actions that are in Defered mode.
• To pass parameter to Deferred CA, create a Set Property CA (MSI Type Number: 51) as 'SetRegisterAsmToGAC', set the property name as RegisterAsmToGAC and set the semicolon separated property names to the property value as [SUPPORTDIR];[ProductName];[AssemblyNameToBeRegistered].
• Schedule the SetRegisterAsmToGAC as a Immediate CA after RegisterProduct.
• Schedule the RegisterAssemblyGAC as a Deferred in System Context after SetRegisterAsmToGAC.