InstallShield Tips and Techniques

July 5, 2012

Checking return code from VBScript Custom Action

Filed under: Reference Materials — shieldmaster @ 9:20 pm

Recently I had the need to run a Custom Action in an older InstallShield Basic MSI project (version 10.5). The Custom Action would verify that a required application product was already installed – and at the correct version level. If either check failed, the Custom Action should return a negative return code and cause the installation to be cancelled.

I did not want to create the Custom Action using InstallScript since that version had the InstallScript Script Engine delivered as a separate MSI (ISScriptEngine.msi), and I wanted no additional MSI requirements. I decided on using VBScript for the Custom Action – but indicated earlier, I needed the VBScript function to return a value that can be used to abort the installation. I have used VBScript often in the past to retrieve CustomActionData and perform activities, but never had to need to issue a return code. Always I would create a VBScript Custom Action with the VBScript embedded in the Custom Action – but I could never could get this script technique to work.

Finally I created a VBScript Custom Action – but stored the VBScript in a .VBS script file.

Here is a snapshot of the Custom Action:

Note that I entered “CheckAgentVersion” in the Script Function line. Here is an extract of the VBScript:

Function  CheckAgentVersion

    Dim    sAgentVersion

       Const  cAgentBaseVersion = "11.01.0001.0000"

    
 

      'MsgBox "Running AgentLP CheckAgentVersion Custom Action"

       LogInfo "======== Running AgentLP CheckAgentVersion Custom Action =========="

       Set objShell = CreateObject("WScript.Shell")

 

       sAgentVersion = Session.Property("AGENT_VERSION")

       If sAgentVersion = "NOT FOUND" Then

        LogInfo "Agent was not installed!" 

        MsgBox "WARNING:  Agent was not installed!  Screen Capture Language Pack will abort!" 

        CheckAgentVersion = -1 

    Else 

           LogInfo "Agent was installed - and version is: " & sAgentVersion   

           If Eval("sAgentVersion > cAgentBaseVersion") then

            LogInfo "Agent installed is proper version!"   

              CheckAgentVersion = 0 

            LogInfo "======== Exiting AgentLP CheckAgentVersion with return code of " & nReturn

            Exit Function 

        Else

              LogInfo "Agent installed is not the proper version!" 

            MsgBox "WARNING:  Agent installed is not the most current version, so Language Pack will abort!      

            CheckAgentVersion = -1                   

            LogInfo "======== Exiting AgentLP CheckAgentVersion with return code of " & nReturn   

            Exit Function

        End If     

    End If     

End Function

 

Function LogInfo(msg)

   dim rec

   Set rec = Session.Installer.CreateRecord(1)

   rec.StringData(0) = msg

   LogInfo = Session.Message(&H04000000, rec)

   'LogInfo is a VBScript function copyrighted (@2011) by Ian Linsdell

End Function

 

By setting the return code to the function name, it will be correctly interrogated by the Custom Action. Granted, you should never pop up a message dialog unless you query the “UserUI” property to see if they are running full dialogs (i.e., not silently). But this should give you a heads up on how to accomplish this.

Also a couple of notes about the VBScript function:

  1. A co-worker Ian Linsdell wrote the slick sub-function that allows you to write directly into the MSI log file. If you use this function, please continue to keep his copyrighted comment!
  2. The MSI Property “AGENT_VERSION” is a result of a System Search entry that looks for the registry entry that confirms the Agent was installed. Obviously if the installation was not found, the default value of “NOT FOUND” would be in the MSI Property.

Regards
ShieldMaster

 

May 27, 2012

Memorial Day 2012

Filed under: Reference Materials — shieldmaster @ 3:05 am

NO, FREEDOM ISN’T FREE
I watched the flag pass by one day.
It fluttered in the breeze.
A young Marine saluted it,
And then he stood at ease.
I looked at him in uniform
So young, so tall, so proud,
With hair cut square and eyes alert
He’d stand out in any crowd.
I thought how many men like him
Had fallen through the years.
How many died on foreign soil?
How many mothers’ tears?
How many pilots’ planes shot down?
How many died at sea?
How many foxholes were soldiers’ graves?
No, freedom isn’t free.
I heard the sound of taps one night,
When everything was still
I listened to the bugler play
And felt a sudden chill.
I wondered just how many times
That taps had meant “Amen,”
When a flag had draped a coffin
Of a brother or a friend.
I thought of all the children,
Of the mothers and the wives,
Of fathers, sons and husbands
With interrupted lives.
I thought about a graveyard
At the bottom of the sea
Of unmarked graves in Arlington.
No, freedom isn’t free.
©Copyright 1981 by CDR Kelly Strong, USCG (Ret).
This poem is important to Kelly because he wrote it as a high school senior (JROTC cadet) at Homestead High, Homestead, FL. in 1981. It is a tribute to his father, a career marine who served two tours in Vietnam. When he finds others trying to take credit for the authorship of the poem, Kelly sees it as a dishonor to the man who inspired the poem, his Dad.

May 3, 2012

Understanding “Per-User” or “Per-Machine” context for application Setup packages

Filed under: Reference Materials — shieldmaster @ 1:05 am

Windows Installer can install an application Setup package in one of two contexts: a “Per-Machine” installation is performed to allow all registered users of the computer to access and use the application. A “Per-User” installation is performed for the single user that is executing the application Setup – it is not available for use by any other registered user of the computer.

Historically with Windows XP and earlier Operating Systems, the “Per-User” or “Per-Machine” context referred to ensuring the Shortcuts/Icons were visible to just the single user or all users. There were implied restrictions when you selected either of the installation contexts – but there was no overt restriction during the installation.

With the introduction of Windows 7 and the more stringent UAC (User Access Control) restrictions, we are seeing more frequently the need for an installation package to “Run as Administrator”. This is because standard users now have more limited privileges and are being prevented from installing into the “Per-Machine” context without first obtaining permission.

With this posting I hope to clear up and improve your ability to address these requirements within your installation packages.

Executing an installation package in the “Per-User” context

On a machine that is setup for multiple users, the application installation package is run by a specific user and no other user can access that application. The other users don’t even see any installed artifacts – so there is no evidence of:

  • Application files
  • All application files would need to be written to Per-User specific folders that are not visible to other users – for example anything written to “c:\Program Files\ISI” would be visible to other users.
  • Icons/Shortcuts
  • Entry in the Add/Remove Control Panel
  • Registry

    Obviously the application would need to be specifically designed to register files in HKCU\CLASSES and registry entries only added to HKCU\Software\xx for application access.

How does the installation package announce that it is to be run as “Per-User”?

There is a MSI property that can be placed within the application package that allows the application setup to announce to Windows Installer that it wants to be installed “Per-User”.

Windows XP

The ALLUSERS MSI property can be set so that the application package will be run in the “Per-User” context. Both by the absence of the ALLUSERS property or the property is present but the value is set to NULL (ALLUSERS=”") will force the installation package to be run in the “Per-User” context.

Vista

On Vista, you could still force the installation package to be run as “Per-User” as we have discussed. Note that the user’s privileges are immaterial when running in the “Per-User” context – but once the decision is made that the install will be run in the “Per-User” context (By setting the ALLUSERS=”" or not having the property), the User rights issue makes no difference. But remember, the install starts but it WILL FAIL
if the user doesn’t have Admin rights and the install tries to write to any machine-wide resources.

If a user has Admin rights, but the install is run in the “Per-User” context, with the Admin rights, any accidental writing to machine-wide resources will be allowed.

Windows 7

On Windows 7, the ability to run as “Per-User” is constrained by the specifics of the package. Essentially these points are important for an application setup to be eligible for a “Per-User” installation context:

  • All files are installed to Per-User folders, such as
    • “C:\Documents and Settings\$User\Local Settings\Application Data” on WinXP
    • “C:\Users\$User\AppData\Roaming” on Windows 7
  • All Shortcuts and the Add/Remove Control Panel entry are only seen by that user
  • All registry entries (Application data and registration) are made to HKEY_CURRENT_USER hive.
  • No registry entries are made to machine-wide registry keys, such as HKEY_LOCAL_MACHINE or HKEY_CLASSES_ROOT hives
  • The installation package cannot allow the user performing the installation package to select destination directories that are machine-wide, such as “c:\Program Files”
  • All application binary file (EXE, DLL) need to be digitally signed to be allowed to be installed by “Per-User” for Windows 7.

On Windows 7, if any of the above constraints are not met, the package will be installed “Per-Machine” – this means that a “Per-User” will not be allowed!

Best Practices

In general, you should configure your installers to be “Per-Machine” installs (i.e. ALLUSERS=1). You should only use “Per-User” installs (i.e. ALLUSERS=”") if your installer meets the following conditions:

1. All files are guaranteed to be installed to “Per-User” folders. Most installers allow the user to choose the install location and default to ProgramFilesFolder which disqualifies them from this requirement.

2. There are not any changes being made to machine-wide Registry keys such as HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT, etc.

3. There are not any other files or folders affected by the installation that are not in “Per-User” locations.

If your installer does meet that criteria, you should also set the “Privileges required” value on the Package tab of the Project Settings screen to Limited so that the Windows Installer engine does not force a UAC elevation to take place once installation is about to begin.

Having said all of that, in practice it is very rare to design and deploy a “Per-User” installation. In general, you should keep your installers as “Per-Machine” installs.

Considerations regarding “Per-User” Installations

There are several common scenarios that an arise when the choice of “Per-User” versus “Per-Machine” is given to the user:

  1. Major Upgrades can Fail

    If you use the Upgrade code feature of Windows Installer to perform a major upgrade the detection of the existing software will fail if: (a) the original software was installed with ALLUSERS=”" and the new software has ALLUSERS=1 in its Property table or passed on the command line or (b) the original software was installed with ALLUSERS=1 and the new software has ALLUSERS=”" or ALLUSERS is not defined in the Property table or on the command line.

  2. Uninstall Problems

    If two different users on the system install the software with ALLUSERS=”" they will both have their own shortcuts and Add/Remove Programs entries made (which is fine and is by design). However, if some of the files are installed to a shared location (such as ProgramFilesFolder) and one of the users uninstalls the software, the other user will not be able to use the software even though their shortcuts and Add/Remove Programs entries are still intact. In other words, the two installed instances of the software will not “know” about each other.

  3. Support Issues
  • Installing to locations the user has the ability to alter might reduce the confidence the package producer has for the integrity of the install. This can affect support costs as well as computational correctness under a regulatory environment (lawyers, accounts, food and drug companies, government agencies, etc)
  • Multiple instances of an install means there is duplicate copies of binaries on the machine which wastes disk space. A “Per-Machine” install creates a single copy of common binaries for all users thus saving space.
  • Software is less secure because updating behavior has to be done for each user on the machine. In other words, the occasional user on the machine can made the machine vulnerable because they are not on the machine often enough to keep the software they use up to date.
  • IT departments want programs in locations users can’t tamper with. User tampering is a major source of support costs.
  • Centralized install, servicing, and uninstall from a central IT department are all more challenging when the apps are just in the users profile. There are numerous conditions where it is known not to work at all

How to block users from installing applications “Per-User”

Setting the policy DisableMSI to 1 will block the “Per-User” install operations of dual mode packages. Setting it to 1 will also block all the uninstall/patching/upgrade of the packages that were previously installed with MSIINSTALLPERUSER=1. Setting the DisableMSI to 2 will block windows installer from doing any operations on the machine. Setting the DisableUserInstalls policy to 1 disables install/uninstall/upgrade/patching of “Per-User” applications.

Executing an installation package in the “Per-Machine” context

What does it mean if an installation package runs “Per-Machine” context?

On a machine that is setup for multiple users, the installation package is typically run by the machine administrator, and all users can use that application. They can see any application files placed in the machine-wide folder (Program Files), all shortcuts and the entries in the Add/Remove Control Panel.

Essentially these points are important for a “Per-Machine” context:

  • All files are installed to machine wide folders, such as “c:\Program Files” on WinXP or Windows 7
  • All Shortcuts and the Add/Remove Control Panel entry are seen by all users
  • All registry entries (Application data and registration) are made to machine-wide registry keys, such as HKEY_LOCAL_MACHINE or HKEY_CLASSES_ROOT hives
  • The installation package can allow the user performing the installation package to select destination directories that are machine-wide, such as “c:\Program Files”

How does the installation package announce that it is to be run as “Per-Machine”?

Windows XP

The setting of the MSI Property “ALLUSERS=1″ dictates that an installation package is to be run in the “Per-Machine” context. This setting will force the installation package to be run in the “Per-Machine” context, but if the User does not have Admin rights the installation package fails.

Vista

On Vista, you could still force the installation package to be run “Per-Machine” by setting of the MSI Property “ALLUSERS=1″ as we have discussed.

Windows 7

On Windows 7, you could still force the installation package to be run “Per-Machine” by setting of the MSI Property “ALLUSERS=1″ as we have discussed.

If the user has only User Access privileges, Windows Installer performs a “Per-Machine” only if Admin credentials are provided to the UAS dialog box – typically by specifying “Invoker=Admin” in the setup manifest.

Creating an installation package that runs in either the “Per-User” or “Per-Machine” context

Windows XP

On Windows XP, you can have the ALLUSERS property set to “ALLUSERS=2″, a value that allows the Operating System to determine whether the install runs as “Per-User” or “Per-Machine” based on whether the user has Admin rights. In this scenario, the conditional logic determines that having Admin rights allows the installation package to run in the “Per-Machine” context, but limited rights forces the install to run in the “Per-User” context.

Vista

On Vista, you could still force the installation package to be run as “Per-User” or “Per-Machine” as we have discussed. But the introduction of the UAC prevented the Operating System from providing the conditional logic to determine where an installation package should be run in the “Per-User” or “Per-Machine” context (for example, setting ALLUSERS=2 and the logic checks the user’s Admin rights).

The workaround solution was to create two separate installation packages, the one that was designed for “Per-User” would have the UAC compliant bit set, while the one that was designed for “Per-Machine” did not have the UAC compliant bit set (UAC compliant bit set refers to the MSI’s Word Count row found in the Information Summary table – which must be done via the Direct Editor when using InstallShield v2009 or earlier). Once this bit is set, no UAC prompt is required and the package is installed “Per-User”. The author of the installation package would need to ensure that the shared locations (c:\Program Files) were not used since there was no “Per-User” equivalent of “Program Files”.

Windows 7 introduces a dual-Mode Package:

With Windows Installer version 5.0 installed on Windows 7, you can author a dual mode package that can be installed “Per-User” or “Per-Machine”. Setup developers that use a dual-purpose package for their application can provide their users with a choice of installation context at installation time and can remove UAC credential prompts from “Per-User” installations on Windows 7 or Windows Server 2008 R2. The development of a dual-purpose Windows Installer 5.0 package for installation on Windows 7 and Windows Server 2008 R2 is referred to as single package authoring.

Setup authors can set the MSIINSTALLPERUSER property to 1 and ALLUSERS to 2 to identify the package as a dual-purpose package. Note that MSIINSTALLPERUSER is only evaluated when ALLUSERS=2. These properties can be specified in the package, passed through the command line, modified by a transform, or – more commonly – selected through a user interface dialog.

Adhere to these Development guidelines for dual-mode packages to ensure your package can be installed in either the “Per-User” or “Per-Machine” context. Here are some crucial points from that extensive list:

  • Consider activating the “Per-User” option in the dialog “Ready to Install” for the user interface of your dual-purpose package that enables the user to choose the context at installation time. See the example shown:

  • Validate the package using Internal Consistency Evaluators – ICEs. The package must be able to pass validation by ICE105 to be a valid dual-purpose package.
  • Use the ProgramFilesFolder property in the Directory table of 32-bit Windows Installer Packages to specify the locations of directories containing 32-bit components not shared across applications. When a user installs the dual-purpose package using the “Per-Machine” context, these components are saved in the Program Files folder on 32-bit versions of Windows and in the Program Files (x86) folder on 64-bit versions of the system. The components in these directories can be accessed by all users. When a user installs the dual-purpose package on Windows 7 or Windows Server 2008 R2 using the “Per-User” context, these components are saved in the Programs folder of the current user (for example at %LocalAppData%\Programs) and can be accessed only by that user.
  • Use the CommonFilesFolder property in the Directory table of 32-bit Windows Installer Packages to specify the locations of directories containing 32-bit components shared across applications. When a user installs the dual-purpose package using the “Per-Machine” context, these components are saved in the Common Files folder and can be accessed by all users. When a user installs the dual-purpose package on Windows 7 or Windows Server 2008 R2 using the “Per-User” context, these components are saved in the Common folder of the current user (for example at %LocalAppData%\Programs\Common) and can be accessed only by that user.
  • Store “Per-User” configuration data for the application under \Users\username\AppData.
  • Do not use custom actions in your package that require elevated privileges to run. The CustomAction table should contain no custom actions that have been marked to run with elevated privileges. For more information about elevated custom actions, see Custom Action Security.
  • Do not write in any global system folders. The Directory table should not contain a reference to any of the following system folder properties.

    AdminToolsFolder

    CommonAppDataFolder

    FontsFolder

    System16Folder

    System64Folder

    SystemFolder

    TempFolder

    WindowsFolder

    WindowsVolume

  • Do not install a common language runtime assembly into the global assembly cache (GAC.) For more information about installing assemblies to the global assembly cache, see Adding Assemblies to a Package and Installation of Common Language Runtime Assemblies.
  • Do not install any services. Do not use the ServiceInstall table to install a service.

Creating an installation package that runs without the UAC Dialog Box

When elevated privileges are not required to install a Windows Installer package, the author of the package can suppress the dialog box that User Account Control (UAC) displays to prompt users for administrator authorization.

This means that the application package is eligible for being installed in the “Per-User” context and conforms to these Development guidelines.

To suppress the display of the UAC dialog box when installing the application, the author of the package should do the following:

  • Install the application using Window Installer 4.0 or later on Windows Vista.
  • Do not depend on using elevated system privileges to install the application on the computer.
  • Set the MSI Property “ALLUSERS=1″

    Installs the application in the “Per-User” context and make this the default installation context of the package. If the ALLUSERS property is not set, the installer installs the package in the “Per-User” context. If you do not include the ALLUSERS property in the Property table, the installer does not set this property and so “Per-User” installation becomes the default installation context. You can override this default by setting the ALLUSERS property on the command line.

  • Set Bit 3 in the Word Count Summary property to indicate that elevated privileges are not required to install the application.

Setting an installation package so that it requires Administrative Privileges

 

There are two configuration items you can use in the InstallShield panels, one is the “Require Administrative Privileges” property in the Summary Information Stream, the other is the “Required Execution Level” property in the Release View.

 

Here is an explanation of what they are used for:

  • “Require Administrative Privileges” indicates how the application setup manifest (which is embedded by InstallShield in the setup launched – when you specify a setup in the Media) should be configured. The Manifest controls how the operating system runs the Setup, any Setup Prerequisites and the .MSI file.
  • “Required Execution Level” applies to just how the Operating System handles the .MSI file. Setting this configuration value will set the fourth bit of the Summary Information Stream’s Word Count property – which in prior to InstallShield v2010 had to be set manually.

 

In my experience, here’s what the two settings mean at runtime. If you launch from a Setup (Setup.exe) Windows 7 will first evaluate the directions in the manifest. If you don’t have a setup.exe, or if setup.exe runs as a limited user (either lowest privileges, or highest available on a limited account), then the User Interface Sequence MSI process (Foreground process as it were) will be launched as a limited user. If you have a Setup running with administrative privileges then the client-side MSI process will be running with administrative privileges.

Now assuming your client-side MSI process is running as a limited user, the Summary Info stream bit comes into play. If you say the MSI requires administrative privileges then when it launches the Execute Sequence MSI process (background processing), MSI will prompt for administrative privileges just like any other UAC prompt, and the Execute Sequence process will run as though you’re an administrator. If you say the MSI does not, there will be no prompt, and MSI will run as though it has limited privileges. This will generally lead to failures unless the MSI does not write to machine-wide resources (i.e., doesn’t to “c:\Program Files\ISI”).

Issues with Custom Actions running “Per-User”

When running a “Per-User” installation, having the Custom Action set as “deferred in system context” actions will run in the same context as normal deferred or immediate custom actions, which is with user impersonation. This can potentially cause a runtime issue with the custom action in the following circumstances:

  1. The user that launched the MSI installation is not an administrator, or is running on Windows Vista, in which users are part of the administrators group, but do not have administrator privileges by default.
  2. The custom action attempts to modify a resource in a “Per-Machine” location on the machine, such as a file in Program Files, or a registry key/value in HKEY_LOCAL_MACHINE in the registry.

While this may not be an issue with Windows XP or older versions of Windows, Windows Vista/Win7 does not run users with full administrator privileges by default. Therefore, since a “deferred in system context” action runs with user impersonation when ALLUSERS is not set, the custom action could fail.

The recommendation to prevent this issue arising is to ensure that a “Per-Machine” installation is always performed by setting ALLUSERS to 1 in the Property Table or on the command line. Per-machine installations are generally easier to manage, and are the current best practice recommendation from Microsoft.

For further research, please refer to my reference documents:

Required Execution Level

Installation Context

ALLUSERS property

MSIINSTALLPERUSER property

Authoring Packages without the UAC Dialog Box

Authoring a single package for Per-User or Per-Machine Installation context in Windows 7

Per-Machine vs. Per-User Installations

Packaging issues that may be encountered when working with Vista

Single Package Authoring

Should I write my installer as a Standard User install?

 

ShieldMaster

April 18, 2012

Using InstallShield as a shell

Filed under: Reference Materials — shieldmaster @ 12:31 am

I recently completed a unique project that required a setup that did not behave like a normal InstallShield setup. In essence the customer had some specific behavior that they wanted the setup to demonstrate, which ran contrary to what you would expect for a normal setup.

For example, these are the condensed specifications:

  • On a clean machine, perform a normal installation of the application source
    • Oh, the source application files will be Zipped and extracted from the web – not carried within the setup
    • Configure various 3rd Party applications (MySQL, Tomcat, etc.)
    • Provide a shortcut on the desktop that will launch the setup again
  • When the setup is launched on a machine that has the application already installed, provide a dialog with three choices:
    • Remove the application
    • Update the application license
    • Update the application source files – this means downloading an updated set of application Zip files

    Normally when an application is rerun you are presented with the Maintenance Dialog, and you have the normal choices of Repair, Modify or Remove. In this case they wanted new source downloaded, or the ability to navigate to directory containing a license file – not normally available!

     

Talk about “thinking outside the box!” – this combined quite a few of the individual amenities that I have offered in the past for special situations. In my mind, I went over the possibilities:

  1. Remove the Standard Actions that register the application MSI – which I blogged about here: Disable MSI Registration
  2. During the initial installation, I would need to create a special registry entry that appears in the Add/Remove Control Panel that will display the Application and it’s version number – but it is not a true entry, the user can’t use it to uninstall the software
  3. Creating a shortcut on the Desktop to the MSI that when executed by the user would:
    1. Recognize that the application was installed (check for the Registry entry) – if not found would perform an initial installation, but if found it would display a special set of dialogs, such as:
      1. Welcome Screen
      2. Action Dialog with the three options noted above
    2. Intra-dialog scripting that recognized the dialog selection and either perform the action (removal, update source or additional dialogs to allow user to specify a license file
  4. Scripting that would connect to a Webpage, download and unzip source files – extract a version file and use to update the entry in the Add/Remove Control Panel
  5. Scripting that would download the license, plus a Dialog with Browse capability to allow the customer to navigate to the directory containing the license and select it for manipulation
  6. Scripting to log every action and results to enable the Tech Staff to diagnose installation issues (poor internet connections, etc.)
  7. Scripting that would need to handle the 3rd Party application:
    1. Evaluate system to ensure the required 3rd Party apps are present (and enable the customer to easily alter the minimum release level requirement). Customer did not want to attempt to install missing 3rd Party applications – just check and stop install if anything is missing, but report exactly the issue to the customer.
    2. Configure each of the required 3rd Party applications – from uploading MySQL Scripts to configuring Java and Apache Tomcat and starting/stopping it’s services

 

As it turned out, I delivered the application in stages to allow the customer to carefully review the application setup. With each deliverable, additional functionality was turned over until the overall objective was met.

 

Sometimes I wonder if I just should have taken up C# development – there turned out to not be very much left of the original InstallShield capability. BUT it was what the customer wanted, and overall I was very satisfied that I was able to accomplish this!

 

If you think over the solution – it’s basically an empty shell that should be able to be used by the customer for a long time, since there is no source embedded and the version number is included with the Zipped source on the website. Quite useful for a long time!


Shieldmaster

April 15, 2012

Running your application setup silently

Filed under: Reference Materials — shieldmaster @ 1:27 am

The advantage of using the InstallShield project type “Basic MSI” is that the ability to run silently is built-in!

When running silently, it implies that the dialogs are not being displayed – consequently there is no ability for the customer to customize the application configuration, only the default values defined within the application package would be used.

User provided command parameters

This means that when a customer wants to provide configuration data, there must be a solution. The solution is to provide a parameter for each MSI Property that is associated with a dialog data entry value. For example, since all of the dialog data fields are tied to MSI Properties  - an example is the MSI Property “INSTALLDIR” for the user modifiable installation directory, when you run silently, you would just provide the user selected data values using a format like this:

msiexec /i “c:\install\Setup.msi” /qb INSTALLDIR=”c:\Program Files\ISI Software

 

“c:\install\Setup.exe” /V” /qb INSTALLDIR=”c:\Program Files\ISI Software

 

Notes: 

  • the “/i” indicates an normal MSI installation,
  • the “/qb” indicates the user dialogs are suppressed, i.e., run with basic progress bar. If you did not include the /q parm, the dialogs would appear with the values supplied via the command parms – a good way to validate the fields before production!
  • the value for the MSI Property INSTALLDIR is the value supplied within quotes – due to embedded spaces.
  • /V” is the method to pass the command line parameters into the setup executable (not needed for .MSI files)

 

The only non-user friendly aspect to this method is that all of the MSI Properties would need to be on a continuous line, so a large amount of data fields would need to be entered similar to this:  (Line breaks accomplished by editor automatically)

msiexec /i “c:\install\Setup.msi” /qb INSTALLDIR=”c:\Program Files\ISI Software” ADVANCED=”TRUE” BRONZE=”FALSE” DISCRETE =”FALSE” PAPER_MACHINE=”YES” GOLD_FIBER=”YES” GOLD_RECOVERY=”NO” PAPER_BOARD=”TRUE”

 

Determining your data field command parameters

For example, if we evaluate this dialog screen within the InstallShield project:


 

We see six data entry fields to be specified on this dialog, with the highlighted data field shown is associated with the property “ISI_ADMINEMAIL”

(Note: all MSI properties used to be passed thru as parameters must be in all Capital letters!).

So all of the MSI Properties represented on this dialog screen are:

ISI_ADMINEMAIL

ISI_MAILHOST

ISI_MAILUSER

ISI_MAILPASSWORD

ISI_MAILPORT

ISI_MAILUSESSL

 

In order to pass the command parameters, we would use either of these formats, based on whether you were executing a .MSI or .EXE setup:

“C:\Install\RBSetup.msi” /qb

INSTALLDIR=”c:\Program Files\ISI Software” ISI_ADMINEMAIL=”admin@gmail.com”

ISI_MAILHOST=”smtp.gmail.com”

ISI_MAILUSER=”charles@gmail.com”

ISI_MAILPASSWORD=”mypassword”

ISI_MAILPORT=”465″

ISI_MAILUSESSL=”TRUE”

 

:

 

“C:\Install\RBSetup.exe” /V” /QB

INSTALLDIR=”c:\Program Files\ISI Software” ISI_ADMINEMAIL=”admin@gmail.com”

ISI_MAILHOST=”smtp.gmail.com”

ISI_MAILUSER=”charles@gmail.com”

ISI_MAILPASSWORD=”mypassword”

ISI_MAILPORT=”465″

ISI_MAILUSESSL=”TRUE”

 

Option #1: Use System Search to reading in command parameters via XML document

 

One option to read in the Command parameters is via an XML document that has been pre-staged in a specific area on the User’s desktop. In our example, we are pre-positioning a file “CFG.XML” onto the user’s Local App Data directory. The format of the CFG.XML document is:

<?xml version=”1.0″ encoding=”utf-8″?>

<QUINTREX>

<MSIPARMS>

<PREREQCHECK TYPE=”STRING”>Bypass</PREREQCHECK>

<INSTALLDIR

    TYPE=”STRING”>c:\ISI Software

</INSTALLDIR>

<ISI_ADMINEMAIL

TYPE=”STRING”>admin@gmail.com

</ISI_ADMINEMAIL>

<ISI_ MAILHOST

TYPE=”STRING”>smtp.gmail.com

</ISI_ MAILHOST>

<ISI_MAILUSER

TYPE=”STRING”>charles@gmail.com

</ISI_MAILUSER>

<ISI_MAILPASSWORD

TYPE=”STRING”>mypassword

</ISI_MAILPASSWORD>

<ISI_MAILPORT

TYPE=”STRING”>465

</ISI_MAILPORT>

<ISI_MAILUSESSL

TYPE=”STRING”>TRUE

</ISI_MAILUSESSL>

</MSIPARMS>

</QUINTREX>

 

On a Windows 7 machine this file will be pre-positioned in the following directory: “C:\Users\<$Charles$>\AppData\Local\Quintrex” – which is accessible via the InstallShield’s directory property “[LocalAppDataFolder]Quintrex”.

On a Windows XP, this directory would be: “C:\Documents and Settings\<$Charles$>\Application\Quintrex”

The sample InstallShield project will have a XML System Search that will access each installation command path and store into the correct MSI Property. Here is a sample dialog:

 

 

 

Notes:

  1. The directories that the CFG.XML can be stored on the desktop are limited, the AppSearch Standard Action happens before the Directory table is resolved, so you can only use the Windows Installer directories, such as:
  • TempFolder
  • WindowsVolume
  • Windows
  • LocalAppDataFolder

The System Search cannot use directories that you have created to install your application, such as [INSTALLDIR] because the Directories have not been defined when the AppSearch Standard Action has been run

 

  1. The value retrieved for the Installation directory cannot directly be used for the INSTALLDIR value. You must retrieve it, store as a MSI Property. Then you will need to create a Type 35 Custom Action “Set a Directory” that will then read in the MSI property and set [INSTALLDIR]. The modification of the System Search to set a property and use a Condition.

     

     

     

     

     

     

     

     

     

     

     

Option #2: Use InstallScript Custom Action to read in command parameters

 

Finally, you can create an InstallScript Custom Action that will read in a INI formatted file that exists in the same directory as the setup. This will allow you to have an easier solution that can be maintained more easier by future InstallShield developers.

 

Here is an example of a INI file:

[ISI Application]

DIR=C:\Program Files\ISI Software

ADMINEMAIL=admin@gmail.com

MAILHOST=smtp.gmail.com

MAILUSER=charles@gmail.com

MAILPASSWORD=mypassword

MAILPORT=465

MAILUSESSL=TRUE

 

Here is a sample InstallScript that will read the INI file and populate the correct MSI properties

 

//Setup the INI file parms

szSectionName = “ISI Application”;

szKeyName = “ADMINEMAIL”;

 

if (GetProfString (szIniFilePath, szSectionName,

            szKeyName, svAdminEmail) != 0) then

 

    // Log an error message if the string

    // could not be retrieved.

    ISI_WriteLogFile

        (“ISI–> ERROR – Could not get the ” +

        szKeyName + ” entry from the ” +

        szSectionName +

        ”section of the ISIAppSilent.ini.”);

else

    // Log the key and its current value.

    ISI_WriteLogFile

        (“ISI–> INFO – Admin Email value = ” +     

        svAdminEmail);

endif;

 

// Set the MSI Properties based on the info

// from the .ini file.

MsiSetProperty(ISMSI_HANDLE, “ISI_ADMINEMAIL”, svAdminEmail);

January 17, 2012

How to update an InstallShield v6.x CAB file

Filed under: Reference Materials — shieldmaster @ 12:46 am

Let’s step back in time – before Windows Installer, and setups had no special security issues. In this situation I had to modify an existing installation – essentially frozen with no ability to recreate the application setup. I needed to replace an executable with a newer version, but leave intact the ability for the setup to work properly.

The CAB file associated with InstallShield v6x does not use the same Zip/Archive technique as PKZip or Microsoft. Consequently you cannot modify a CAB file unless you use the special batch command line tools provided by InstallShield.

Tools

ISCab.exe – command line tool used to add/modify/delete files

ISCabVu.exe – GUI tool used to view contents of a CAB file

Process

 

  • Create a INI file listing of the CAB contents

We need to use the ISCab.exe in batch mode to create an INI file of the existing CAB file. Note we are only going to specify the DATA1.CAB – all other CAB files (Data2/Data3, ect) will be included in the INI file.

 

  • Modify the INI file listing to reflect the revised or new files

Clone the output INI file from Step #1 and modify it. Look for all occurrences of the file we need to replace (in this sample it is “Archiver.exe”. To add or replace a file, we will use the same convention. Identify the File Group and signify which file is to be added. Here is a sample of Archiver.exe which was found in only one location.

 

[ISCAB Info]

Product=ISCAB

Version=2.0

 

[[Archiver]NS_NSR_NPL_1___<TARGET_DIR_ARCHIVER>_1]

File1=”Archiver.exe”

 

 

  • Update the CAB contents

We need to use the ISCab.exe in batch mode to read the modified INI file and point to the CAB file we want to update.. Note the tool is relative stupid – we need to store the new/replacement files in the same directory as the ISCab.exe. The CAB will be updated in place – so copy it elsewhere if needed.

 

  • Verify the CAB has been successfully changed

There are two methods we need to verify that the change was successful”

  • Run step #1 again and specify a different output INI name. Use this to compare against the original INI – very that all of the other files are still within the CAB. The match should be perfect if you are replacing a file.
  • Use the GUI CAB viewer “ISCabVu.exe” (in Expert Mode) to open up the DATA1.CAB that was modified. Using the File Group, look for the file with an altered TimeStamp and size. Sometimes the Version number does not get reflected. You can Extract the File to compare the file more closely.

 

Sample Batch Command file

The contents are from the file “AlterCab.bat” in which I have demonstrated how to handle CAB modification with the same revised executable “Archiver.exe”

REM ************************************************

REM ** Replacing Files in INSTALLSHIELD v6.x CAB

REM ** These are notes on how to replace individual

REM ** files within an InstallShield v6.x CAB file

REM ** Remember, only deal with DATA1.CAB – other cab

REM ** files (Data2, Data3) are handled when you

REM ** change DATA1.cab

REM ************************************************

 

REM ************************************************

REM ** First need to obtain INI listing of CAB

REM ************************************************

REM “c:\Archiver781_HotFix\iscab.exe” “c:\Archiver781_HotFix\Setups\DVD2 – Recorder\data1.cab” -i”Recorder_Witness_datacab.ini” -lx

 

REM ************************************************

REM ** Clone INI file “Datacab.ini” and only

REM ** leave in the entry for files to be replaced

REM ** The new files should be in the same directory

REM ** as the ISCAB.exe file..

REM ************************************************

REM “c:\Archiver781_HotFix\iscab.exe” “c:\Archiver781_HotFix\Setups\DVD2 – Recorder\data1.cab” -i”Revised_Recorder_Witness_datacab.ini” -a

 

REM ************************************************

REM ** To ensure correct updating, obtain another

REM ** INI listing of CAB after replacement and

REM ** use Text Compare tool to verify all files

REM ************************************************

REM “c:\Archiver781_HotFix\iscab.exe” “c:\Archiver781_HotFix\Setups\DVD2 – Recorder\data1.cab” -i”AfterRevised_Recorder_Witness_datacab.ini” -lx

 

REM ************************************************

REM ** To ensure correct updating of the File Size

REM ** and timestamp, you need to use ISCabVu.exe

REM ** (in Expert Mode)to view the Data1.cab

REM ** contents to verify the files changed

REM ************************************************

 

 

 


 

December 1, 2011

Converting a MSI to an InstallShield Basic Project

Filed under: Reference Materials — shieldmaster @ 11:07 pm

Recently I had two separate situations that arose in which I had a MSI and needed to convert each to an InstallShield Project. One was a project that was originally a WISE installation, and the other was a InstallShield MultiPlatform package. In both situations I had access to a MSI Package, and chose to convert it to an InstallShield package.

Apparently the built-in Conversion feature is not as well known as I thought – and it’s been around since v10.5, so it seems to be a good candidate for a BLOG entry, so here it goes!

First, you need to open the InstallShield project and then select OPEN from the File Dropdown menu.

Notice that there are three data entry fields ‘File Name:’; ‘Files of Type:’; and ‘Open as:’ entries. Notice that the ‘Open as:’ entry has two choices, Auto and Wizard.

Choose Wizard and open the MSI Package.

You will receive the next dialog which allows you to choose to open the MSI for Direct Editing or Convert the MSI/MSM to an InstallShield project. Now if you did not realize it, when you open a MSI you can change quite a few items, such as System Search Entries, string values, etc. This has been helpful in many situations, but I don’t recommend it due to a lack of auditing capabilities. IT has been a great solution to validate entries, such as to verify whether files are included in the MSI.

Let’s continue – select the Convert option:

The next dialog screen will be prefilled with generic information – as shown here:


You should name it uniquely and set the disk location for the new project to be stored – as I have done:

Selecting Finish will most likely result in a verification dialog, as shown here:

 

The InstallShield will complete the conversion and it creates a Basic MSI Project, ready for you to finish dressing up:

Depending on what type of Project you started with will depend on the effort to finish the project. For example a Wise created MSI will end up creating a project with non-standard Dialog names and Custom Actions.

Just start at the top and work thru the project, cleaning up as you go:

The nice aspect is the files are extracted from the Binary table and placed in an sub-directory “Files” under the new ISM Project. But it’s much easier than rebuilding an old project from scratch!

 

Hope this helps!

ShieldMaster

 

 

October 23, 2011

Creating additional Destination Folder dialog

Filed under: Reference Materials — shieldmaster @ 12:39 am

For some projects I occasionally find that it is necessary to prompt the user for a destination location in addition to the default INSTALLDIR.

 

For example, what if I want to confirm the Java JRE directory that I found installed is the one the user wants to associate with their applications (quite possible they certified an older JRE version – not the most current). The only reference I found on how to do this was for InstallScript MSI project, but I am working solely in Basic MSI projects.

In order to provide the end user with the same Browse to a folder dialog used in a default installation, the following steps can be followed for use in a Basic MSI InstallShield project:

  1. Create a new Directory that will be used to hold the JRE directory found – and will be displayed in the Browse directory. Since I have never, (repeat never) mastered the Directory Table (using Direct Editor), here is how I approach it. I create a new component (delete if afterwards) and select the dropdown to create a new directory entry.


     

    Now a directory browse dialog is presented:


    Using the INSERT key, create a new directory “JRE Path”


    Now rename the Directory Identifier to be all CAPS, such as “JRE_PATH” – this will be the MSI Property that we will use as our Directory. Now we need to create some dialog screens to display and allow the user to browse to a new directory.

     

    Go to the Dialogs section, and export a dialog that we will need to “repurpose” for our needs. For our example, we are going to export the dialog “AdminChangeFolder” by selecting the dialog and right-clicking. Export the dialog ISD to a folder you can retrieve it from later.


     

    Now rename the original “AdminChangeFolder” to “AdminChangeFolder_ORIG” to preserve it. I do this because even though I tried to rename the dialog during export, it always appears with the same name – overwriting the original.

     

    Now import back the “AdminChangeFolder” dialog by right-clicking on the “All Dialogs” title. The repository appears:


    Browse to the saved dialog, and select it – it will appear in the repository as shown here:


     

    Select OK and the dialog will appear back in your listing of dialogs.


    WARNING: if this popup dialog appears:


    You must select the red conflict item and select “Overwrite”, like this:


    What is happening is that the internal bitmaps are being exported as “NewBinary1″ files and stored in the same directory as the project ISM file (Hint: look for a file “NewBinary1″ and copy as “NewBinary.jpg” and you will see the banner bitmap). Here is the result you might find – the banner bitmap points to a file “NewBinary1″ – not to the original file location:


     

    The solution is to replace the “File Name” with the original value, such as: <ISProductFolder>\Redist\Language Independent\OS Independent\IsDialogBanner.ibd (With InstallShield v10.5 it will ripple this NewBinary1 reference to ALL of your dialogs, so you may have to create a new InstallShield project to determine the original file values. If this happens, then you either must go to each dialog and correct it, or you can open the Direct Editor, go to the “Binary” table and alter the displayed value for NewBinary1,


     

    Now rename “AdminChangeFolder_ORIG” to “JavaChangeFolder”.

     

    We are going to leave this dialog and create a new dialog “JavaDirectory” that will display the Java JRE directory along with a “Change” button.

    Here is a sample of one I created:


     

    Essentially it contains a text box, a PathEdit box and a Change pushbutton. The property associated with the PathEdit box is “JRE_PATH”.

    We want the user to see a directory browse button when they hit the ‘Change’ pushbutton, so we need to switch to the ‘Behavior’ to edit the JavaDirectory dialog behavior. On the Change pushbutton (titled ‘PushButton1′ add an Event “SpawnDialog” with the argument “JavaChangeFolder” and a condition of 1 – as shown here:


     

    Now change to the dialog “JavaChangeFolder” and in the dialog view, change ALL of the property values from “TARGETDIR” to the property “JRE_PATH” as shown:


     

    Then you will need to switch to the ‘Behavior’ view and alter the event OK and change the argument from “TARGETDIR” to “JRE_PATH”


    FINALLY – go to the project Property Manager section and delete the property “JRE_PATH” – if you don’t the path will be incorrectly set as “0″ and your project will hang during the starting and fail with error 1603!! For some reason, this value will keep appearing during your development, so you may need to double check it a couple of times.


    Now, to prime the directory “JRE_PATH” you can setup an Custom Action to grab the environment variable JAVA_HOME and prime the directory with this value, or you can execute a Custom Action InstallScript that will evaluate the machine and set this MSI Property (MsiSetProperty xxx) to a directory value. Here is a sample display of the dialogs when running:


     


     


     

     

    Hope this helps!

    ShieldMaster

     

     

     

     

     

     


 

June 27, 2011

InstallShield Upgrade Strategy

Filed under: Reference Materials — shieldmaster @ 9:42 pm

Quite a concern with customers is what strategy should they follow when delivering future updates to their application. The confusion as to what to delivery (Small Updates, Minor Updates, Major Upgrades, Patches) leaves the customer paralyzed with indecision. Couple that with having a part-time InstallShield developer (or consultant), and you will need to evaluate a strategy that blends reliability with ease in creating and QA testing an upgrade.

In this post, I would like to outline a roadmap for your Upgrade Strategy, giving both Pros and Cons as well as realistic guidance that experience has provided.

Packaging Options

First, let’s discuss the various packaging options that are available to you.

  • Each upgrade can be packaged for delivery as a full MSI installation which can offer existing clients a method to deliver just the updated files, or a full replacement of the original package. The advantage of creating a full MSI installation is that it can be delivered to new customers and they will be able to install and configure as easily as the original installation.
  • An upgrade can be packaged as a Windows Installer patch file that offers existing customers a smaller footprint, and will apply binary file differences that will upgrade a file from the previous version to the newer version. The effort to create this is relatively simple, but must be tested as much as a full upgrade package. In addition it can only deliver updates to existing customers after a full installation – a new customer cannot install a Patch package and have a working program.

Windows Installer GUID Codes

The GUID Codes associated with each InstallShield package play a major role in how Windows Installer determines whether the package being installed is considered a new installation, or an update that is being handled as a Major or Minor upgrade.

  • Package Code – must change for each build. Pretty much ignored for your requirements.
  • Product Version – MSI Property – Only 1st three fields used by Windows Installer for version comparisons (Build # ignored)
  • Product Code– MSI Property – GUID of product. If two packages with same name have different ProductCode’s, MSI treats both packages as different!
  • Upgrade Code – MSI Property holds GUID of family of products – used for patching purposes. Essentially never change for life of application!

 

Here is a matrix that graphically displays when each GUID should be changed:

Now, let’s discuss the various vehicles that InstallShield provides to deliver updates to your customer.

Small Update

This type of update is characterized by just some simple product changes – so small in scope that you don’t alter the Product Version number. Some requirements you must adhere to when preparing the installation to be delivered as a Small Update:

  • Can add a new component to an existing feature
  • Can add a new component to a new feature
  • Can add new sub-feature with new components
  • Cannot change MSI Package name
  • Cannot move or delete a feature
  • Cannot move/delete component
  • Cannot change Component GUID
  • Cannot change the Key file of a component

In practice, delivering a new full MSI Package without changing the Product Version ensures you will have no means to track which customer has received this package. Granted the Package Code will always be regenerated, but that is not easy for the customer to determine. Realistically this might be a method to rebuild the package while it’s in the QA stages – I just don’t see a practical use for delivery to customers.

Minor Upgrade

This is the typical solution that most developers deliver to their customer base. Characterized by a full rebuild of the package with the Product Version changing (goes from version 2.1.3.xx to 2.2.0.xx), it most often will contain newly compiled binary files that resolve a customer reported defect. When the new customer receives this package, a full installation will occur with all of the User Dialogs presented with version 2.2.0.xx installed.

When an existing customer (v2.1.3.xx) receives this package, they will see a small dialog asking “Do you want to upgrade the application? Y/N) – and then they would just see the progress bar as the updated binaries are applied. Note that no User Dialogs will appear, the same destination drive/directory are maintained, plus any features selected within original installation are preserved with no ability to change.

A patch can be created that provides a method to deliver the Minor Update changes in a smaller footprint versus delivering a full MSI package.

Note that it is critical that you have followed “Best Practices” when creating the components – and key files are set for all versioned binary files. If you keep all of the non-versioned files in a component, it would be recommended that you select a versioned file as the Key file of the component.

Some requirements you must adhere to when preparing the installation to be delivered as a Minor Upgrade:

  • Can add a new component to an existing feature
  • Can add a new component to a new feature
  • Can add new sub-feature with new components
  • Cannot change MSI Package name
  • Cannot move or delete a feature
  • Cannot move/delete component
  • Cannot change Component GUID
  • Cannot change the Key file of a component

 

Major Upgrade

This is the method by which developers introduce a significant change to the application, which would require the user to completely uninstall the original application and then the new application is installed. With the authoring of a Major Upgrade entry, this process is accomplished seamlessly when the new installation is executed by an existing customer.

Most importantly, you decide when a new release qualifies as a Major Upgrade, for example version 2.2.0.xx to 3.0.0.xx might qualify, but you may want to have 2.2.0.xx to 2.3.0.xx be handled as a Major Upgrade, especially if a new feature is introduced and you want the customer to be able to choose it during installation.

Some requirements you must adhere to when preparing the installation to be delivered as a Major Upgrade:

  • Can add a new component to an existing feature
  • Can add a new component to a new feature
  • Can add new sub-feature with new components
  • Can change MSI Package name
  • Can move or delete a feature
  • Can move/delete component
  • Can change Component GUID
  • Can change the Key file of a component

As you can see, it’s pretty flexible since the original installation is being removed you have free rein in doing anything you want with Features and Components.

You can specify the behavior of how the Major Update is applied, you have the following choices:

  1. Completely remove the original application, registry entries, and files, then install the new application. Note that none of the original files are preserved or backed up during the process.
  2. Overwrite the original application, then weed out obsolete files as necessary.

Realistically, I always choose option #1, because it offers the customer the flexibility of choosing a different drive and destination folder.

 

Considerations

Here are the Pros and Cons that I am aware of with each upgrade approach ( I am ignoring Small Updates completely):

Minor Update

Pros

  • Works consistently when a versioned binary files has newer version number (matches InstallShield product version).
  • Allows you to create small “Patches/Updates” from this new MSI package.
  • Process is typically “built” into an installation, requiring overt entries to the Upgrade table. Accomplished simply by altering the Version number.
  • Can use Patch process to deliver changes in a smaller footprint

Cons

  • No user dialogs presented, so customer has to live with the original drive and directory.
  • If package delivers a registry entry, which is modified by InstallScript Custom Actions – or during the user dialogs, this may not be done during Minor Update, consequently you might have empty variables in the registry after the update. Modifying the REINSTALLMODE properties can prevent the registry from being rewritten. Creating a new Custom Action that runs with Condition=Installed will also work towards resolving this issue.
  • Application files that are configured by the customer during application execution should be preserved – but you have to watch to ensure they are not overwritten by the template within the CAB files. Sometimes a InstallScript Custom Action that preserves the user configuration files before the Upgrade process and then another to restore it after the Upgrade process is necessary.
  • Delivering new non-versioned files (XML, INI, CFG, etc) may not be delivered consistently (Refer to link regarding File Versioning rules). Only alternative to ensure new non-versioned files are consistently delivered are to modify the REINSTALLMODE properties to force all files to be delivered (overkill at best), or create an InstallScript Custom Action before the update step to delete the critical non-versioned files to ensure that they are always delivered.
  • Cannot make significant changes to organization of the package (for example, restructure the Features)

 

 

Major Update

Pros

  • Allows unlimited reorganization of Features and Components – essentially a vastly different package than the original one
  • Allows you the ability to wipe out troublesome packages that were originally delivered that are not easy to properly apply updates to.
  • Full user dialogs presented, allows existing customers to choose different Features, specify a different drive or destination folder
  • Removes existing product silently at beginning
  • To denote a Major Update, you must:
    • Regenerate the Product Code GUID
    • Change the Version Number
    • Author a Major Upgrade entry in the Updates table

     

    Notes:

  1. to run a Custom Action during uninstall of Original Product, use condition “Remove=”ALL” not “UPGRADINGPRODUCTCODE”
  2. To run a Custom Action during upgrade, use condition “UPGRADINGPRODUCTCODE

Cons

  • Must be mindful that the uninstall may not completely remove all or the original installation, which could pose problems for the new installatino

 

Recommendations

These recommendations are based on years of providing consulting services to small development shops that don’t have a Full Time Dedicated InstallShield Developer. Consequently, your upgrade strategy should focus on creating Upgrade packages that are:

  • easy for the customer to apply and relatively Bulletproof so that valuable hours are not wasted dealing with customer upgrade issues.
  • Able to consistently build with repeatable results
  • QA can handle the iterative testing to ensure files are delivered correctly in all scenarios

 

  1. Small Update – don’t even think of them in a customer environment!
  2. Realize that creating Minor Upgrades will require extensive InstallShield package testing and particular attention to the treatment of non-versioned files. Don’t create a Minor Update unless you are going to devote the testing to ensure all files correctly updated.
  3. Patches require extensive testing, far beyond their worth in the field – which is mainly a smaller download size. I would just create Minor Updates, test correctly and release this to both existing and new customers.
  4. If you have no user configured data to be concerned with, then I recommend that you consider every release a Major Upgrade. It removes the requirement to ensure non-versioned files are correctly, and you are sure everyone is correctly updated at the end. If you don’t have a dedicated InstallShield developer, or limited QA testing time this is the way to go.

    As far as the treatment of user configuration data/files goes, if you put in the System Search and/or InstallScript Custom Actions, and they are proven to work correctly – then releasing a Major Upgrade becomes quite straightforward and easy to manage for future releases.

     

Hope this helps!

ShieldMaster

March 17, 2011

Preselecting Features within an InstallShield Basic MSI Project

Filed under: Reference Materials — shieldmaster @ 9:44 pm

My previous blog discussed a method using InstallScript to determine whether a Feature had been selected by the customer in the Custom Setup dialog .

This blog posting will be about preselecting Features, the methodology and the issues involved.

 

In my sample Custom Setup Dialog, I have three major Features as shown in this Custom Setup Dialog:

 

I have some scripting to do, checking various components installed on the workstation. Now suppose that if:

  • .NET Framework 2.0 is not installed, deselect Feature “.NET Applications” before the dialog Custom Setup is presented
  • .NET Framework 2.0 was found installed, have the Feature “.NET Applications” preselected before the dialog Custom Setup is presented

 

I abbreviated the script logic to the critical script that sets a MSI Property “DOTNET_FEATURE” to a value of “FALSE” to test the logic:

 

NOTE: This script function MUST be sequenced before the standard action “CostFinalize”!

Now we need to set a Condition on the Feature “.NET Applications” that will make the feature be preselected or deselected.

Navigate to the Feature panel and create a Feature condition:

 

This Condition will alter the InstallLevel to be 200 if the MSI Property “DOTNET_FEATURE”=”FALSE”.

The InstallLevel, by default is set to 100, so any Feature or component that has a value from 1 to 100 will install. If you reset the level for a Feature (or sub-feature) to any number >100, the feature will be displayed Unselected.

Here are the results:

 

WARNING: if you set the InstallLevel to a value of 0, then the entry for Client Server will disappear from viewing in the Custom Setup Dialog.

If might be a nice option, but then the customer can never select the feature!

Hope this helps!

SHIELDMASTER

 

 

Older Posts »

Theme: Silver is the New Black. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 29 other followers