OPENMSI.MMH - Making changes to existing databases |
This section deals mainly with making changes to existing Windows Installer databases. The same process could be used to build a complete Windows Installer database from scratch but this is basically covered under the section "Preferred MSI Interface for Building a Complete MSI" as you would wish to create some sort of "wrapper" to take care of common requirements such as what do you begin with (a "template" MSI etc) and common requirements such as setting package GUIDs.
As an alternative to this "OPENMSI.MMH" approach you could use a batch file running multiple "WiRunSql.VBS" commands. The main advantage of this is that it will be much quicker, the downsides include that errors are difficult to test for, its harder to create the correct commands and its not as easy to understand. The "MsiDiff.VBS" tool can generate the correct MAKEMSI code for you.
To use the "OpenMsi.MMH" header simply include it rather than "MAKEMSI.MMH".
These are the main "basic" macros you would likely wish to use (as they basically supply most of what "ORCA" does):
EXAMPLE - Basic ("OPENMSI.MMH") |
;--- Include MAKEMSI Support ------------------------------------------------ #include "OpenMsi.MMH" ;--- Do the work ------------------------------------------------------------ <$Msi "out\TestMsi.mm\Msi\After.msi" template="out\TestMsi.mm\Msi\Before.msi"> ;--- A simple change to an existing MSI ---------------------------------- <$Property "ABCDEFG" VALUE="C:\"> <$/Msi>
Of course there is no reason most of the many higher level commands can't be used if you wish although some of these may need a bit more care (mostly checking prerequisites and defaults), for example this code can be used to add files:
;--- Include MAKEMSI Support ------------------------------------------------ #include "OpenMsi.MMH" ;--- Do the work ------------------------------------------------------------ <$Msi "out\TestMsi.mm\Msi\After.msi" template="out\TestMsi.mm\Msi\Before.msi"> <$Cabinet "Added Files"> ;<$Feature "ALL.3.080.0101.TESTMSI" CREATE="N"> <$Component "c1.ALL.3.080.0101..INSTALLDIR_x" CREATE="N"> <$Files "TryMe.*"> <$/Component> ;<$/Feature> <$/Cabinet> <$/Msi>
The above is just one possibility (as to how you may need to do that depending on the source msi and your requirements), here are some notes:
EXAMPLE - WRAP IT - Perhaps a Smarter Way... |
The previous example directly included the "OPENMSI.MMH" header file, while this is OK you probably also wish to do other "standard" things when you change and MSI (or you may wish to in the future). An example of this is any "standard" (for you) "MsiValFilter" commands mentioned above.
Its a good idea if you create your own header file (even if it doesn't do much more than include "OpenMSI.MMH"), that way you can add to your wrapper header at any time and the changes will be included in any future updates you do without the need to retrofit anything.
The most obvious thing you may wish to do when updating an MSI is to to update the author information. You can make any application of "standards" optional to handle any instances where you may not be able to apply the updates. You may also wish to require the user (probably you!) to specifically refer to macros you create in this header, whatever you do have a think about how you like to work and how you can maximise your flexibility.
The following is one example of such a header file (called "MyMsiUpdate.MMH").
;--- Include the standard MAKEMSI "update" header --------------------------- #include "OpenMsi.MMH" ;--- Start the Update process ----------------------------------------------- <$Msi "<$UPDATE_TO>" template="<$UPDATE_FROM>"> ;--- Schedule the update termination after all your changes ----------------- #OnExit #100 <$ExecutedAfterAllUserUpdates> #( #define ExecutedAfterAllUserUpdates ;--- Record Details about who is making the change ---------------------- <$Summary "LastAuthor" VALUE="<$MAKEMSI_USERNAME>"> <$Summary "EDITTIME" VALUE="now()"> ;--- Now finish off the "MSI" nesting ----------------------------------- <$/Msi> #)
As you hopefully noticed, the header requires the "includer" to define some standard definitions which contains the "before" and "after" database information and also removes the need for the "MSI" and "/MSI" commands in the including code.
The following shows the changes to the original sample to include the header:
;--- Include My MAKEMSI Update Support -------------------------------------- #define UPDATE_FROM out\TestMsi.mm\Msi\Before.msi #define UPDATE_TO out\TestMsi.mm\Msi\After.msi #include "MyMsiUpdate.MMH" ;;Include header and do "standard" things ;--- A simple change to an existing MSI ---------------------------------- <$Property "ABCDEFG" VALUE="C:\">
Note that the "before" and "after" macros could be passed on the invoking command line (with the PPWIZARD "/Define" switch) or via environment variables (see the "Invoking MSI Update Via Batch File" section for an example of this).