patrick
Posts: 4
Joined: Thu Mar 10, 2005 8:59 pm

Upgrade/uninstall question

My program makes use of two important user settings files. I am currently in the process of creating the first upgrade for the software, and I am running into a problem. During the upgrade process, the un-installation deletes these files, which are then replaced with the default versions from the installation. It is important that the user-modified settings files are neither deleted nor overwritten during the upgrade process.

This seems like it would be a relatively common problem/requirement. I realize I can probably use a custom action, but I have no idea how to use custom actions. If someone could point me to a sample custom action that does something similar to this, or has any other ideas, please let me know.

Patrick
travis001
Posts: 10
Joined: Sat Dec 03, 2005 12:23 am

I was able to handle this by writing an application that performs this exact operation. Then I call my custom app as a custom action.

The other way (although not recommended) would be to flag those files as (do not remove), then also flag them as never overwrite. that way the would not be removed by the uninstall, and the would not be overwritten by the new install. This is not recommended and besides, you are already past that point.
Ionut
Posts: 605
Joined: Tue Nov 22, 2005 11:29 am
Contact: Website

Hi Patrick,

You are right, one solution would be to use Custom Actions: one which performs the backup of the user settings files and another which restores them at the end of the installation.

I shall describe the method first. At the beginning of the setup process, you have to create a "Property Set With Formatted" Custom Action for each file or folder you do not want overwritten. The properties created by each of these Custom Actions will be used by the Backup script (see below) to copy those files and/or folders to a temporary location. At the end of the setup routine, those files/folders are copied back to their original location, thereby overwriting the new ones.

A Custom Action that creates a backup for a file and a folder is given below. This VBScript may be customized to your needs:

Code: Select all

Function Backup
Dim fso, tempfolder, tfolder, tname, f
Dim strkeepfile, strkeepfolder 
	
Const TemporaryFolder = 2
	
Set fso = CreateObject("Scripting.FileSystemObject")
	
Set tempfolder = fso.GetSpecialFolder(TemporaryFolder)
	
tname = fso.GetTempName
tfolder = tempfolder & "\" & tname & "\"
	
' Create a temporary folder where the files/folders will be copied
Set f = fso.CreateFolder(tfolder)
	
' MsgBox("Temporary folder created: " & tfolder)
	
' This property will be used to restore the files afterwards 
' (it has a trailing "\")
Session.Property("tfolder") = CStr(tfolder)
	
' The files and folders to backup
''' TODO: Replace these properties with the ones you set for each
'''       "Property Set With Formatted" custom action
strkeepfile   = Session.Property("KEEPFILE")
strkeepfolder = Session.Property("KEEPFOLDER")
	
''' TODO: Add additional variables for additional files/folders
''' to backup
	
' Copy the file to temp folder
If Len(strkeepfile) > 0 Then
	fso.CopyFile strkeepfile, tfolder

	' MsgBox(strkeepfile & " copied to " & tfolder)
End If
	
' Copy the folder to temp folder
If Len(strkeepfolder) > 0 Then
	' Ignore the trailing "\"
	fso.CopyFolder Left(strkeepfolder,Len(strkeepfolder)-1),tfolder

	' MsgBox(strkeepfolder & " copied to " & tfolder)
End If

''' TODO: Copy additional files/folders to the temp folder

End Function
A Custom Action that restores the file and the folder copied by the above script is given below. This can also be customized:

Code: Select all

Function Restore
Dim fso, tfolder, tname
Dim origfile, origfolder 
Dim pos, name
Dim tempfile, tempfolder, destfolder

Set fso = CreateObject("Scripting.FileSystemObject")
	
' Files and folders will be restored from this location
tfolder = CStr(Session.Property("tfolder"))
	
' The original file and folder paths
''' TODO: Replace these properties with the ones you set for each
'''       "Property Set With Formatted" custom action
origfile   = Session.Property("KEEPFILE")
origfolder = Session.Property("KEEPFOLDER")
	
''' TODO: Add additional variables for additional files/folders to restore
	
' Restore the original file
If Len(origfile) > 0 Then
	' extract the name of the file
	pos = InStrRev(origfile, "\", Len(origfile))
	name = Mid(origfile, pos+1, Len(origfile) - pos)
		
	' the full path of the saved temp file
	tempfile = tfolder & name
		
	' This method will fail if the destination file has the 
	' read-only attribute set
	fso.CopyFile tempfile, origfile, True

	' MsgBox(tempfile & " copied to " & origfile)
End If
	
' Restore the original folder
If Len(origfolder) > 0 Then
	' extract the name of the folder, ignoring the trailing "\"
	pos = InStrRev(origfolder, "\", Len(origfolder) - 1)
	name = Mid(origfolder, pos+1, Len(origfolder) - pos - 1)
	
	' the full path of the saved temp folder (without trailing "\")
	tempfolder = tfolder & name
		
	' the destination where the temp folder will be copied 
	' (the original location)
	destfolder = Left(origfolder, Len(origfolder) - Len(name) - 1)
		
	fso.CopyFolder tempfolder, destfolder, True

	' MsgBox(tempfolder & " copied to " & destfolder)
End If
	
''' TODO: Restore additional files/folders if necessary
	
' Delete the temporary folder
fso.DeleteFolder(Left(tfolder, Len(tfolder) - 1))

End Function

These are the steps you should follow:

1. Create a new text file (backup_restore.vbs) and copy the two functions above into it.

2. Open your project in Advanced Installer and switch to the Custom Actions page.

3. Use the "Show Standard Action" toolbar button and make sure these 2 items are visible in the tree control: "Before Initialization -> CostFinalize" and "Before Finalization -> InstallFinalize".

4. Right-click the CostFinalize item and add a "New Custom Action -> Property Set With Formatted". Repeat this step for each file and/or folder you do not want overwritten.

5. For each of these Custom Actions do the following:
- Enter a name in the "Property Name" field. Note that this property will be used subsequently in the Backup and Restore scripts. I have used KEEPFILE and KEEPFOLDER to store the path of a file and a folder that will be saved and restored.
- Use the "Edit" button at the right of the "Formatted Text" field and then the "File" or "Folder" buttons (in the Edit Custom Actions Parameters dialog) to select a file or a folder from your package.

6. Right click the CostFinalize item and select "New Attached Custom Action", then select the VBS file you have created in step 1. In the Function Name field, type "Backup" (without quotes). Please note that the Backup Custom Action must come after all the Property Set With Formatted Custom Actions.

7. Right click the InstallFinalize item and select "New Attached Custom Action", then select the VBS file you have created in step 1. In the Function Name field, type "Restore" (without quotes).

8. Modify the Backup and Restore functions according to your needs.

[edit Jan 3, 2006]

9. The backup and restore scripts should not run when the application is removed, repaired or the user modifies the installed features. In order to do this, set the Execution Condition for all Custom Actions to:

Code: Select all

(Not Installed)

Hope this helps.

Regards,
Denis
Last edited by Ionut on Tue Jan 03, 2006 9:37 am, edited 1 time in total.
Denis Toma
Advanced Installer Team
http://www.advancedinstaller.com/
lslarry86
Posts: 1
Joined: Fri Dec 30, 2005 2:07 am
Location: RTP NC
Contact: Website

wildcards in filespec for backup/restore

Hi,

The above steps seem to work for me. Now I want to backup and restore all my .JOB files using one command, both because there are several of them in my distribution and because my end users create their own JOB's.

The Scripting.FileSystemObject.Copy method used by the Backup and Restore VBS functions accepts wildcards (see http://www.rgagnon.com/wshdetails/wsh-0006.html) but the Advanced Installer will not let me enter a wildcard:

[#*.job]Formatted text

creates error "Exception - Invalid MSI identifier string [*.job].

Is there a way to pass a wildcard to the VBS Backup and Restore functions?

Thanks,
Larry
Mike
Posts: 292
Joined: Wed Jun 01, 2005 10:50 am
Location: Craiova, Romania
Contact: Website

Hi Larry,

I'm afraid that you cannot pass a wild card as a file name in Advanced Installer. You cannot specify multiple identifiers using this method. This is the way Windows Installer works.

To achieve what you want you have two possibilities:

- place all your files in a folder and use the custom action to back it up.

- place a custom action to back up every folder that contains JOB files.

Hope this helps.

Regards,
Mihai
Mihai Bobaru
Advanced Installer Team
http://www.advancedinstaller.com
Lucky.
Posts: 7
Joined: Tue Nov 01, 2005 10:46 pm

Hi,

Thank you, this is very helpful, however I am running into another problem.

The upgrade works very well using this method, and preserves the files that I want to keep.

However when I uninstall the product, it appears to attempt to run the scripts again (make a backup and restore when uninstalling), which causes failure the following way:

1. It creates a backup of my files that I want to keep.

2. It uninstalls the product

3. It tries to restore the files I wanted to keep to the program's directory (which is now deleted). Failure occurs.

This failure is quite catastrophic, leaving the appearance of my product installed on the user's machine (it appears in add/remove programs), but it really is not. When uninstalling, I get the following error message

This action is only valid for products that are currently installed
Is there a way to prevent the scripts from running during uninstallation?
Or perhaps I did something wrong?

Best Regards,

-Eric
Ionut
Posts: 605
Joined: Tue Nov 22, 2005 11:29 am
Contact: Website

Hi Eric,

You are right, it seems that I forgot to mention this aspect in my previous post. The backup and restore scripts should not run when the application is removed, repaired or the user modifies the installed features. In order to do this, set the Execution Condition for all Custom Actions to:

Code: Select all

(Not Installed)
Regards,
Denis
Denis Toma
Advanced Installer Team
http://www.advancedinstaller.com/

Return to “Common Problems”