MSI FAQ

HOME
UP

 
 

How to run a nested *.exe relative to the calling *.msi ([SOURCEDIR]setup.exe)

  • Define a Property as "placeholder" to store Path in it --> _SDEXE 

Table:Properties

Property Value
_SDEXE placeholder, will be replaced
  • Create a Custom Action "CA_SETPROP" (immediate Execute, call VBS embedded)
  • Create a Custom Action "CA_SILENT" (defered, System, Synchronous)

Table:Custom Action

Action Type Source Target
CA_SETPROP     session.property("_SDEXE")= session.property("SOURCEDIR")& "setup.exe"
CA_Silent 3122 _SDEXE <commandlineparameters...>
  • Give that Stuff the proper Conditions and Sequence in 

Table: InstallExecuteSequence

Action Condition Sequence
CA_Silent NOT REMOVE~="ALL" AND NOT REINSTALL i.e. 2962
CA_SETPROP   i.e. 1825

 


What are the differences between patching, update and upgrade with MSI?

Type of update ProductCode ProductVersion PackageCode remark
Small Update - - Changed
An update to one or two files.The package code in the Revision Number Summary Property does change. Can be shipped as a full installation package or as a patch package.
Minor Upgrade - Changed  
A small update making changes significant enough. Shipped as a full installation package or as a patch package.
Major Upgrades Changed Changed  
A comprehensive update of the product. Shipped as a patch package or as a full product installation package.

 


Which UI Level I'm running?

To detemine the user-interface level being used by a running installation,create conditions that test the value of the UILevel property.
The UILevel property contains the value

Level Description
5 full-UI
4 reduced-UI
3 basic-UI
2 completely silent

I.e. to create a CA that should run only during a completely silent installation, you can schedule the action with the condition UILevel=2.

Keep in mind that actions in the User Interface sequence will be skipped for anything other than a completely silent installation, irrespective of any conditions associated with them!

Instead using msiexec.exe, you can launch an MSI package from VBScript using the InstallProduct method of the MSI Automation interface; you can set the UI level for an installation launched from VBScript code by setting the UILevel property of the Installer object before calling InstallProduct.

Set oMSI = CreateObject("WindowsInstaller.Installer")
' set the UI level to basic
oMSI.UILevel = 3
' launch the installer
oMSI.InstallProduct "C:\Source\MyApp\MyApp.msi", ""
' clean up used ObjectVars
Set oMSI = Nothing


Note, however, than you cannot change the user-interface of a running installation (that is, inside a custom action).


How to Add a Printer

If OS > W2k you can call printui.dll to install a printer and its driver, example:
rundll32.exe printui.dll,PrintUIEntry /if /b "HP LaserJet III" /f%windir%\inf\ntprint.inf /r "lpt1:" /m "HP LaserJet III"
Installs Printer HP LaserJet III on port lpt1 using HP LaserJet III driver .
rundll32.exe printui.dll,PrintUIEntry /? for help file.
Run the executable rundll32.exe in a custom action with the rest of the syntax as the command line.
I have found that if you want to add the printer and its driver you need to have the port already existing. To add the port you can use the follwoing VB script, but you will need to install prnadmin.dll, comes with WIN2k resource kit, with your install. Substitute PORT Name with the port you desire to add.

Set oPort = CreateObject("Port.Port.1")
Set oMaster = CreateObject("PrintMaster.PrintMaster.1")
oPort.PortName = "PORT Name"
oPort.PortType=3
on error resume next
oMaster.PortAdd oPort


How to run a classID from Explorer / InternetExplorer

eg. Publishing on Windows Terminal Server / Citrix

iexplore.exe ::{ClassGUID}
explorer.exe ::{ClassGUID}

 

Where to place Custom Action to manipulate Directory Table

The Directory Table will be resoluted during the "CostFinalize" Action
To manipulate Directory Table Entries ensure that You place Your type 51 Custom Action after that InstallExecuteSequence entry.

Add Line to logfile from Custom Action

If You need to add a Line of text to the MSI-Logfile within Your custom action

 VBS:

Add Line to MSI Logfile Sub AddLogFile (strLogText)
Dim recLogText
 Const msiMessageTypeInfo = &H04000000
 Set recLogText = Session.Installer.CreateRecord(2)
 recLogText.StringData(1) = "CustomAction"
  recLogText.StringData(2) = by Zacky, CleverITS: " & strLogText
 Session.Message msiMessageTypeInfo, recLogText
End Sub
 

Return last / free position in Enumerated Regkey and submit to MSI

VBS code to add as Custom Action, with session.property transaction

just a sample, You have to optimize ;-)

ENUM REGKEYS ' (c) 2004 by Zacky, www.cleverits.com
Option Explicit
Dim WSHShell, RegKey, RegRoot, i, actENUM,return, lastENUM
Set WSHShell = CreateObject("WScript.Shell")
RegKey = Session.Property("REGENUM1")
RegRoot = "HKLM\"
'beautifying Regkey if no trailing \
If InStr (Len(RegKey)-1,RegKey,"\") Then
Else
  RegKey = RegKey & "\"
End If
RegKey = revEnum(RegRoot,RegKey)
session.Property("REGENUM1")= RegKey

Function revEnum (RegRoot,RegKey)
  actENUM = 9999
  On Error Resume Next
  'guess its unlike that more than 299 drivers exists (rec by zacky)
  For i = 299 To 0 Step -1
    Select Case Len(i)
      Case 4 actENUM = i
      Case 3 actENUM = "0" & i
      Case 2 actENUM = "00" & i
      Case 1 actENUM = "000" & i
    End Select
    return = WSHShell.RegRead(RegRoot & RegKey & actENUM & "\DriverDesc")
    If return <> "" Then Exit For
      lastENUM = RegKey & actENUM
  Next
  revEnum = lastENUM
End Function

 

HKCU RegKey in Citrix Server

just put them in HKLM\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\TerminalServer\Install

Resolve SourceDir Property

make use of ResolveSource in InstallExecuteSequence

 

Custom Action: Delete Folder given by Property

'(C) by Wolfgang Zerzawy
' use as Custom Action Type 102
' Use Condition in Install Execute Sequence: REMOVE~="ALL"
Option Explicit
Dim WshShell,SystemFolder,Fso,strFolder, strFile, ret
' ensure that You dont Use "Root-Folders" ! e.g. C:\Programme -- that would be fatal!
strFolder = GetAProperty("DATADIR")
strFolder = Left(strFolder,Len(strFolder)-1)
On error resume next
'Environment variable reading
set WshShell = CreateObject("WScript.Shell")
set Fso=createobject("scripting.filesystemobject")

If Fso.FolderExists(strFolder) Then
ret = Fso.DeleteFolder (strFolder,True)
MsgBox strFolder & " deleted with ErrorLevel" & ret & ". Let's go further"
AddLogFile strFolder & " deleted with ErrorLevel" & ret & ". Let's go further"
Else
AddLogFile strFolder & " could not be deleted. Either not Present or something else ... --> not really an error"
End if

Set WshShell = Nothing
Set fso = Nothing


' Getting a Property
Function GetAProperty (PROPERTYNAME)
dim szStringVal
szStringVal = Session.Property(PROPERTYNAME)
GetAProperty = szStringVal
End Function

Sub AddLogFile (LogText)
const msiMessageTypeInfo = &H04000000
set LogText = Session.Installer.CreateRecord(2)
LogText.StringData(1) = "ZA_CustomAction"
LogText.StringData(2) = LogText
Session.Message msiMessageTypeInfo, LogText
End Sub
 

Launch Condition Windows XP SP2 or Windows 2000 Sp4 or Server 2003 or newer

Condition Description
(VersionNT>501) OR (VersionNT=500 AND ServicePackLevel>3) OR (VersionNT=501 AND ServicePackLevel>1) The minimum operating system requirement is Windows 2000 SP4, Windows XP SP2, or Windows Server 2003

 

(c) by Wolfgang Zerzawy 07-Mai-08 12:11   

XING