Skip to content

Sections and install types

A section is a unit of work the user can turn off. Sections are written inside installer {} or uninstaller {}; the components page lists them in the order they appear.

Declares a section: a name and a body. The table form takes options beside the name — optional starts it unticked, required makes it untickable, installTypes puts it in the presets, description is its hover text. Leave the body out and the section is empty, as NSIS allows.

Usage section(name, body), section(name) or section { <name>, body = …, optional = …, required = …, installTypes = { … }, size = …, description = … }

installer {
section("Core", function()
setOutPath(INSTDIR)
file("assets/Example.exe")
writeUninstaller(INSTDIR .. "/uninstall.exe")
end),
section { "Start menu shortcut",
optional = true,
description = "Adds Example to the Start menu.",
body = function()
createDirectory(SMPROGRAMS .. "/Example")
createShortcut(SMPROGRAMS .. "/Example/Example.lnk", INSTDIR .. "/Example.exe")
end,
},
}

Groups sections under one collapsible heading on the components page. Ticking the heading ticks the children. A group can hold groups too. Takes description like a section does. Leave the sections out and the group is empty, as NSIS allows.

Usage group(name, { <section>, … }), group(name) or group { <name>, sections = { … }, expanded = …, description = … }

group("Extras", {
section("Documentation", function()
file("assets/manual.pdf")
end),
section { "Samples", optional = true, body = function()
file("assets/samples/*.example")
end },
})

The presets the components page offers, listed by name on the block. A section joins one through installTypes; there are no indices here.

Usage an installer’s or uninstaller’s installTypes = { <name>, … }

installer {
installTypes = { "Typical", "Full" },
page.components {},
page.instFiles {},
}

Which install types a section belongs to, by name, plus required for the untickable one.

Usage a section’s installTypes = { <name>, … } and required = <boolean>

installer {
installTypes = { "Typical", "Full" },
section { "Documentation",
installTypes = { "Full" },
body = function() file("assets/manual.pdf") end,
},
}

Adds kilobytes to a section’s reported size, for things the compiler cannot weigh — a download, a generated file, a database built on first run.

Usage a section’s size = <int> (kilobytes)

section { "Offline map data",
size = 240000,
body = function() exec(INSTDIR .. "/fetch-maps.exe") end,
}

The components page can start the way the user left it last time, through the Memento.nsh header that ships with NSIS. Each section to remember says remember = true, and its local becomes an id: the name of the registry value that stores its box. A section written inline has no local, so it gives the id as a string.

Usage a section’s remember = true, or remember = <id> (letters, digits and _)

attributes { name = "Example" }
local docs = section { "Documentation",
remember = true,
body = function() file("assets/manual.pdf") end,
}
installer {
page.components {},
page.instFiles {},
docs,
section { "Samples",
remember = "samples",
optional = true,
body = function() file("assets/samples/*.example") end,
},
}

On the first run optional decides, as it always does. On a later run the stored choice does, and a section that is new since then is drawn in bold. The choice is saved only when the install succeeds.

The boxes are stored under HKLM\Software\<name>\Components, with the name from attributes {}. Beside multiUser {} the root is SHCTX, so each mode keeps its own choice. A top-level memento {} changes either one:

Usage memento { root = <root>, key = <key> }, both optional

Keep the key and the ids the same from one version to the next, or the stored choices are forgotten. So when the product is renamed, write the old key with memento { key = "Software/OldName/Components" }. When a local is renamed, write its old name with remember = "oldname".

Only installer sections can remember. The compiler writes the header’s lines: MementoSectionEx and MementoSectionEnd around each remembered section, MementoSectionDone after the last one, MementoSectionRestore at the start of .onInit and MementoSectionSave at the start of .onInstSuccess, which it writes itself when the block has no onInstSuccess.

The restore goes first so that a docs.selected = false in onInit sticks. To restore later, after writing a saved state yourself, call memento.restore() at the top level of the installer’s onInit, and the compiler leaves out its own:

attributes { name = "Example" }
local docs = section { "Documentation",
remember = true,
body = function() setOutPath(INSTDIR) end,
}
installer {
page.components {},
page.instFiles {},
docs,
onInit(function()
writeReg(HKLM, "Software/Example/Components", "MementoSection_docs", 1)
memento.restore()
end),
}

Sections the user picks between, as radio buttons: ticking one unticks the one that was ticked, and unticking it ticks it again. The first section listed is the one ticked at the start, so mark the others optional. Compiled through the Sections.nsh header that ships with NSIS.

Usage a radioButtons { <section>, … } entry of installer {} or uninstaller {}, listing two or more of that block’s sections

local small = section("Small", function() end)
local large = section { "Large", optional = true, body = function() end }
installer {
page.components {},
page.instFiles {},
small,
large,
radioButtons { small, large },
}

The compiler writes the header’s StartRadioButtons, RadioButton and EndRadioButtons at the start of .onSelChange, which it writes itself when the block has no onSelChange, and the starting section into a Var in .onInit.

Reading and changing a section while it runs

Section titled “Reading and changing a section while it runs”

Your installer reaches a section through the handle section(…) gives back, rather than by counting positions. group(…) gives back the same kind of handle. These eight NSIS commands all become fields on it:

NSIS Installua
SectionGetText / SectionSetText handle.text — read and write
SectionGetFlags / SectionSetFlags handle.selected — read and write, a boolean
SectionGetSize / SectionSetSize handle.size — read and write
SectionGetInstTypes handle.installTypes(name) → boolean — a membership question, because NSIS stores it as a bit field and this language has no list to decode it into
SectionSetInstTypes handle.installTypes = { … }
local core = section("Core", function()
file("assets/Example.exe")
end)
installer {
core,
page.components {},
page.instFiles {},
onInit(function()
core.text = "Core files"
core.selected = true
end),
}

By name, rather than by the number NSIS uses. Covers GetCurInstType, SetCurInstType, InstTypeGetText and InstTypeSetText.

Usage currentInstType → string, currentInstType = <name>, instTypes.getText(name) → string, instTypes.setText(name, text)

installer {
installTypes = { "Typical", "Full" },
onInit(function()
currentInstType = "Full"
instTypes.setText("Full", "Everything")
end),
}

Writes the uninstaller executable, built from the uninstaller {} block. Call it from a section — usually the first — after setOutPath.

Usage writeUninstaller(path) → nothing

writeUninstaller(INSTDIR .. "/uninstall.exe")