Edited at

NSISでインストーラを作ってみる その2


はじめに

その1に引き続き、NSISのスクリプトをサンプルを用いてレクチャーします。

その1を読んでいない方は、以下から読んでください。

NSISでインストーラを作ってみる その1


アンインストールに確認を設ける

アンインストーラを実行した時に確認を取らずにアンインストールすると、うっかり操作ミスでアンインストールしてしまう危険性があります。

アンインストール前に確認の一手間を置いて、意図しないアンインストールを防ぎます。


Install.nsi

# 日本語UI

LoadLanguageFile "${NSISDIR}\Contrib\Language files\Japanese.nlf"
# アプリケーション名
Name "サンプル アプリケーション"
# 作成されるインストーラ
OutFile "Install.exe"
# インストールされるディレクトリ
InstallDir "$PROGRAMFILES\NSISSample"
# ページ
Page directory
Page instfiles
# アンインストーラ ページ
UninstPage uninstConfirm
UninstPage instfiles

# デフォルト セクション
Section
# 出力先を指定します。
SetOutPath "$INSTDIR"
# インストールされるファイル
File "C:\Sample\Sample.exe"
# 出力先を指定します。
SetOutPath "$INSTDIR\docs"
# インストールされるファイル
File "C:\Sample\docs\readme.txt"
# アンインストーラを出力
WriteUninstaller "$INSTDIR\Uninstall.exe"
# スタート メニューにショートカットを登録
CreateDirectory "$SMPROGRAMS\NSISSample"
SetOutPath "$INSTDIR"
CreateShortcut "$SMPROGRAMS\NSISSample\サンプル アプリケーション.lnk" "$INSTDIR\Sample.exe" ""
# レジストリに登録
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample" "DisplayName" "サンプル アプリケーション"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample" "UninstallString" '"$INSTDIR\Uninstall.exe"'
SectionEnd

# アンインストーラ
Section "Uninstall"
# アンインストーラを削除
Delete "$INSTDIR\Uninstall.exe"
# ファイルを削除
Delete "$INSTDIR\Sample.exe"
# ディレクトリを削除
RMDir /r "$INSTDIR"
# スタート メニューから削除
Delete "$SMPROGRAMS\NSISSample\サンプル アプリケーション.lnk"
RMDir "$SMPROGRAMS\NSISSample"
# レジストリ キーを削除
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample"
SectionEnd


001.png

アンインストーラを実行すると、確認のウィンドウが表示されます。

アンインストールしたくない場合は"キャンセル"をクリックすれば取り消すことができ、

アンインストールしてもよい場合は"アンインストール"をクリックすると、アンインストールされます。

※注意: UninstPage uninstConfirmだけでなく、UninstPage instfilesも記述しないと、アンインストールが実行されません。

又、Page uninstConfirmと記述してもコンパイルできますが、正しく機能しません。


LZMAで圧縮する

LZMAは7-Zipで用いられている非常に圧縮率の高い圧縮メソッドです。

大規模なアプリケーションをなるべく軽量にしたい時に効果を発揮しますが、

圧縮時間がトレードオフになっています。

又、解凍時のメモリ消費も大きめですが、現代的なスペックのマシンであれば特に問題にはならないでしょう。


Install.nsi

# 日本語UI

LoadLanguageFile "${NSISDIR}\Contrib\Language files\Japanese.nlf"
# アプリケーション名
Name "サンプル アプリケーション"
# 作成されるインストーラ
OutFile "Install.exe"
# インストールされるディレクトリ
InstallDir "$PROGRAMFILES\NSISSample"
# 圧縮メソッド
SetCompressor lzma
# ページ
Page directory
Page instfiles
# アンインストーラ ページ
UninstPage uninstConfirm
UninstPage instfiles

# デフォルト セクション
Section
# 出力先を指定します。
SetOutPath "$INSTDIR"
# インストールされるファイル
File "C:\Sample\Sample.exe"
# 出力先を指定します。
SetOutPath "$INSTDIR\docs"
# インストールされるファイル
File "C:\Sample\docs\readme.txt"
# アンインストーラを出力
WriteUninstaller "$INSTDIR\Uninstall.exe"
# スタート メニューにショートカットを登録
CreateDirectory "$SMPROGRAMS\NSISSample"
SetOutPath "$INSTDIR"
CreateShortcut "$SMPROGRAMS\NSISSample\サンプル アプリケーション.lnk" "$INSTDIR\Sample.exe" ""
# レジストリに登録
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample" "DisplayName" "サンプル アプリケーション"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample" "UninstallString" '"$INSTDIR\Uninstall.exe"'
SectionEnd

# アンインストーラ
Section "Uninstall"
# アンインストーラを削除
Delete "$INSTDIR\Uninstall.exe"
# ファイルを削除
Delete "$INSTDIR\Sample.exe"
# ディレクトリを削除
RMDir /r "$INSTDIR"
# スタート メニューから削除
Delete "$SMPROGRAMS\NSISSample\サンプル アプリケーション.lnk"
RMDir "$SMPROGRAMS\NSISSample"
# レジストリ キーを削除
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample"
SectionEnd



スクリプトを分割する

プロジェクトが大きくなってくると、インストーラを1つのファイルで管理すると複雑になってきます。

スクリプトをモジュールで分割してみます。


Install.nsi

# 日本語UI

LoadLanguageFile "${NSISDIR}\Contrib\Language files\Japanese.nlf"
# アプリケーション名
Name "サンプル アプリケーション"
# 作成されるインストーラ
OutFile "Install.exe"
# インストールされるディレクトリ
InstallDir "$PROGRAMFILES\NSISSample"
# 圧縮メソッド
SetCompressor lzma
# ページ
Page directory
Page instfiles
# アンインストーラ ページ
UninstPage uninstConfirm
UninstPage instfiles

# デフォルト セクション
Section
# 出力先を指定します。
SetOutPath "$INSTDIR"
# インストールされるファイル
File "C:\Sample\Sample.exe"
# 出力先を指定します。
SetOutPath "$INSTDIR\docs"
# インストールされるファイル
File "C:\Sample\docs\readme.txt"
# アンインストーラを出力
WriteUninstaller "$INSTDIR\Uninstall.exe"
# スタート メニューにショートカットを登録
CreateDirectory "$SMPROGRAMS\NSISSample"
SetOutPath "$INSTDIR"
CreateShortcut "$SMPROGRAMS\NSISSample\サンプル アプリケーション.lnk" "$INSTDIR\Sample.exe" ""
# レジストリに登録
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample" "DisplayName" "サンプル アプリケーション"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample" "UninstallString" '"$INSTDIR\Uninstall.exe"'
SectionEnd

# アンインストーラ
!include Uninstall.nsi



Uninstall.nsi

# アンインストーラ

Section "Uninstall"
# アンインストーラを削除
Delete "$INSTDIR\Uninstall.exe"
# ファイルを削除
Delete "$INSTDIR\Sample.exe"
# ディレクトリを削除
RMDir /r "$INSTDIR"
# スタート メニューから削除
Delete "$SMPROGRAMS\NSISSample\サンプル アプリケーション.lnk"
RMDir "$SMPROGRAMS\NSISSample"
# レジストリ キーを削除
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample"
SectionEnd

Uninstall.nsiというファイルを新たに作成し、アンインストーラ部を分割しました。

大きくなりすぎると管理が複雑になってしまう部分は、分割すると管理しやすくなります。


セクションの使い方

今まではSectionという項目はデフォルト セクションとアンインストーラ セクションの2つが存在していました。

NSISはセクションを使いこなす事によりフレキシブルなインストーラが作成できます。

ここでは、インストールするファイルに"C:\Sample\utils\Utility.exe"というファイルを新たに用意してみます。


Install.nsi

# 日本語UI

LoadLanguageFile "${NSISDIR}\Contrib\Language files\Japanese.nlf"
# アプリケーション名
Name "サンプル アプリケーション"
# 作成されるインストーラ
OutFile "Install.exe"
# インストールされるディレクトリ
InstallDir "$PROGRAMFILES\NSISSample"
# 圧縮メソッド
SetCompressor lzma
# ページ
Page directory
Page components
Page instfiles
# アンインストーラ ページ
UninstPage uninstConfirm
UninstPage instfiles

# デフォルト セクション
Section
# 出力先を指定します。
SetOutPath "$INSTDIR"
# インストールされるファイル
File "C:\Sample\Sample.exe"
# アンインストーラを出力
WriteUninstaller "$INSTDIR\Uninstall.exe"
# スタート メニューにショートカットを登録
CreateDirectory "$SMPROGRAMS\NSISSample"
SetOutPath "$INSTDIR"
CreateShortcut "$SMPROGRAMS\NSISSample\サンプル アプリケーション.lnk" "$INSTDIR\Sample.exe" ""
# レジストリに登録
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample" "DisplayName" "サンプル アプリケーション"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample" "UninstallString" '"$INSTDIR\Uninstall.exe"'
SectionEnd

Section "ドキュメント"
# 出力先を指定します。
SetOutPath "$INSTDIR\docs"
# インストールされるファイル
File "C:\Sample\docs\readme.txt"
SectionEnd

Section /o "ユーティリティ"
# 出力先を指定します。
SetOutPath "$INSTDIR\utils"
# インストールされるファイル
File "C:\Sample\utils\Utility.exe"
SectionEnd

# アンインストーラ
!include Uninstall.nsi


Page directoryの次の行に、Page componentsを追加します。

デフォルト セクションから"C:\Sample\docs\readme.txt"のインストールを削除し、新たにSection "ドキュメント"SectionEndを作成します。

又、Section /o "ユーティリティ"SectionEndも作成します。

image.png

実行すると、インストール先の選択の次にインストール コンポーネントの選択が表示されます。

"ドキュメント"が既定でチェックされた状態になり、"ユーティリティ"は既定ではチェックされません。

Section/oオプションを付与すると、そのセクションはオプション扱いとなります。

又、デフォルト セクションはこの一覧にリストされませんが、名前無しのセクションは必ず実行されるセクションになります。

そして、Section "Uninstall"と記述されたセクションは、アンインストーラが実行するセクションになります。

参考ドキュメント

Scripting Reference

Reference/Section - NSIS


セクションのグループ化

セクションはその属性等でグループ化することができます。


Install.nsi

# 日本語UI

LoadLanguageFile "${NSISDIR}\Contrib\Language files\Japanese.nlf"
# アプリケーション名
Name "サンプル アプリケーション"
# 作成されるインストーラ
OutFile "Install.exe"
# インストールされるディレクトリ
InstallDir "$PROGRAMFILES\NSISSample"
# 圧縮メソッド
SetCompressor lzma
# ページ
Page directory
Page components
Page instfiles
# アンインストーラ ページ
UninstPage uninstConfirm
UninstPage instfiles

# デフォルト セクション
Section
# 出力先を指定します。
SetOutPath "$INSTDIR"
# インストールされるファイル
File "C:\Sample\Sample.exe"
# アンインストーラを出力
WriteUninstaller "$INSTDIR\Uninstall.exe"
# スタート メニューにショートカットを登録
CreateDirectory "$SMPROGRAMS\NSISSample"
SetOutPath "$INSTDIR"
CreateShortcut "$SMPROGRAMS\NSISSample\サンプル アプリケーション.lnk" "$INSTDIR\Sample.exe" ""
# レジストリに登録
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample" "DisplayName" "サンプル アプリケーション"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample" "UninstallString" '"$INSTDIR\Uninstall.exe"'
SectionEnd

SectionGroup "ドキュメント"
Section "readme.txt"
# 出力先を指定します。
SetOutPath "$INSTDIR\docs"
# インストールされるファイル
File "C:\Sample\docs\readme.txt"
SectionEnd
SectionGroupEnd

SectionGroup "ユーティリティ"
Section /o "Utility.exe"
# 出力先を指定します。
SetOutPath "$INSTDIR\utils"
# インストールされるファイル
File "C:\Sample\utils\Utility.exe"
SectionEnd
SectionGroupEnd

# アンインストーラ
!include Uninstall.nsi


image.png

"readme.txt"を"ドキュメント"グループに、"Utility.exe"を"ユーティリティ"グループにグループ化しました。

グループ化はSectionSectionGroupSectionEnd間にネストします(インデントは必須ではありません)。

勿論、SectionGroup内には複数のSectionを記述することができます。


インストールされるコンポーネントの組み合わせを用意する

アプリケーションには、必ずインストールされなければならないファイルの他に、必要に応じてユーザーが取捨選択すべきファイルもある場合があります。

そのような場合にインストーラがあらかじめ組み合わせを提供することができます。


Install.nsi

# 日本語UI

LoadLanguageFile "${NSISDIR}\Contrib\Language files\Japanese.nlf"
# アプリケーション名
Name "サンプル アプリケーション"
# 作成されるインストーラ
OutFile "Install.exe"
# インストールされるディレクトリ
InstallDir "$PROGRAMFILES\NSISSample"
# 圧縮メソッド
SetCompressor lzma
# ページ
Page directory
Page components
Page instfiles
# アンインストーラ ページ
UninstPage uninstConfirm
UninstPage instfiles
# インストールの種類
InstType "推奨"
InstType "フル"
InstType "最小"

# デフォルト セクション
Section
# 出力先を指定します。
SetOutPath "$INSTDIR"
# インストールされるファイル
File "C:\Sample\Sample.exe"
# アンインストーラを出力
WriteUninstaller "$INSTDIR\Uninstall.exe"
# スタート メニューにショートカットを登録
CreateDirectory "$SMPROGRAMS\NSISSample"
SetOutPath "$INSTDIR"
CreateShortcut "$SMPROGRAMS\NSISSample\サンプル アプリケーション.lnk" "$INSTDIR\Sample.exe" ""
# レジストリに登録
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample" "DisplayName" "サンプル アプリケーション"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\NSISSample" "UninstallString" '"$INSTDIR\Uninstall.exe"'
SectionEnd

SectionGroup "ドキュメント"
Section "readme.txt"
# 推奨・フル
SectionIn 1 2
# 出力先を指定します。
SetOutPath "$INSTDIR\docs"
# インストールされるファイル
File "C:\Sample\docs\readme.txt"
SectionEnd
SectionGroupEnd

SectionGroup "ユーティリティ"
Section /o "Utility.exe"
# フル
SectionIn 2
# 出力先を指定します。
SetOutPath "$INSTDIR\utils"
# インストールされるファイル
File "C:\Sample\utils\Utility.exe"
SectionEnd
SectionGroupEnd

# アンインストーラ
!include Uninstall.nsi


InstTypeの行で組み合わせとして用意する名前を記述します。

Sectionの中でSectionInの後に組み合わせに含める番号を指定します。

1番目のInstTypeに"推奨"を指定し、セクションを"推奨"に含める場合はそのセクション内でSectionIn 1と記述します。

image.png

image.png

image.png

image.png

インストール オプションで"インストール タイプを選択"というコンボボックスが表示されます。

InstTypeで記述した組み合わせを選択できるようになっており、もう一つ"カスタム"という選択肢を選択すると、ユーザーが任意に組み合わせることができます。

"カスタム"を許容しない場合、InstType /NOCUSTOMを記述します。

# インストールの種類

InstType /NOCUSTOM
InstType "推奨"
InstType "フル"
InstType "最小"


最後に

次回は、nsDialogsとModern UIを使用したより現代的なインストーラの作成について説明します。

※当初、その2(本ページ)でnsDialogsとModern UIの説明をしておりましたが、一般的なセクションの使い方の説明が浅かったため、順序を変更しました。