言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

NSIS インストーラの研究

われながら力作なので http://metatoys.org/pub/sqland2005j/squeakland05.nsihttp://metatoys.org/pub/sqland2005j/SqueakPluginInstaller.exe に晒す。まだもうちょっと調整したいな。

今までのスクイーク日本語版では、VisualStudio、NSIS、VISE と色々なツールでインストーラを作ってきた。年末に新たに Squeakland 2005J を出すにあたって、機能と自由度を兼ね備えた NSIS の動作をもう少し勉強してみる。

NSIS とは、スクリプトベースのインストーラ作成ツールで、テキストエディタで書いたスクリプトを「コンパイル」して exe 形式のインストーラを作成する。独自のスクリプト言語を覚える必要があるのだが、これがちょっと昔のマクロ言語のような文法で結構難儀する。単にインストーラを作るだけなら、HM NIS Edit という贅沢なツールを併用すれば簡単なのだが、色々と必要な物があるので地道に直接スクリプトを書いてゆく事にする。

必要な物

UI の選定

ややこしい事に、今風のインストーラを作ろうとすると二つのマニュアルを読む必要がある。NSIS Users Manual と NSIS Modern User Interface だ、Modern UI は NSIS スクリプトで記述されているはずなんだけど色々約束事があって独立した解説が別に設けられている。動作を理解するためにはサンプルの Modern UI\Basic.nsi あたりを参考にしてゆけばよい。

変数

変数はグローバルで、セクションもしくは関数内で使える。長さは 1024 文字まで。使える文字は英数字と_。Var 変数名 で宣言。$変数名 で利用。あらかじめ用意されている定数も同じく $定数名 で使う。

スクリプトの構成

スクリプトの中身は、地の文、Page 定義、Section 定義、Function 定義を書く。地の文はマクロ等定義、Page は画面構成、Section はインストールとアンインストール時に何をやるか、Function は Section から呼ばれるサブルーチンやコールバックになる。Function は関数とは違うので、いわゆる関数のような物を作りたいときには !macro を使う。

スタートメニューに登録する。

サンプルの Modern UI\StartMenu.nsi を参考に

; 最初に変数を二つ定義
; Variables 
  Var MUI_TEMP
  Var STARTMENU_FOLDER

; ページ定義でレジストリに何かを保存
; Start Menu Folder Page Configuration
  !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU" 
  !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\${Product}" 
  !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
  !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER

; インストールセクションの中でショートカット定義を MUI_STARTMENU_WRITE_BEGIN で挟む
; Start Menu Folder Page Configuration
  !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
    CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
    CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
    CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\${Product}.lnk" "$INSTDIR\Squeak.exe" "${Product}.image"
  !insertmacro MUI_STARTMENU_WRITE_END

; アンインストールセクションの中で削除
  !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
  RMDir /r "$SMPROGRAMS\$MUI_TEMP"

デスクトップアイコン

; インストールセクションでアイコン作成
  CreateShortCut "$DESKTOP\${Product}.lnk" "$INSTDIR\squeak.exe" "${Product}.image"

; アンインストールセクションでアイコン削除
  Delete "$DESKTOP\${Product}.lnk"

.image .pr の関連付け

関連付けとは、レジストリの HKCR (HKEY_CURRENT_ROOT) に以下を書き込む事(情報源忘れました)。そしてアンインストール時に削除する。本当はバックアップして戻すのが正しいやり方だが、面倒なので今回保留。登録には WriteRegStr 削除には DeleteRegKey を使う。

; 登録時

  ; File Extension
  WriteRegStr HKCR ".image" "" "SqueakNihongo.Image"
  WriteRegStr HKCR "SqueakNihongo.Image" "" "SqueakNihongo Image"
  WriteRegStr HKCR "SqueakNihongo.Image\shell" "" "open"
  WriteRegStr HKCR "SqueakNihongo.Image\DefaultIcon" "" "$INSTDIR\Squeak.exe,0"
  WriteRegStr HKCR "SqueakNihongo.Image\shell\open\command" "" '$INSTDIR\Squeak.exe "%1"'
  
  WriteRegStr HKCR ".pr" "" "SqueakNihongo.Project"
  WriteRegStr HKCR "SqueakNihongo.Project" "" "SqueakNihongo Project"
  WriteRegStr HKCR "SqueakNihongo.Project\shell" "" "open"
  WriteRegStr HKCR "SqueakNihongo.Project\DefaultIcon" "" "$INSTDIR\Squeak.exe,0"
  WriteRegStr HKCR "SqueakNihongo.Project\shell\open\command" "" '"$INSTDIR\Squeak.exe" "$INSTDIR\${Product}.image" "%1"'

;; 削除時

  ; File Extension
  DeleteRegKey HKCR ".image"
  DeleteRegKey HKCR "SqueakNihongo.Image"
  DeleteRegKey HKCR ".pr"
  DeleteRegKey HKCR "SqueakNihongo.Project"

Netscape Mozilla Firefox Operaプラグイン

以下の場所にアプリケーションのフルパスが書いてあるので書いてあったら
NPSqueak.dll をコピーする。

HKLM SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\netscp.exe Path
HKLM SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\netscape.exe Path
HKLM Software\Microsoft\Windows\CurrentVersion\App Paths\Mozilla.exe Path
HKLM Software\Microsoft\Windows\CurrentVersion\App Paths\firefox.exe Path
HKLM SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Opera.exe Path

以下のレジストリを登録

HKCU "Software\Squeak" "InstallDirectory" $INSTDIR
HKLM "Software\Squeak" "InstallDirectory" $INSTDIR

IEプラグイン

DLL を登録/削除するだけです。

;登録時
RegDLL "$INSTDIR\SqueakOCX.dll"
;削除時
UnRegDLL "$INSTDIR\SqueakOCX.dll"

メモ

  • $名前 で変数名、${名前} で引数か define 名、$(名前) で多言語文字列。
  • !include - 標準で ${NSISDIR}\Include 以下のファイルを読み込む。
  • Name - 製品名を指定する。
  • OutFile - 最後に生成するインストーラの exe ファイル名の指定。
  • InstallDir - インストール先の指定。
  • InstallDirRegKey - もしレジストリにキーがあれば InstallDir として使う。
  • !define - フラグを定義する。コマンドラインで /D で定義する物と同じ。
  • !insertmacro - !macro で定義したマクロを挿入。
  • !macro - !macro パラメータ名 から !macroend まででマクロを定義。パラメータは ${パラメータ名} で使う。
  • Section - SectionEnd までセクションの定義
  • Page / PageEx - 画面構成を定義、Modern UI では !insertmacro MUI_PAGE_ の中で定義されるため開発者には見えない。
  • Section - 引数はセクション名とセクションID???
  • SetOutPath - 出力場所 $OUTDIR の指定。普通はただ "$INSTDIR" と書く。
  • WriteRegStr - レジストリ書き込み。指定の仕方はヘルプの WriteRegExpandStr 参照。
  • WriteUninstaller - アンインストーラ書き込み。
  • LangString 名前 言語ID 文字列 - 多言語文字列の指定。使うときは $(名前)。
  • IfErrors - エラーフラグがセットされていれば解除してジャンプ
  • CreateShortCut - ショートカットの作成
  • $PROGRAMFILES - Program Files ディレクトリの場所
  • $DESKTOP - デスクトップの場所