InstallOptions 2

InstallOptions 插件已落伍了。新编写的脚本,推荐使用新的 nsDialogs 插件来替代。

介绍

InstallOptions 是一个可以创建自定义安装程序页面的 NSIS 插件,它可以提供一些额外的信息。

InstallOptions 在 NSIS 窗口内所创建的对话框的所有控件及其属性由 INI 文件定义。这些 INI 文件可被脚本修改进而实时地调整对话框。

INI 文件的格式描述就在 Wikipedia article

INI 文件结构

这个 INI 文件有一个必需的区段。这个区段包含了要创建的控件的数量和常规的窗口属性。INI 文件也包含了一些带变量的 Field x 区段用来定义要创建的控件及其属性。

该必须的区段名为 "Settings"。其可以包含下列值:

NumFields (必需) 对话框窗口上要显示的控件数量。
Title (可选) 如果指定,则设置标题栏文本,否则保持不变。
CancelEnabled (可选) 如果指定,将会取代 NSIS 的设置并允许或禁止取消按钮。如果设为 1,取消按钮被允许。如果设为 0,取消按钮被禁止。
CancelShow (可选) 如果指定,将会取代 NSIS 的设置并显示或隐藏取消按钮。如果设为 1,取消按钮被显示。如果设为 0,取消按钮被隐藏。
BackEnabled (可选) 如果指定,将会取代 NSIS 的设置并允许或禁止上一步按钮。如果设为 1,上一步按钮被允许。如果设为 0,上一步按钮被禁止。
CancelButtonText (可选) 取代取消按钮的文本,如果未指定取消按钮的文本保持不变。
NextButtonText (可选) 取代下一步按钮的文本,如果未指定下一步按钮的文本保持不变。
BackButtonText (可选) 取代上一步按钮的文本,如果未指定上一步按钮的文本保持不变。
Rect (可选) 取代默认的矩形 ID。这会使得 IO 重新调整它本身对话框窗口的大小。
RTL (可选) 如果指定为 1 则所有对话框文本将显示为从右至左文本。如果需要支持从右至左文本(比如阿拉伯文)你可以使用 NSIS 的 $(^RTL) 变量来填写该值。
State (输出) 这个值不是由你来提供而是由 InstallOptions 在调用你的自定义页面确认函数之前来设置的,提供了一些控件的状态信息,比如按钮(或其它带有 Notify 标记的控件)被点击了。

每个区段都为 "Field #" 形式,这里 # 是一个从 1 到 NumFields 的连续的数字。每一个区段可以包含下列值:

Type (必需) 要创建的控件的类型。有效的值为 Label, Text, Password,Combobox, DropList, Listbox, CheckBox, RadioButton,FileRequest, DirRequest, Icon, Bitmap, GroupBox, LinkButton

Label 用来显示静态文本。
TextPassword 接受用户的文本输入。"Password" 则把输入显示为 * 字符。
Combobox 使用户可以直接输入不在列表里的文字,"Droplist" 只能从列表项里选择。
Listbox 显示了多项并可以选择多个项。
CheckBox 显示了带文本的复选框。
RadioButton 显示了带文本的单选框。
FileRequest 显示文本框和浏览按钮。点击浏览按钮将显示文件打开对话框使用户可以从中选择文件。
DirRequest 显示文本框和浏览按钮。点击浏览按钮将显示目录打开对话框使用户可以从中选择目录。
Icon 显示图标。不带文本可以显示安装程序图标。
Bitmap 显示位图。
GroupBox 显示一组控件的框架。
HLine 显示一条水平线段以隔开其它控件。
VLine 显示一条垂直线段以隔开其它控件。
Link 显示一个静态的链接。当用户点击控件时,State 指定的内容将被其关联程序执行(如 http://)。作为选择 State 也可以联合 NOTIFY 标记来使用 NSIS 回调。查看下面的 NOTIFY 标记以了解更多信息。
Button 显示按钮,可以执行类似上面的 "Link" 控件的功能。
Text (可选) 指定 label, checkbox, 或 radio button 控件的标题。对于 DirRequest 控件则指定浏览对话框的标题。对于 icon 和 bitmaps 控件则指定图像的路径。

注意: 对于 label,\r\n 将被转换为新行。若要在文本里使用反斜杠 \ 请使用 \\ 来转义。下面 有一个函数可以进行这些文本的转换。
State (可选) 控件的状态。当用户关闭窗口时会更新,所以你可以从 NSIS 里读取该项内容。对于编辑框和目录选择框、文件选择框来说保存的字串指示了内容。对于互斥按钮或单选框,可能是 0 或 1 (对应于选择或未选择)。对于列表框,组合框或下拉列表框来说这是所选择的内容,由 | 进行分隔。对于链接和按钮来说这里可以指定要被执行或被打开的对象(使用其关联程序)。

注意: 对于带 MULTILINE 标记的文本段,\r\n 将会被转换为换行符。若要使用 \, 你应该用 \\ 来进行转义。下面 有一个函数可以进行这些文本的转换。
ListItems (可选) 用来初始化列表框、组合框、下拉列表框的内容。使用单行字串并使用 | 来分隔每一项。
MaxLen (可选) 使得选择的控件限制最大的文本长度。如果用户选择的文本大于该限制,则当他们点确定的时候会出现一个消息框提示并且对话框不会结束。
你不应该用在组合框中,因为用户无法控制其选择的对象。
应该用在 FileRequestDirRequest 里用来限制最大的路径长度为 260。
会被 Label 控件忽略。
MinLen (可选) 使得选择的控件限制最小的文本长度。如果用户选择的文本小于该限制,则当他们点确定的时候会出现一个消息框提示并且对话框不会结束。
不像 MaxLen,这在组合框中非常有用。如果把这一项设为 1 的话程序就会强制用户至少选择一项。
会被 Label 控件忽略。
ValidateText (可选) 如果某一个 Field 在测试上面的 MinLenMaxLen 时达到了限制的条件,那么就会出现一个消息框显示这个文本。

注意: \r\n 将会被转换为换行符。要使用 \ 你应该用 \\ 来进行转义。
Left
Right
Top
Bottom
(必需) 各个控件出现在对话框里的位置。所有的尺寸单位均使用对话框里的单位。要获取你想知道的的控件的正确尺寸,你可以使用资源编辑器来设计你的对话框并把尺寸复制到 INI 文件。

注意: 你可以指定负值,这表示距离是从右端或底部算起。

注意 (2): 对于组合框或下拉列表框,bottom 值的意义稍微不同。
在这种情况下。底部的值表示下拉时所能显示的窗口的最大尺寸。通常来说,组合框会自动地调整大小到一个元素高度。如果你碰到了组合框下拉时看不到列表的时候你应该检查 bottom 值是否有足够的大小。粗略的估计所需要的高度时列表项数目乘以 8 加 20。

注意 (3): FileRequest 和 DirRequest 控件会分配 15 个对话框单位给浏览按钮。请确认控件的宽度足够显示按钮文本内容。
Filter (可选) 指定 FileRequest 控件所用的过滤条件。
这是成对出现的,每一项由 | 分隔。
每一对的第一个值是过滤条件显示的文本。
第二个值是用来匹配文件的模式。
例如,你可以指定:
Filter=文本文件|*.txt|程序|*.exe;*.com|所有文件|*.*
如果没有指定,则使用默认的 所有文件|*.*

注意: 在 | 分隔符的两旁不应该有多余的空格。
Root (可选) DirRequest 控件用来指定浏览时的根目录。默认值是允许用户浏览电脑里的任何目录。指定这个值可以限制只能在特定的目录里浏览。
Flags (可选) 对于不同的控件显示这个值指定了额外的标记。每一个标记需要用 | 来分隔,并且需要注意 | 的两旁不能有多余的空格。
意义
REQ_SAVE 使得 FileRequest 控件显示为保存文件对话框。如果不指定则是打开文件对话框。
FILE_MUST_EXIST 用于 FileRequest 来检测选择的文件是否必须存在。
仅应用在打开文件对话框时。
它通常不会强制文件必须存在但除了使用浏览按钮。
FILE_EXPLORER 用于 FileRequest 使用新的文件请求外观(推荐)。
FILE_HIDEREADONLY 用于 FileRequest,在打开文件对话框里隐藏“仅打开只读文件”单选框。
WARN_IF_EXIST 用于 FileRequest ,当选择的文件不存在时显示一个警告信息。
这个警告信息仅在通过浏览按钮选择文件是显示。
PATH_MUST_EXIST 用于 FileRequest 来强制路径必须存在。这可以阻止用户在浏览对话框窗口里输入一个无效的路径。
仅在通过浏览按钮选择时有效。
PROMPT_CREATE 用于 FileRequest ,当选这里一个不存在的文件时显示一个警告。但是,它仍然允许用户选择文件。
仅在通过浏览按钮选择时有效。
不能和 REQ_SAVE 一起使用。
RIGHT 用于 CheckboxRadiobutton 控件来指定选择按钮是左对齐还是右对齐。默认是左对齐。
MULTISELECT 用于 Listbox 控件。是否允许用户点击或双击列表框里的字串来选择多项。如果指定了这个标记或 EXTENDEDSELCT 标记时用户可以选择多项,否则每次只能选择一项。
EXTENDEDSELCT 用于 Listbox 控件。允许通过 SHIFT 健和鼠标或特殊的组合键来选择多项。如果未指定这个标记和 MULTISELECT 的话每次只能选择一项。
RESIZETOFIT 这个标记使得 Bitmap 控件重新调整图象的大小来适合控件的大小。对于支持自定义 DPI 设置非常有用。不指定的话图像只能居中显示。
TRANSPARENT 用于 Bitmap 控件。隐藏和左上方相同颜色的像素。这使得控件看上去就像在后面出现的一样。这个标记和 RESIZETOFIT 组合使用且位图多于 256 种颜色时不太好。
GROUP 添加该标记到需要成组控件的第一个控件上使他们成为一组控件。成组的控件使你可以创建多个互斥按钮并可以方便的使用键盘上下键来选择。
NOTABSTOP 当用户按 Tab 键时不要停止在控件上。把这个标记添加到一组控件上除了第一个控件,这可以使按 Tab 键时一次性跳过该组。
DISABLED 禁用该控件。
ONLY_NUMBERS 用于 Text 控件。强制用户只能在编辑框里输入数字。
MULTILINE 用于 Text 控件。使控件接受多行文本。
WANTRETURN 用于多行 Text 控件。指定当用户按下回车键时插入一个回车符。
NOWORDWRAP 用于多行 Text 控件。禁止自动换行。
HSCROLL 显示水平滚动条。当用于多行 Text 控件时也会禁止自动换行。
VSCROLL 显示垂直滚动条。
READONLY 用于 Text 控件。不允许用户从编辑框输入内容但是可以读取或复制。
NOTIFY 用于 Button, Link,CheckBox, RadioButton, ListBoxDropList 控件。当控件的选择更改或按钮被点击时使得 InstallOptions 调用 NSIS 自定义页面的离开函数。你的离开函数可以从 Setting 区段里读取 State 值来检测是哪一个控件产生了这个通知事件。需要时你可以在执行某些操作后再调用 Abort 指令(使得 NSIS 返回到该页面)。Examples\InstallOptions 文件夹里包含了如何使用这个标记的示例。
TxtColor (可选) 用于 Link 控件来指定文本的前景色。格式为: 0xBBRRGG (十六进制)。
HWND
HWND2
(输出) 在 initDialog 返回后,包含了这个字段创建的控件的句柄。可以用来代替 FindWindow 和 GetDlgItem。HWND2 包含了附加控件的句柄,比如浏览按钮。

头文件

InstallOptions 头文件提供了宏和函数以便于创建自定义对话框。你可将其插入到你的脚本的开头部分:

!include InstallOptions.nsh

创建对话框

    释放 INI 文件

    首先,你需要在 .onInit 函数(或卸载程序的 un.onInit) 里使用宏 INSTALLOPTIONS_EXTRACT 把对话框的 INI 文件释放出来。文件将被释放到一个自动创建的临时文件夹(NSIS 插件文件夹)中。

    Function .onInit
      !insertmacro INSTALLOPTIONS_EXTRACT "ioFile.ini"
    FunctionEnd
    

    若 INI 文件在另外的文件夹中,使用 INSTALLOPTIONS_EXTRACT_AS。 其第二个参数是临时文件夹中的文件名称,其它宏将要用该文件名称作为输入项。

    Function .onInit
      !insertmacro INSTALLOPTIONS_EXTRACT_AS "..\ioFile.ini" "ioFile.ini"
    FunctionEnd
    

    显示对话框

    你可以在 Page 或 UninstPage 命令定义的页面函数里调用 InstallOptions。关于页面系统的更多信息请查看 NSIS 文档。

    Page custom CustomPageFunction
    

    要显示对话框,使用宏 INSTALLOPTIONS_DISPLAY:

    Function CustomPageFunction ;函数名称用 Page 命令定义
      !insertmacro INSTALLOPTIONS_DISPLAY "ioFile.ini"
    FunctionEnd

用户输入

要获取用户的输入,可以用宏 INSTALLOPTIONS_READ 来读取某个 Field 的 State 值:

!insertmacro INSTALLOPTIONS_READ $VAR "ioFile.ini" "Field #" "Name"

写入 INI 文件

宏 INSTALLOPTIONS_WRITE 允许你写入数值到 INI 文件以实时地修改文本或控件设置:

!insertmacro INSTALLOPTIONS_WRITE "ioFile.ini" "Field #" "Name" "Value"

值的转义

一些 InstallOptions 的值已被转义(类似于 "C" 字串)来使得一些原本无效的特定字符可以在 INI 文件里使用。受影响的值为:

  • ValidateText 字段
  • Label 字段的 Text 值
  • 带有 MULTILINE 标记的 Text 字段的 State 值

转义符为反斜杠 (\),可用的转义字符如下:

"\\" 反斜杠
"\r" 回车 (ASCII 13)
"\n" 换行 (ASCII 10)
"\t" Tab (ASCII 9)

在安装代码中宏 INSTALLOPTIONS_READ_CONVERT 和 INSTALLOPTIONS_WRITE_CONVERT 会自动转换这些字符。在卸载代码中使用宏 INSTALLOPTIONS_READ_UNCONVERT 和 INSTALLOPTIONS_WRITE_UNCONVERT。

要在脚本中使用这些宏,必须包含转换函数:

;对于 INSTALLOPTIONS_READ_CONVERT
  !insertmacro INSTALLOPTIONS_FUNCTION_READ_CONVERT
;对于 INSTALLOPTIONS_WRITE_CONVERT
  !insertmacro INSTALLOPTIONS_FUNCTION_WRITE_CONVERT
;对于 INSTALLOPTIONS_READ_UNCONVERT
  !insertmacro INSTALLOPTIONS_UNFUNCTION_READ_CONVERT
;对于 INSTALLOPTIONS_WRITE_UNCONVERT
  !insertmacro INSTALLOPTIONS_UNFUNCTION_WRITE_CONVERT

输入验证

要验证用户输入(例如要检测用户是否填写了某个文本框),可使用 Page 命令的离开函数并在验证失败时使用 Abort 命令:

Function ValidateCustom

  !insertmacro INSTALLOPTIONS_READ $R0 "test.ini" "Field 1" "State"
  StrCmp $R0 "" 0 +3
    MessageBox MB_ICONEXCLAMATION|MB_OK "请输入你的大名!"
    Abort

FunctionEnd

返回值

一个对话框被创建(使用 display 或 show)后,可能的返回值为:

  • success - 用户按了下一步按钮
  • back - 用户按了上一步按钮
  • cancel - 用户按了取消按钮
  • error - 发生了一个错误,对话框无法显示

仅当你需要做某些特别的事情时才需要去检测返回值,比如当用户按了上一步按钮时要做些什么事情。

如果你需要返回值,使用宏 INSTALLOPTIONS_DISPLAY_RETURN 和 INSTALLOPTIONS_SHOW_RETURN。返回值将会被添加到堆栈,你可以使用 Pop 命令来提取它。

保留文件

如果你使用了固实压缩,很重要的一点是在页面初始化阶段或页面函数里需要释放的文件,应当放在数据区块中的位置就应当放在其它文件的前面。否则,会使某个页面在显示时会有所延误。

要确保这一点,请在所有区段和函数之前添加 InstallOptions 和 INI 文件的 ReserveFile 命令:

ReserveFile "test.ini"
ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"

字体和颜色

要在 InstallOptions 对话框里使用自定义的字体和颜色,你可使用宏 INSTALLOPTIONS_INITDIALOG 和 INSTALLOPTIONS_SHOW。

INSTALLOPTIONS_INITDIALOG 会在内存里创建页面但不显示出来。在插入了此宏后,你可以设置字体和颜色,然后插入宏 INSTALLOPTIONS_SHOW 来显示对话框。

宏 INSTALLOPTIONS_INITDIALOG 也会将自定义对话框的 HWND 压进堆栈。每一个控件在 INI 文件各对应区段的 HWND 项中都有一个 HWND 值。

使用自定义颜色的例子:

Var HWND
Var DLGITEM
Var FONT

Function FunctionName ;函数名称已用 Page 命令定义

  !insertmacro INSTALLOPTIONS_INITDIALOG "ioFile.ini"
  Pop $HWND ;对话框的 HWND

  !insertmacro INSTALLOPTIONS_READ $DLGITEM "ioFile.ini" "Field 1" "HWND"

  ;变量 $DLGITEM 包含了第一个区段的 HWND
  CreateFont $FONT "Tahoma" 10 700 
  SendMessage $DLGITEM ${WM_SETFONT} $FONT 0

  !insertmacro INSTALLOPTIONS_SHOW

FunctionEnd

致谢名单

初始版本作者: Michael Bishop
DLL 版本作者:Nullsoft, Inc.
DLL 版本 2 作者:Amir Szekely、ORTIM、Joost Verburg
新版文档作者:Joost Verburg

新版文档翻译:陈敏毅@汉化后花园

许可协议

原创版本:版权所有 © 2001 Michael Bishop
DLL 版本:版权所有 © 2001-2002 Nullsoft,Inc.,ORTIM
DLL 版本 2:版权所有 © 2003-2008 Amir Szekely、Joost Verburg、Dave Laundon

本软件提供原则为“依其现状”,不提供明示或暗示的保证。作者不对任何因使用本软件而
引起的损害事件负责。

如果你同意下列条款,允许任何人、出于任何目的使用本软件,包括商业应用及二次发布:
1、这个软件的来源必须如实说明;你不能声称本软件是你编写。如果你发布的产品使用了
  本软件,在你的产品说明中对此进行说明,我们将非常感谢,但这不是必需的。
2、修改版必须有明确标识,并且不得宣称它是原创软件。
3、二次发布版不得移除此通告。(翻译应该是没有问题的吧 +_+)