NSISで作るインストーラーのチートシート

[NSIS(Nullsoft Installer Script)](http://nsis.sf.net/)とは、その名の通りインストーラーを作るための言語である。今となってはVisual Studioに標準でデプロイツールなどが出ていることからあまり需要はないと思うけど、一応書いておく。

ここでは、[Ultra ModernUI](http://ultramodernui.sf.net/)を用いてリッチなUIを使用したインストーラーを作ってみよう。

```nsis
; o-----------------------------------------------o
; | ○○○○のインストーラー                           |
; (-----------------------------------------------)
; | インストーラースクリプト。                      |
; | 著者：Logue                                   |
; o-----------------------------------------------o

;--------------------------------
;全般設定
    ; 多言語で使用する場合はここをUnicodeにすることを推奨
    Unicode true

    ; インストーラーのアイコン
    !define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\nsis3-install.ico"
    ; アンインストーラーのアイコン
    !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\nsis3-uninstall.ico"

    ; 使用する外部ライブラリ
;    !include "MUI2.nsh"    ; ModernUIを使用する場合
    !include "Sections.nsh" ; セクション（カテゴリ分けする場合必須）
    !include "UMUI.nsh"     ; UltraModernUIを使用する場合
    !include LogicLib.nsh   ; IF～ELSE～ENDIFのような条件式やSwitch文を使用する場合

    ; インストーラーの識別子
    !define PRODUCT_NAME "○○○○"
    ; インストーラーのバージョン。
    !define PRODUCT_VERSION "0.0.0.0"

    ; 圧縮設定。通常は/solid lzmaが最も圧縮率が高い
    SetCompressor /solid lzma

    ; インストーラー名
    Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
    ; 出力されるファイル名
    OutFile "Setup ${PRODUCT_NAME}.exe"

    ; インストール時の進捗画面で実行している処理のメッセージを表示する（何を解凍したかなど）
    ShowInstDetails show
    ; アンインストール時の進捗画面で実行している処理のメッセージを表示する（何を削除したかなど）
    ShowUnInstDetails show

    ; バージョン表記
    VIProductVersion ${PRODUCT_VERSION}"
    VIAddVersionKey ProductName "なんとかのインストーラー"
    VIAddVersionKey ProductVersion "${PRODUCT_VERSION}"
    VIAddVersionKey Comments "インストーラーの説明文"
    VIAddVersionKey LegalTrademarks "通常はライセンスを入力"
    VIAddVersionKey LegalCopyright "著作権表記"
    VIAddVersionKey FileDescription "インストーラーの説明文"
    VIAddVersionKey FileVersion "${PRODUCT_VERSION}"

    ; デフォルトのファイルのインストール先。
    ; この設定ではインストーラーと同じディレクトリが選択される。
    InstallDir $EXEDIR

    ; これは権限設定。ここをadminにするとUACが表示される。
    RequestExecutionLevel user

;--------------------------------
;インターフェース設定
    ; インストーラーの左側に表示する画像
    ; ${NSISDIR}はNSISのインストール先のパスが入っている。
    !define MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\nsis3-metro.bmp"
    !define MUI_ABORTWARNING

    ; 説明文のボックスを小さくする
    !define MUI_COMPONENTSPAGE_SMALLDESC
    ; チェックボックスやボタンを装飾する
    !define UMUI_USE_INSTALLOPTIONSEX

    ; インストーラーがインストール情報を格納する使用するレジストリーキー
    !define UMUI_PARAMS_REGISTRY_ROOT HKCU 
    !define UMUI_PARAMS_REGISTRY_KEY "Software\${PRODUCT_NAME}"
    ; インストール先のレジストリーキーの名前
    !define UMUI_INSTALLDIR_REGISTRY_VALUENAME "InstallDir"
    ; インストーラーの言語のレジストリーキーの名前
    !define UMUI_LANGUAGE_REGISTRY_VALUENAME "Language"

    !define UMUI_USE_ALTERNATE_PAGE

    ; 言語選択画面を常に出す
    !define UMUI_LANGUAGE_ALWAYSSHOW
    ; 左に表示するインストーラー画像を表示しない
    !define UMUI_NOLEFTIMAGE

;--------------------------------
;インストーラーウィザード設定
    ; 言語選択ページ
    !insertmacro UMUI_PAGE_MULTILANGUAGE
    ; ようこそページ
    !insertmacro MUI_PAGE_WELCOME
        ; 「ライセンスに同意する」をラジオボタンにする
        !define MUI_LICENSEPAGE_RADIOBUTTONS
    !insertmacro MUI_PAGE_LICENSE "ライセンスファイル（テキストか、リッチテキスト形式）のパス"
        ; インストール先の変数名
        !define MUI_PAGE_DIRECTORY_VARIABLE $APPDIR
    ; インストール先選択画面
    !insertmacro MUI_PAGE_DIRECTORY
    ; インストール項目選択画面
    !insertmacro MUI_PAGE_COMPONENTS
    ; インストールの進捗画面（詳細テキストはこの画面で表示される）
    !insertmacro MUI_PAGE_INSTFILES
        ; インストール完了後自動的に完了画面に遷移しないようにする
        !define MUI_FINISHPAGE_NOAUTOCLOSE
    ; インストール完了画面
    !insertmacro MUI_PAGE_FINISH

    ; アンインストーラーの言語選択ページ（初期状態でインストール時にレジストリに記載した値が選択されている）
    !insertmacro UMUI_UNPAGE_MULTILANGUAGE
    ; アンインストーラーのようこそ画面
    !insertmacro MUI_UNPAGE_WELCOME
    ; アンインストーラーの確認画面
    !insertmacro MUI_UNPAGE_CONFIRM
    ; アンインストーラーの進捗画面
    !insertmacro MUI_UNPAGE_INSTFILES
        ; annインストール完了後自動的に完了画面に遷移しないようにする
        !define MUI_UNFINISHPAGE_NOAUTOCLOSE
    ; アンインストール完了画面
    !insertmacro MUI_UNPAGE_FINISH

; 言語ファイル
    !insertmacro MUI_LANGUAGE "English"
    !insertmacro MUI_LANGUAGE "Japanese"

; 予約ファイル
    ; /solidオプションを追加したときにデーターブロックの最初におかれるファイルを指定する。
    ; MUIを使う場合は下記行をコメントアウトする。（UMUIを使用するときは不要）
    ;!insertmacro MUI_RESERVEFILE_LANGDLL

; MUI end ------

; マクロ
; この例では、詳細画面でインストールしている項目を表示するのに使用する。
; 使用方法は、!insertmacro PrintSection セクション名 サブセクション名。
; NSISではIf文は本来使えないが、LogicLib.nshを読み込ませることで近いことができるようになうる。
!macro PrintSection Section SubSection
    ${If} "${SubSection}" == ""
        DetailPrint "$(INSTALLING_STR_1)${Section}$(INSTALLING_STR_3)"
    ${Else}
        DetailPrint "$(INSTALLING_STR_1)${Section}$(INSTALLING_STR_2)${SubSection}$(INSTALLING_STR_3)"
    ${EndIf}
!macroend

;言語設定
    ; 英語
    LangString DISSELECT ${LANG_ENGLISH} "No install"
    LangString INSTALLING_STR_1 ${LANG_ENGLISH} "Installing "
    LangString INSTALLING_STR_2 ${LANG_ENGLISH} " "
    LangString INSTALLING_STR_3 ${LANG_ENGLISH} "..."
    ; 日本語
    LangString DISSELECT ${LANG_JAPANESE} "インストールしない"
    LangString INSTALLING_STR_1 ${LANG_JAPANESE} ""
    LangString INSTALLING_STR_2 ${LANG_JAPANESE} "の"
    LangString INSTALLING_STR_3 ${LANG_JAPANESE} "をインストールしています…。"

;--------------------------------
;インストール項目設定

Section "セクション１" SEC01
    ; 上書きを許可
    SetOverwrite on
    ; インストール先を指定
    SetOutPath "$INSTDIR"
    !insertmacro PrintSection "セクション１" ""
    ; インストールするファイル。data\*のようなワイルドカードも指定可能
    File "インストールしたいファイルへのパス"
SectionEnd

; セクショングループは配下のセクションをまとめるのに使う。
; セクショングループの中に子セクショングループを作ることも可能だが、おすすめしない。
SectionGroup "セクショングループ１" SEC02
    Section "サブセクション１" SEC02_1
        !insertmacro PrintSection "セクショングループ１" "サブセクション１"
        File "インストールしたいファイルへのパス"
    SectionEnd

    ; この/oスイッチは、初期状態で選択しないオプション項目。optionalの意味
    Section /o "サブセクション２" SEC02_2
        !insertmacro PrintSection "セクショングループ１" "サブセクション２"
        File "インストールしたいファイルへのパス"
    SectionEnd
SectionGroupEnd

; この/eスイッチは、常に配下のセクションを表示した状態にする。expandの意味。
SectionGroup /e "セクショングループ２" SEC02
    Section "サブセクション３"
    ; 略
    SectionEnd
SectionGroupEnd

; セクション名の先頭に-を追加すると、常にインストールされる項目になる。
; 通常は以下のようにレジストリの記入やアンインストーラーの設置などを入力する
Section -Post
    WriteUninstaller "$INSTDIR\Uninstall ${PRODUCT_NAME}.exe"
    WriteRegStr HKCU "Software\${PRODUCT_NAME}" "" $INSTDIR
SectionEnd

;--------------------------------
;インストーラーの関数

; インストーラー起動時の処理。スプラッシュ画面などもここで指定。
Function .onInit
    ; UMUIで言語選択画面を使用する場合必須
    !insertmacro UMUI_MULTILANG_GET
    ; 最初に選択状態にするセクション名を変数$1に割り当てる。
    StrCpy $1 ${SEC02_1}
FunctionEnd

; セクションの選択が変わったときの処理
Function .onSelChange
    ; ここではセクショングループ内のセクションを排他選択（ラジオボタンにする）
    !insertmacro StartRadioButtons $1
        !insertmacro RadioButton ${SEC02_1}
        !insertmacro RadioButton ${SEC02_2}
    !insertmacro EndRadioButtons
FunctionEnd

; セクションの説明文を入力
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
    !insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "セクション１の説明"
    !insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "セクショングループ１の説明"
    !insertmacro MUI_DESCRIPTION_TEXT ${SEC02_1} "サブセクション１の説明"
    !insertmacro MUI_DESCRIPTION_TEXT ${SEC02_2} "サブセクション２の説明"
    !insertmacro MUI_DESCRIPTION_TEXT ${SEC03} "セクショングループ２の説明"
!insertmacro MUI_FUNCTION_DESCRIPTION_END

;--------------------------------
;アンインストーラーの説明

Function un.onInit
    ; UMUIで言語選択画面を使用する場合必須
    !insertmacro UMUI_MULTILANG_GET
FunctionEnd

;--------------------------------
;アンインストーラーの設定

Section Uninstall
    Delete "$INSTDIR\Uninstall ${PRODUCT_NAME}.exe"
    ; これは見境なしにdataディレクトリ内のファイルを削除してしまう悪い見本。
    Delete "$INSTDIR\data\*"
    ; ディレクトリを削除する。ファイルが残っている場合は実行されない。
    RMDir "$INSTDIR\data"
    ; インストーラーが使用したレジストリーキーを削除する
    DeleteRegKey "Software\${PRODUCT_NAME} ""
SectionEnd
```