Easy MSI - A basic guide to Windows Installer

Click here to edit subtitle

Chapter 3 - Files and more (Download Solution)


Exercise 3.1: The File table and file components


In this exercise you will install one single file named bgm.wav.


Open your blastermaster.msi package with InstEd and add the following new record to the Component table:

column
 VALUE
 Component
  Comp_File_bgm.wav
 ComponentId
 <New GUID>
 Directory_
  TARGETDIR
 Attributes
  0x0000
 Condition
  <null>
 KeyPath
  <null>

Next add the following record to the FeatureComponents table:

Column
 Value
 Feature_
 Feature_BlasterMaster
 Component_
 Comp_File_bgm.wav

Finally add the following record to the File table:

column
 value
 File
 File_bgm.wav
 Component_
 Comp_File_bgm.wav
 FileName
 bgm.wav
 FileSize
 0
 Version
 <null>
 Language
 <null>
 Attributes
 <null>
 Sequence
 1

Exercise 3.2: A handy utility for adding many files


In this exercise you will use the utility file_adder.hta for adding many files to your blastermaster.msi package.


Copy both the utility file_adder.hta and the installation sources to your projects folder.

Use the utility file_adder.hta as described in the book to add File, Component, and Feature_Components records for each file of the installation sources (except of the file bgm.wav which you already included in the exercise above. At the end your file table should contain the following files:

File
 Component_
 filename
 File_bgm.wav
 Comp_File_bgm.wav
 bgm.wav|bgm.wav
 File_BlasterMaster.exe
 Comp_File_BlasterMaster.exe
 BLASTE~2.EXE|BlasterMaster.exe
 File_BlasterMaster.pdb
 Comp_File_BlasterMaster.pdb
 BLASTE~1.PDB|BlasterMaster.pdb
 File_BlasterMaster.vshost.exe
 Comp_File_BlasterMaster.vshost.exe
 BLASTE~1.EXE|BlasterMaster.vshost.exe
 File_BlasterMaster.vshost.exe.manifest
 Comp_File_BlasterMaster.vshost.exe.manifest
 BLASTE~1.MAN|BlasterMaster.vshost.exe.manifest
 File_BMService.exe
 Comp_File_BMService.exe
 BMSERV~1.EXE|BMService.exe
 File_dive.wav
 Comp_File_dive.wav
 dive.wav|dive.wav
 File_enemyShot.wav
 Comp_File_enemyShot.wav
 ENEMYS~1.WAV|enemyShot.wav
 File_eol.wav
 Comp_File_eol.wav
 eol.wav|eol.wav
 File_explosion.wav
 Comp_File_explosion.wav
 EXPLOS~1.WAV|explosion.wav
 File_fmod.dll
 Comp_File_fmod.dll
 fmod.dll|fmod.dll
 File_high scores.txt
 Comp_File_high scores.txt
 HIGHSC~1.TXT|high scores.txt
 File_Ionic.Zip.Reduced.dll
 Comp_File_Ionic.Zip.Reduced.dll
 IONICZ~1.DLL|Ionic.Zip.Reduced.dll
 File_manual_english.pdf
 Comp_File_manual_english.pdf
 MANUAL~1.PDF|manual_english.pdf
 File_manual_german.pdf
 Comp_File_manual_german.pdf
 MANUAL~2.PDF|manual_german.pdf
 File_NET.Library.dll
 Comp_File_NET.Library.dll
 NETLIB~1.DLL|NET.Library.dll
 File_nextLevel.wav
 Comp_File_nextLevel.wav
 NEXTLE~1.WAV|nextLevel.wav
 File_pickup.wav
 Comp_File_pickup.wav
 pickup.wav|pickup.wav
 File_setup.inf
 Comp_File_setup.inf
 setup.inf|setup.inf
 File_setup.rpt
 Comp_File_setup.rpt
 setup.rpt|setup.rpt
 File_shoot.wav
 Comp_File_shoot.wav
 shoot.wav|shoot.wav
 File_warp.WAV
 Comp_File_warp.WAV
 warp.WAV|warp.WAV

Then rename the entry File_high scores.txt to  File_highscores.txt (remove the empty space).

Finally mark all files, right-click them and click "Retrieve file details from external source path" in the context menu in order to update the FileSize, Version, and Language column values for each file.


Exercise 3.3: Including the source (uncompressed source outside)

In this exercise you will include the source located uncompressed outside of the MSI package (in an external tree).


Make sure all the files you added in the exercise above lie in the same folder as your blastermaster.msi package before you continue.

Then add the following new record to the Media table.

column
 Value
 DiskId
  1
 LastSequence
  22
 DiskPrompt
 <null>
 Cabinet
 <null>
 VolumeLabel
 <null>
 Source
 <null>

Note: If you install your blastermaster.msi now it will copy the files to the root folder of the drive with the largest available disk space (because we did not yet specify a value for the TARGETDIR property).


Exercise 3.4: Including the source (CAB outside)

In this exercise you wil include the source located in a CAB file outside of the MSI package.


First edit the Summary Information Stream of your blastermaster.msi package (Tables > Summary Info...) and change its "ImageType" to "Compressed. Long file names." Then go to the Media table add modify the existing record to the following:
column
 Value
DiskId
  1
 LastSequence
  22
 DiskPrompt
 <null>
 Cabinet
 blastermaster.cab
 VolumeLabel
 <null>
 Source
 <null>

Note: For an installation you will now need only the two files blastermaster.msi and blastermaster.cab located in the same folder.


Exercise 3.5: Including the source (CAB inside)

 this exercise you will include the source located in a CAB file inside of the MSI package.


To stream the blastermaster.cab into your MSI package just prefix the Cabinet entry in the Media table with a number character (#) and rebuild the CAB.
column
 Value
 DiskId
  1
 LastSequence
  22
 DiskPrompt
 <null>
 Cabinet
 #blastermaster.cab
 VolumeLabel
 <null>
 Source
 <null>

Note: For an installation you will now need only the file blastermaster.msi.


Exercise 3.6: Setting the directory layout

In this exercise you will set the directory layout where the files will get installed on the target system.


First add the following record to the Property table:
Column
 VALUE
 Property
  TARGETDIR
 Value
  C:\BlasterMaster

Switch to the Component table add change the value of the Comp_File_manual_english.pdf and Comp_File_manual_german.pdf records’ Directory_ column to the following: Dir_Manuals_english and Dir_Manuals_german.


Once you you added the Components you might have noticed red errors indication that the Directory_ column of the Component table holds references to records in in the Directory table that do not yet exist. Thus, add the following records to the Directory table:

Column
 Value
 Directory
  Dir_Manuals_english
 Directory_Parent
  Dir_Manuals
 DefaultDir
  english
Column
 Value
 Directory
 Dir_Manuals_german
 Directory_Parent
 Dir_Manuals
 DefaultDir
 german

Another red error will indicate that the Directory_Parent column is not (yet) valid. Therefore, add another record for the parent directory to the Directory table.

Column
 value
 Directory
  Dir_Manuals
 Directory_Parent
  TARGETDIR
 DefaultDir
  Manuals

Finally move the files manual_english.pdf and manual_german.pdf into the following sub folders:

C:\YourProjectDir\Manuals\english\manual_english.pdf

C:\YourProjectDir\Manuals\german\manual_german.pdf


Then rebuild your CAB by switching to the Media table, right-click, Rebuild selected CABs...


Exercise 3.7: Installing empty folders

In this exercise you will install an empty folder named "empty" on the target system.


First add the following record to the CreateFolder table:

Column
 Value
 Directory_
  Dir_empty  
 Component_
  Comp_CreateFolder_empty

Once you added the record red errors will be shown, indicating that the foreign key references to the Directory and to the Component table could not be resolved. 

Thus, add the following new records to the Directory and Component tables:

column
 VaLUE
 Directory
  Dir_empty
 Directory_Parent
 TARGETDIR
 DefaultDir
 empty
column
 Value
 Component
 Comp_CreateFolder_empty 
 ComponentId
  <new GUID>
 Directory_
 TARGETDIR
 Attributes
 0x0000
 Condition
  <null>
 KeyPath
  <null>

Finally link the new component with a feature via the FeatureComponents table:

column
 Value
 Feature_
 Feature_BlasterMaster
 Component_
 Comp_CreateFolder_empty

Exercise 3.8: Moving, duplicating, and removing files

In this exercise you will move, duplicate, and remove files.


First the file C:\WINDOWS\notify.wav shall be copied to the installation target directory under the new name C:\BlasterMaster\notifier.wav.

Therefore add the following new record to the MoveFile table:

Column
 Value
 FileKey
 MoveFile_notify.wav
 Component_
 Comp_MoveFile_notify.wav
 SourceName
  <null>
 DestName
 notifier.wav
 SourceFolder
 Prop_Path_notify.wav
 DestFolders
 TARGETDIR
 Options
 0

Next add the Prop_Path_notify.wav property to the Property table:

column
 Value
 Property
 Prop_Path_notify.wav
 Value
 C:\Windows\Media\notify.wav

Then add a component that controls the execution of the MoveFiles action to the Component table and link it with a feature via the FeatureComponents table:

Column
 value
 Component
 Comp_MoveFile_notify.wav
 ComponentId
 <new GUID>
 Directory_
 TARGETDIR
 Attributes
 0x0000
 Condition
 <null>
 KeyPath
 <null>
column
 value
 Feature_
 Feature_BlasterMaster
 Component_
 Comp_MoveFile_notify.wav

In a next step the file C:\BlasterMaster\bgm.wav (which is installed with the package) shall be duplicated as file C:\BlasterMaster\bgm2.wav.

Therefore add the following new record to the DuplicateFile table:

column
 Value
 FileKey
 DupFile_bgm.wav
 Component_
 Comp_DupFile_bgm.wav
 File_
 File_bgm.wav
 DestName
 bgm2.wav
 DestFolder
 TARGETDIR

Then add a component that controls the execution of the DuplicateFiles action to the Component table and link it with a feature via the FeatureComponents table:

column
 Value
 Component
 Comp_DupFile_bgm.wav
 ComponentId
 <new GUID>
 Directory_
 TARGETDIR
 Attributes
 0x0000
 Condition
 <null>
 KeyPath
 <null>
column
 Value
 Feature_
 Feature_BlasterMaster
 Component_
 Comp_DupFile_bgm.wav

When you uninstall the package, you will notice that the file "notifier.wav" (which comes by the MoveFile action), is not removed.

For getting rid of that file during uninstallation you have to explicetely remove it using the RemoveFile table:

Column
 value
 FileKey
 RemoveFile_notifier.wav
 Component_
 Comp_RemoveFile_notifier.wav
 FileName
 notifier.wav
 DirProperty
 TARGETDIR
 InstallMode
 2

Finally, add the "Comp_RemoveFile_notifier.wav" record to the Component table and link it with the "BlasterMaster" feature by adding a new record to the FeatureComponents table.

Column
 Value
 Component
  Comp_RemoveFile_notifier.wav
 ComponentId
  <new GUID>
 Directory_
  TARGETDIR
 Attributes
  0x0000
 Condition
  <null>
 KeyPath
  <null>
Column
 Value
 Feature_
  Feature_BlasterMaster
 Component_
  Comp_RemoveFile_notifier.wav

Exercise 3.9: Reorganizing the feature-component tree

In this exercise you will modify the following records of the FeatureComponents table. All other records stay linked to the default feature Feature_BlasterMaster.


Feature_
 COMPONENT_
 Feature_BlasterMasterService
 Comp_File_BMService.exe
 Feature_UserManual_English
 Comp_File_manual_english.pdf
 Feature_UserManual_German
 Comp_File_manual_german.pdf

Exercise 3.10: .NET Assemblies


Purpose of this exercise is to author the tables MsiAssembly and MsiAssemblyName in order to install a .NET assembly.


First go to the Component table and change the KeyPath value for the Comp_File_NET.Library.dll component to File_NET.Library.dll.


Then add the following record to the MsiAssembly table:

Column
 Value
 Component_
 Comp_File_NET.Library.dll
 Feature_
 Feature_BlasterMaster
 File_Manifest
  File_NET.Library.dll
 File_Application
 <null>
 Attributes
 0

Next add the following records to the MsiAssemblyName table:

Column
 value
 Component_
 Comp_File_NET.Library.dll
 Name
 Name
 Value
 NET.Library
column
 value
 Component_
 Comp_File_NET.Library.dll
 Name
 Version
 Value
 2.0.0.0
Column
 Value
 Component_
 Comp_File_NET.Library.dll
 Name
 ProcessorArchitecture
 Value
 MSIL
Column
 Value
 Component_
 Comp_File_NET.Library.dll
 Name
 PublicKeyToken
 Value
 d284900a5773d0d8
column
 Value
 Component_
 Comp_File_NET.Library.dll
 Name
 Culture
 Value
 neutral

Exercise 3.11: Registering for COM


In this exercise you will register a DLL for COM. 


First add the following new record to the Component table:

column
 value
 Component
 Comp_Reg_Ionic.Zip.Reduced.dll
 ComponentId
  <new GUID>
 Directory_
 TARGETDIR
 Attributes
 0x0004
 Condition
  <null>
 KeyPath
  <null>

Then link the component with a feature via the FeatureComponents table:

Column
 VALUE
Feature_
  Feature_BlasterMaster
 Component_
  Comp_Reg_Ionic.Zip.Reduced.dll

Then open a Visual Studio CMD shell and call 

regasm.exe Ionic.Zip.Reduced.dll /regfile:myregfile.reg


Then import the .reg file into the Registry table as described earlier in the book (right-click component, import reg file ...).


Exercise 3.12: Setting Environment Variables


In this exercise you will set an environment variable using the Environment table. Thus, add the following new record to the Environment table:

Column
 Value
 Environment
 Env_BlasterMasterPath
 Name
 =-*BlasterMasterPath
 Value
 [TARGETDIR]
 Component_
 Comp_Env_BlasterMasterPath

Once the Environement table is done, add the Component and the FeatureComponents records:

column
 value
 Component
 Comp_Env_BlasterMasterPath
 ComponentId
 <new GUID>
 Directory_
 TARGETDIR
 Attributes
 0x0000
 Condition
 <null>
 KeyPath
 <null>
column
 value
 Feature_
 Feature_BlasterMaster
 Component_
 Comp_Env_BlasterMasterPath

Exercise 3.13: File Shortcuts


In this exercise you will create a desktop shortcut to the BlasterMaster.exe.


Before you start this exercise, download the tool IconExplorer.


Now add the following new record to the Directory table:

column
 Value
 Directory
 DesktopFolder
 Directory_Parent
 <null>
 DefaultDir
 SourceDir

Use the tool IconExplorer to find out the Index for the "Star" Icon in the C:\Windows\System32\shell32.dll (43).

Then stream the file C:\Windows\System32\shell32.dll into the Icon table: 

column
 value
 Name
 shell32.dll
 Data
 <binary> (Stream C:\Windows\System32\shell32.dll into this field)

Finally, add the following record to the Shortcut table:

column
 value
 Shortcut
 Sc_Desktop_Blastermaster.exe
 Directory_
 DesktopFolder
 Name
 Blaster Master
 Component_
 Comp_File_BlasterMaster.exe
 Target
 [TARGETDIR]BlasterMaster.exe
 Arguments
 <null>
 Description
 <null>
 Hotkey
 <null>
 Icon_
  shell32.dll
 IconIndex
  43
 ShowCmd
  <null>
 WkDir
  <null>
 DisplayResourceDLL
  <null>
 DisplayResourceId
  <null>
 DescriptionResourceDLL
  <null>
 DescriptionResourceId
  <null>

Exercise 3.14: Advertised Shortcuts


In this exercise you will modify the desktop shortcut from the exercise above to an advertised shortcut.


First change the Target field of the Shortcut table for the Sc_Desktop_Blastermaster.exe shortcut to Feature_BlasterMaster.

column
 value
Target
 Feature_BlasterMaster
Then change the KeyPath field of the Component table for the component Comp_File_BlasterMaster.exe to File_BlasterMaster.exe.
Column
 value
KeyPath
 File_BlasterMaster.exe

For transforming the advertised shortcut to a non-advertised shortcut again just set the DISABLEADVTSHORTCUTS property to 1 in the Property table:

column
 value
 Property
 DISABLEADVTSHORTCUTS
 Value
 1