MAKEMSI quickly and reliably creates MSI files in a non-programmatic way
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
[Bottom][Contents][Prev]: Binary[Next]: Compile Options
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
\->Source Code->Commands->Cabinet

The "Cabinet" Command

This command will be used for these main reasons:

Compiled cab files are now cached by default for better build performance.

The main cabinet (compile) related options are:

;--- GLOBAL DEFAULT options when option not specified on the "Cabinet" command ---
#define? CABINET_ALIAS_DEFAULT                 [DEFAULT]             ;;If no or empty alias provided
#define? CABINET_ALIAS_FREQUENTLY_CHANGES      [FrequentlyChanges]   ;;If no or empty alias provided
#define? CABINET_CACHE                         Y                     ;;Y/N cache results
#define? CABINET_CABDDF_Compression            ON                    ;;ON/OFF - Want to compress files?
#define? CABINET_CABDDF_CompressionType        <$COMPRESS_MEDIUM>
#define? CABINET_CABDDF_CompressionLevel       7                   ;;Valid 1-7
#define? CABINET_CABDDF_CompressionMemory      21                  ;;Valid 10-21
#define? CABINET_CABDDF_ClusterSize            4096                ;;Safe for CD-ROM, floppies (512) etc
#define? CABINET_CAB_FILE_NAME_FORMAT          MM_?_*              ;;Name of generated 8.3 formatted CAB filename (without extension)., etc.

This command proves default cabinet options for any files nested between this command and the associated "/cabinet" command.

The command takes these parameters:

EXAMPLE: Grouping Files & varying parameters for Compiles

You may have some pre-compressed or large files for which you want to adjust the default "compile options" to turn off or reduce the level of compression to speed up the msi build. The following code (which can be added to the end of "TryMe.MM for testing) demonstrates this:

;--- Grab all the files in "SRC" directory (don't compress some) ------------
#define+ COMPILE_MAKECAB_VERBOSITY                3            ;;Max info
#define+ COMPILE_DELETE_CAB_FILES_IN_LOG_DIR      N            ;;Want to (easily) examine the .cab files (so leave in "LOG" dir)
<$Compile>                                                     ;;Start "Clean" : Compile files listed in "Tryme.MM" (above)
<$MacroCfg "COMPILE_CABDDF_Compress" PreExists="Y">            ;;Save correct value of this setting (so we don't need to "know" the original setting)
<$MacroCfg "COMPILE_CAB_FILE_NAME"   PreExists="Y">            ;; "
    #define+ COMPILE_CABDDF_Compress OFF                       ;;Zips are already compressed so we don't want to slow down the compile by recompressing
    #define+ COMPILE_CAB_FILE_NAME   NC*                       ;;Give CAB a "non compression" prefix (to remind me)
    <$Files "SRC\*.zip" DestDir="INSTALLDIR" EXLIST="COMPOFF"> ;;Add ZIPs and build  exclusion list of these files
    <$Files "SRC\*.rar" DestDir="INSTALLDIR" EXLIST="COMPOFF"> ;;Add RARs and update exclusion list of these files
    <$Compile>                                                 ;;Now compile the .zip & .rar files
<$/MacroCfg>                                                   ;;Restore "normal" state (could have just set to "ON" for this simplistic example)
<$/MacroCfg>                                                   ;; "
<$Files "SRC\*.*" DestDir="INSTALLDIR" EXLIST="COMPOFF">       ;;Add the rest of the files

The above example didn't use the cache (and there may not be much point for the ".zip" and ".rar" as we are not compressing them now), but you could add this command to the end of the example to have the "rest" of the files cached (another way to do this would be to adjust "COMPILE_CACHE_VALUE_FOR_COMPILE_ENDPASS1"):

<$Compile cache="TheRest" "Compiling the rest of the files">

CACHE: Using the "CACHE" Parameter

The cache allows you to avoid the possibly lengthy "MakeCab.EXE" steps since it remembers the results from the last time a set of files was compiled and will then only create a new cabinet file if one or more of that group of files has changed.

You would want to cache files if they take a long time to compile. It would pay to group files based on update frequency as any differences will cause the whole lot to be rebuilt, if this is not practical then you may wish to group by alphabet or some other scheme. Of course if you had one very large and slow file you would compile this one file on its own!

Without the cache you might be tempted to reduce the compression options for some files, however you are probably more prepared to take "a hit" if its only for the first time you build and perhaps infrequently after this...

Apart from file changes a rebuild will occur if:

  1. The file order was changed. Note that the "Files" command sorts filenames before adding them (so this doesn't depend on the file system's file ordering).

  2. Any compile option (that affects the ".ddf") is changed.

To determine if the cache is current the contents of the two ".ddf" files (cached & newly built) are compared after stripping out all comments except for those that mark the file details (that is begin with ";>>>").

CACHE: Add File Content Checking

By default only the file modification time and file size is used to indicate the "version" of a file (which is almost always enough).

You can change the following macro to define a replacement function which could look at a files contents (using an MD5 hash, will it slow it down too much though?) etc:

<__$ExampleFile INDENT=0 FILE="COMPILE.MMH" FRAGMENT="[4Doco-CacheFileStamp]" STATE="REMEMBER">

If the returned stamp is "" or a non zero "err.number" is returned then a randomised one will be generated which will include the "err.number" and "err.description" (and thereby effectively disabling the cache). Note that all variables you use must be declared or it will fail.

The following code when added to the start of your script will add an MD5 file hash to the comparison:


    "FileSize:"        & oFile.Size &               ;;File size
    ", LastModified: " & oFile.DateLastModified &   ;;Last modified
    ", MD5:"           & FileMd5(FileName)          ;;This alone will uniquely identify file but can be slow on big files (but faster than compile!)
#( '<?NewLine>'

   function FileMd5(ByVal FileName)     'Used by "COMPILE_VBSCRIPT_EXRESSION_CacheFileStamp"
       FileMd5 = "?"
       dim oHash : set oHash = oInstaller.FileHash(FileName, 0)
       FileMd5 = PrettyHash(oHash)                  ;;PrettyHash() is defined by MAKEMSI
       set oHash = Nothing
   end function

The information returned by "CacheFileStamp()" is stored in the ".DDF" file as demonstrated in the first line of this content (notice the MD5 we added):

;>>> FileSize:766, LastModified: 14/05/2004 3:01:08 PM, MD5:0076FBA0-47C5E6C0-01F96DCF-1D687C36 <<<
"TryMe.ico" TryMe.ico /DATE=2004-05-14 /TIME=15:01:08

Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.Please email me any feedback, additional information or corrections.
See this page online (look for updates)

[Top][Contents][Prev]: Binary[Next]: Compile Options

MAKEMSI© is (C)opyright Dennis Bareis 2003-2008 (All rights reserved).
Friday March 02 2018 at 4:06pm
Visit MAKEMSI's Home Page
Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.