NSISのスクリプトで得た知見

ここ最近、遅まきながらElectronを触り始めました。Windowsのインストーラー作成にNSISを使うことにしました。

# スクリプトファイルの文字コード
NSISには、Unicode指定のものとそうでないものの２つのビルドがあります。スクリプト内に日本語が使用されていなければどちらのビルドでも実行できますが、Unicode指定のものはUnicodeまたはUTF-8で保存されたスクリプトファイルが実行できます。指定なしのものはシフトJIS(OS既定の文字コード)で保存されたスクリプトファイルが実行できます。もし違う文字コードで保存されたスクリプトファイルを実行すると、日本語部分が文字化けするか、エラーとなりインストーラーを作成できません。

#フォルダのコピー
フォルダ配下のファイルをごっそり、配置先にコピーしたいと思い

```
File /r dist\win\myapp
```
と記述してインストーラーを作成し実行すると、\$INSTDIR直下にdist\win\myapp配下のファイルが配置されると期待したのですが、結果は\$INSTDIRにmyappフォルダが作成され、その配下にファイルが配置されました。\$INSTDIR直下にdist\win\myappフォルダ内のファイルを配置させるには

```
File /r dist\win\myapp\*
```
と、最後にワイルドカードを付けたパスを指定することで\$INSTDIR直下にファイルを配置させることができました。

#コマンドラインオプションから値を渡す
コマンドライン版のmakensisの/Dオプションで、動的に値を渡すことができます。
変数名は自由に設定でき、変数は${}で囲みます。
例えば以下のようにビルドされたインストーラーファイルの出力先やコピー元のフォルダを動的に変更するようにスクリプトを記述すると

```installer.nsi
outFile "${OUTPATH}\setup.exe"
section "install"
  setOutPath $INSTDIR\ScreenShare
  file /r ${SETUPFILESPATH}\*
sectionEnd
```

makensisを以下のようにオプションを設定して実行することで該当する変数に値を渡すことができます。

```
makensis /DOUTPATH=installer\win32 /DSETUPFILESPATH=dist\win32
```

これを利用すれば、32bit用/64bit用など、いろんな条件のインストーラーを一つのスクリプトファイルで作成することができるようになります。

#アンインストーラーの登録
インストーラーを作成して、実行してみたのですが、コントロールパネルの"プログラムと機能"のリストに表示されません。
このリストに表示されるようにするためには、アンインストーラーをレジストリに登録しなければならないようです。
アンインストーラー登録には最低2つのキーが必要です。

```
HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "DisplayName"
HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "UninstallString" 
```

(試していないですが、対象がインストールユーザーのみの場合はHKLMのところをHKCUに置き換える必要があるようです)

上記の2つのキーの登録のスクリプト例

```
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "DisplayName" "マイアプリ"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "UninstallString" "$INSTDIR\uninstaller.exe"
```

このスクリプトをsection "install"内に記述し、インストーラーを実行すると、"プログラムと機能"に「マイアプリ」としてリストに表示され、そこからアンインストーラーを実行することができるようになりました。
ただし、これだけだとアイコンや発行元、バージョンといった情報がないためリストに表示される内容が乏しいものとなります。
これらのものも登録したい場合は主に以下のキーを登録します。

```
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "InstallLocation" "$\"$INSTDIR$\""
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "DisplayIcon" "$\"$INSTDIR\logo.ico$\""
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "Publisher" "${COMPANYNAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "HelpLink" "${HELPURL}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "URLUpdateInfo" "${UPDATEURL}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "URLInfoAbout" "${ABOUTURL}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "DisplayVersion" "${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "VersionMajor" ${VERSIONMAJOR}
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "VersionMinor" ${VERSIONMINOR}
# There is no option for modifying or repairing the install
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "NoRepair" 1
# Set the INSTALLSIZE constant (!defined at the top of this script) so Add/Remove Programs can accurately report the size
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\xxx" "EstimatedSize" ${INSTALLSIZE}
```
参考にしたページ http://nsis.sourceforge.net/A_simple_installer_with_start_menu_shortcut_and_uninstaller
参考元のページにはバージョン情報などにもダブルクォーテーションで囲んで(\$\"~\$\")いますがパス関連以外は不要のようです。
DisplayIconのところを見てみると、表示するアイコンファイルのパスを設定していますが、そのほかのアプリの登録情報を見てみるとexeファイルでもいいようで、実際にexeファイルのパスを設定してもアイコンを表示することができました。
それとEstimatedSizeはKB単位で、1K=1024で計算された値となります。