rubrapack Manual←↑→

9 Conditions and searches

Goal: decide on the user's computer what to install. Install only on 64-bit Windows; offer a part only where Notepad exists; make the desktop shortcut something the user can turn off; and install the next version into the folder the user chose for this one.

9.1 Properties#

Windows Installer keeps named values called properties while it runs: ProductName, INSTALLDIR, VersionNT64 (set on 64-bit Windows), and your own. A property whose name is all capitals is public: it can be set on the command line (msiexec /i hello.msi DESKTOP_SHORTCUT=0) and by the dialogs. A condition is a small expression over properties, true or false:

ConditionTrue when
VersionNT64the property is set (not empty): here, on 64-bit Windows
NOT Installedthe product is not installed yet (a first installation)
DESKTOP_SHORTCUT = "1"the property's value is exactly 1
VersionNT >= 603the Windows version number is 6.3 or later
A AND (B OR NOT C)combinations, as you would expect

9.2 The source#

# tutorial 09: hello.toml
format = 1

[package]
name = "Hello"
manufacturer = "Example Software"
version = "$(VERSION)"
arch = "x64"
upgrade-code = "{3F2A6C1D-8B4E-4F7A-9C2D-5E6F7A8B9C0D}"
ui = "features"

[define]
VERSION = "1.7.0"

[property.DESKTOP_SHORTCUT]
value = "1"
secure = true

[require.Windows64]
condition = "VersionNT64"
message = "[ProductName] needs 64-bit Windows."

[search.Notepad]
property = "NOTEPAD_PATH"
kind = "file"
path = "$(SystemRoot)"
file = "notepad.exe"

[search.PreviousDir]
property = "INSTALLDIR"
kind = "registry"
root = "HKLM"
key = "Software\\Example Software\\Hello"
name = "InstallDir"

[feature.Main]
title = "Hello"
required = true

[feature.NotepadHelper]
title = "Open notes in Notepad"
description = "Only offered where Notepad is installed."
when = "NOTEPAD_PATH"

[dir.INSTALLDIR]
path = "$(ProgramFiles)/Hello"
feature = "Main"

[file.Hello]
dir = "INSTALLDIR"
source = "dist/hello.exe"

[file.Settings]
dir = "INSTALLDIR"
source = "dist/settings.ini"
feature = "NotepadHelper"

[registry.RememberDir]
root = "HKLM"
key = "Software\\Example Software\\Hello"
name = "InstallDir"
value = "[INSTALLDIR]"
feature = "Main"

[shortcut.StartMenu]
dir = "Programs"
name = "Hello"
target = "file:Hello"

[shortcut.Desktop]
dir = "Desktop"
name = "Hello"
target = "file:Hello"
when = "DESKTOP_SHORTCUT = \"1\""

9.3 Your own property: [property.NAME]#

[property.DESKTOP_SHORTCUT] creates the property with the default 1. Names must be all capitals to be public; names Windows or rubrapack use themselves (ALLUSERS, ARP..., MSI..., ...) are refused.

9.4 Installing something only when: when#

when on a feature, a file or file group, a shortcut, a registry value, an environment variable or an INI value installs it only when the condition is true at the first installation:

A repair keeps what was installed; a major upgrade (the next version) decides again.

9.5 Refusing to install: [require.ID]#

A requirement stops a first installation with its message when its condition is false - here, on 32-bit Windows: "Hello needs 64-bit Windows." Repair and removal are never blocked.

9.6 Looking around first: [search.ID]#

A search runs before anything else and puts what it found into a property (empty if nothing was found), which conditions can then test:

kindFindsKeys
filethe full path of a filepath (a known folder and a relative path), file, min-version (for programs)
dira folderpath
registrya value in the registryroot, key, name, view (32 for the 32-bit view)
componentthe key file of another product's componentcomponent-guid

[search.Notepad] looks for notepad.exe in the Windows folder and puts its path into NOTEPAD_PATH.

9.7 Remembering the install folder#

If a user installed Hello into D:\Tools\Hello, the next version should go there too, not back to Program Files. Two pieces do it:

  1. [registry.RememberDir] writes the folder into the registry when installing: [INSTALLDIR] in a value is replaced by the folder (chapter 11 is about the registry).
  2. [search.PreviousDir] reads it back. Its property is the dir ID INSTALLDIR, so what it finds becomes that dir's default - but only if that folder still exists, and a folder given on the command line still wins.

9.8 What happened inside#

C:\work\hello> rubrapack inspect hello.msi LaunchCondition
Installed OR (VersionNT64)	[ProductName] needs 64-bit Windows.
C:\work\hello> rubrapack inspect hello.msi AppSearch
NOTEPAD_PATH	Notepad
RpFound_PreviousDir	PreviousDir
C:\work\hello> rubrapack inspect hello.msi Condition
NotepadHelper	0	NOT Installed AND NOT (NOTEPAD_PATH)

(Headers left out.) rubrapack adds Installed OR to requirements, so that an installed product can always be repaired or removed. A feature's when becomes a row in the Condition table that sets its level to 0 - "not installed, not shown" - when the condition is false; NOT Installed keeps that from happening at removal, when properties are gone. Every shortcut has a component of its own (chapter 5); the desktop shortcut's holds the when in its Condition column:

C_2ea6d5bfd9b4a9073b30	{BCBFF063-...}	DesktopFolder	260	DESKTOP_SHORTCUT = "1"	R_7f1795ed8aa7ac1a1c60