Answer
You could use two custom actions:
- one performing the backup of the user settings files
- one restoring them at the end of the installation
The Backup custom action will be executed before the old version of the product is uninstalled. The Restore custom action will run after the files from the new package have been copied.
A VBScript implementation for such custom actions (together with sample projects) is available here. The code for both custom actions and the required helper functions can be found in the "backup_restore.vbs" file inside the archive.
In what follows it is described the behaviour of the Backup/Restore scripts. Additionally, instructions on how to integrate them in your own projects are provided below.
Backup script
When executed as Immediate, the input for this custom action is the BackupList property - a list of file/folder paths separated by the pipe "|" character. The script will create a temporary directory and copy all the files/folders specified in the BackupList Property into that temporary directory. After performing this operation, the script will create a Property (tfolder) which will contain the full path of the temporary directory. This property will be used subsequently by the Restore script.
The Backup script can also be executed as a Deferred custom action, in which case you have the possibility to specify the backup folder yourself. In this case, data is passed to it via the “Action Data” field, in the following format:
[BackupFolder]<>[BackupList]
The custom action will attempt to create the complete folder tree designated by the BackupFolder property, if it does not exist, instead of creating a temporary directory in the user's TempFolder. When specifying the backup folder through the “Action Data” field, make sure you set the Backup custom action as Deferred with no impersonation, otherwise it might fail in Vista or above when attempting to write to the designated backup folder.
Restore script
This custom action receives the values of 3 properties through the CustomActionData property (since it must run as Deferred in system context), in the following format:
[tfolder]|[BackupList]<>[RestoreLocationList]
- tfolder - the property set by the Backup script which designates the temporary directory where the backup files/folders reside
- BackupList - the original location of the files/folders which reside in the temporary directory (tfolder) and which must be restored. This is the same property used as input for the Backup script.
- RestoreLocationList - an optional property which, if present, will designate for each file/folder the new directory where that respective file/folder will be restored to. The value of this property is a list of folder paths (which should exist at install time) separated by the pipe "|" character. It is possible to specify selectively the new location for each file/folder - if a new location is not specified for a particular file/folder it will be restored to its original location (as it appears in the BackupList property). The order in which the file/folder paths appear in the BackupList property will determine the order in which their new locations will be specified in the RestoreLocationList property.
The RestoreLocationList property is useful when several
files/folders need to be restored to a directory that can be changed
by the user at install time and thus may be different across distinct
versions of the same product (such as the Application Folder).
The Restore script will attempt to copy a file/folder to a new location if one has been specified for that particular file/folder (in the RestoreLocationList Property) and the specified destination folder exists at install time. Otherwise, the file/folder will be restored to its original location (the complete folder tree is created if it does not exist anymore).
After finishing its execution, the Restore script will delete the temporary folder created by the Backup script.
How to use the scripts in your project
Both scripts are generic and modifying their code is not required. You only need to define the BackupList and optionally the RestoreLocationList Properties, in addition to adding both scripts as custom actions. Follow the steps presented below:
1. Add a new "Set installer property" custom action under "Paths Resolution" action group , specifying "BackupList" (without quotes) in the “Property Name” field. The “Formatted Text” field will be set to a pipe-separated list of file/folder paths representing the files/folders that need to be backed-up.
Keep in mind that this field is Formatted and thus you can enter references to files/folders from the package or property values (these properties may have been set by a search etc). See the sample project "p2.aip" and the explanation below as an example.
2. Add a new "Attached Custom Action" after "Paths Resolution" and select the "backup_restore.vbs" file from the disk. Make sure that this custom action comes after the "Set installer property" custom action defined above.
Use the following settings for this custom action:
a) Function Name: Backup
b) Execution Properties: “Synchronous execution, check return code”
c) Execution Options: “Immediate execution”
d) Execution Condition: (Not Installed)
3. Add a new "Set installer property" custom action under "Add Resources" specifying "RestoreLocationList" in the "Property Name" field. This step is optional if you do not need to specify a new location for (some of) the files/folders that will be restored.
The “Formatted Text” field will the set to a pipe-separated list of folder paths, representing the new directories where each file/folder (specified in the BackupList Property) will be restored to. See the sample project "p2.aip" as an example.
4. Add a new "Attached Custom Action" under "Add Resources" and select the "backup_restore.vbs" file from the disk. Make sure that this custom action comes after the "Set installer property" custom action defined in step 4, above.
Use the following settings for this custom action:
a) Function Name: Restore
b) Action Data: [tfolder]|[BackupList]<>[RestoreLocationList]
c) Execution Properties: “Synchronous execution, check return code”
d) Execution Options: “Deferred with no impersonation”
e) Execution Condition: (Not Installed)
It is very important that the Restore custom action is set as
“Deferred with no impersonation” instead of
“Deferred” because it needs to run in system
context, not using the credentials of the user installing the package.
This is a requirement for the custom action in order to work correctly
in Windows Vista or above.
Sample projects
In order to illustrate the usage of the Backup/Restore scripts, two sample projects are provided inside the archive, representing two consecutive versions of a package. The dummy files required to build these projects are also included.
The first project ("p1.aip") contains 2 files and 2 folders that need to be preserved when upgrading to version 2.0 ("p2.aip"). These are "file_to_backup.txt" and "folder_to_backup" (located in the Application Folder) and "file_to_backup2.txt" and "folder_to_backup2" (located under "Common Application Data\Your Application") - see the Files and Folders page from "p1.aip".
It can be noticed that "file_to_backup.txt" and "folder_to_backup" reside in a directory that can be changed by the user at install time (the Application Folder), while "file_to_backup2.txt" and "folder_to_backup2" reside in a fixed location (the same for both "p1.aip" and "p2.aip").
For this reason, the full paths of "file_to_backup.txt" and "folder_to_backup" are written in the registry under the key: HKLM\[Manufacturer]\[ProductName]\Backup. See the Registry page for "p1.aip".
In the Search page for "p2.aip" there are 2 registry searches defined (FILE_TO_BACKUP and FOLDER_TO_BACKUP) in order to locate the paths of "file_to_backup.txt" and "folder_to_backup" installed by the first package. It would also be possible to use file searches instead, but these are less reliable because the wrong file/folder may be found.
In the Custom Actions page for "p2.aip", the BackupList property is set to:
[FILE_TO_BACKUP]|[#file_to_backup2.txt]|[FOLDER_TO_BACKUP]|[folder_to_backup2_DIR]
It means that the search properties (FILE_TO_BACKUP and FOLDER_TO_BACKUP) are used for the file/folder whose paths may vary between distinct versions of the package ("file_to_backup.txt" and "folder_to_backup" which reside in the Application Directory).
For the other file and folder (located under "Common Application Data\Your Application"), the corresponding file/directory references are used (which will be resolved to their full paths at install time).
The RestoreLocationList property is set to:
[APPDIR]||[APPDIR]
which means that a new directory is specified only for the first and third elements in the BackupList property (in this case, for those files/folders whose full paths are given by the values of the properties FILE_TO_BACKUP and FOLDER_TO_BACKUP, namely "file_to_backup.txt" and "folder_to_backup"). Their new location is the current Application Folder, which might be different from the original one where the old version of the package was installed.
Both scripts write useful information in the Windows Installer log file which
can be used for troubleshooting purposes. After creating a verbose
log, search for "[Backup]" or "[Restore]" (without quotes) in order to
locate this information.