Anda di halaman 1dari 5

Using MSI Automation to Modify a Developer 7 Project

Robert M. Dickau Senior Technical Trainer InstallShield Software Corp. http://www.installshield.com/training

Abstract
The InstallShield Developer 7 Automation interface exposes most of the contents of a project file, including properties, Summary Information Stream settings, features, components, build configuration information, sequences, and more. This article demonstrates how to use the MSI Automation interface to modify project tables that are not exposed by the Developer Automation interface; in particular, the Disk1Files table that represents files in the Disk1 file list in the Setup Files view.

The Problem
The Disk1 area of the Setup Files view allows you to add files to the project that will be left uncompressed at the root of your release image. As with a components Files editor, you add a file to the Disk1 folder by selecting the Disk1 icon, right-clicking in the Files list, and then browsing for the file (specifying a path variable, if desired).

Unlike a component, however, the Disk1 area does not accept dynamic file links.

The Solution
All of the settings you set for a project are stored in tables of the ISM file, which is a renamed MSI database with extra tables that store Developer-specific data. For example, feature settings are stored as records in the Feature table, and file- link information is added to the File table. For each file you add to the Disk1 area of the Setup Files view, Developer adds a record to the ISDisk1File table of your ISM file. You can view the records using the Direct Editor, located under Advanced Views.

As you can see in the Direct Editor, records in the ISDisk1File table have two fields, called ISDisk1File (an arbitrary key that identifies a record) and ISBuildSourcePath (the location on the build system of the file in the Disk1 view). Because an ISM file is an enhanced MSI file, you can use the same MSI Automation interface methods to query and modify the data in your ISM file that you would use on an MSI file. In particular, you might add a record to the ISDisk1File table as follows, using a SQL query that inserts the new record in a VBScript file.
Set oMSI = CreateObject("WindowsInstaller.Installer") ' open transacted Set oDB = oMSI.OpenDatabase("C:\MySetups\Disk1Files.ism", 1) ' insert a single record into the ISDisk1File table Set oView = oDB.OpenView("INSERT INTO `ISDisk1File` " & _ "(`ISDisk1File`.`ISDisk1File`," _ "`ISDisk1File`.`ISBuildSourcePath`) " & _ "VALUES ('OneMoreFile', 'C:\Sources\ReadMe2.txt')") ' clean up oView.Execute: oView.Close: oDB.Commit Set oMSI = Nothing

Listing 1. AddOneFileToDisk1.vbs

(For more information about the MSI Automation interface and SQL queries, see the MSI Help Library book Automation Interface Reference.) After running the script and reopening the ISM file, you should see the new file appear in the Disk1 view.

Simulating Dynamic Linking


To simulate dynamic file linking in the Disk1 folder, you can use the FileSystemObject interface to enumerate all the files in a desired source directory, and then add a record to the ISDisk1File table for each file found in the directory. An outline of the code might appear as follows.
Set oFSO = CreateObject("Scripting.FileSystemObject") Set cSourceFiles = oFSO.GetFolder("C:\Sources\AddMeToDisk1").Files For Each file in cSourceFiles ' add a record to the ISDisk1File table, as above Next ' file

There are some issues with this approach that need to be addressed: A file name might contain a character that is invalid for a primary key name. A dynamically linked file might not appear in a future build, and so the new records should perhaps be deleted from the database after a build.

The following VBScript code, then, simulates dynamic file linking in the Disk1 folder, using this approach:
' ' ' ' ' ' ' ' ' '

Get a list of the files in the desired source folder; Fix up the file names to make valid primary keys; Add the new file records to the ISDisk1File table; Build a release using Developer Automation; Delete the new dynamic records.

Disk1Files.vbs: Adds the contents of a given folder to the table that represents Disk1 files, builds the package, and then deletes the new records. Limitations: Doesn't detect duplicate "fixed" file names. Filters out spaces, parentheses, and ampersands from file names; should filter other illegal characters. Fails if records already exist.

' ' ### change this to your project file ### Const g_Project = "C:\MySetups\Disk1Files.ism" ' ### change this to your source folder ### Const g_Sources = "C:\Sources\AddMeToDisk1" ' ### change these to desired product config, release ### Const g_ProductConfig = "ThisProductConfig" Const g_Release = "ThisRelease" Set oFSO = CreateObject("Scripting.FileSystemObject") Set oMSI = CreateObject("WindowsInstaller.Installer") Set oDB = oMSI.OpenDatabase(g_Project, 1) ' i.e., open transacted Set cSourceFiles = oFSO.GetFolder(g_Sources).Files For Each file In cSourceFiles ' for testing... ' MsgBox "Adding record " & FixFilename(file.Name) & ", file " & file.Path ' create records, using fixed-up file names as primary keys Set oView = oDB.OpenView("INSERT INTO `ISDisk1File` " & _ "(`ISDisk1File`.`ISDisk1File`, `ISDisk1File`.`ISBuildSourcePath`) " & _ "VALUES ('" & FixFilename(file.Name) & _ "', '" & CStr(file.Path) & "')") oView.Execute oView.Close Next ' file oDB.Commit Set oView = Nothing: Set oDB = Nothing

'

build using Developer Automation

Set oISM = CreateObject("ISWiAutomation.ISWiProject") oISM.OpenProject g_Project, True ' open read-only oISM.ISWiProductConfigs(g_ProductConfig).ISWiReleases(g_Release).Build( ) oISM.CloseProject

'

delete records added

Set oDB = oMSI.OpenDatabase(g_Project, 1) ' i.e., open transacted For Each file In cSourceFiles ' for testing... ' MsgBox "Deleting record " & FixFilename(file.Name) ' create records, using filenames as primary keys Set oView = oDB.OpenView("DELETE FROM `ISDisk1File` WHERE " & _ "`ISDisk1File`.`ISDisk1File`='" & FixFilename(file.Name) & "'") oView.Execute oView.Close

Next ' file oDB.Commit Set oISM = Nothing Set oMSI = Nothing: Set oFSO = Nothing MsgBox "Done!" ' for testing

' -----------------------------Function FixFilename(strFilename) ' TO DO: filter out other illegal characters strFilename = Replace(strFilename, " ", "_", strFilename = Replace(strFilename, "&", "_", strFilename = Replace(strFilename, "(", "_", strFilename = Replace(strFilename, ")", "_",

1, 1, 1, 1,

-1, -1, -1, -1,

1) ' text replacement 1) 1) 1)

' if first character is numeric (e.g., 28.txt) prefix key name with underscore If (IsNumeric(Left(strFilename, 1))) Then strFilename = "_" & strFilename End If ' limit primary key name to 72 chars strFilename = Left(strFilename, 72) FixFilename = strFilename End Function

Listing 2. Disk1Files.vbs

Further Directions
Using the technique described here, you can modify other properties of your project that are not exposed in the Developer Automation interface, such as: Path variable settings (modifying the ISPathVariable table) The maximum product version detected in a major upgrade (modifying the Upgrade table) Features required by another feature (modifying the ISRequiredFeature table)

Anda mungkin juga menyukai