ホーム http://cml.s10.xrea.com/

オリジナルは、 こちら (英語)です。

Previous | Contents | Next

2 章: チュートリアル: 基礎

2.1 イントロダクション

ダウンロードしたり購入した ほとんどのソフトウェア パッケージが、インストーラー付きでやって来ます。 インストーラーは、ファイルをコピーやアップデートし、レジストリーキーを書き、コンフィギュレーションを書き、 ショートカットを作成する などをします。 これらの全てが ユーザーの為に自動的に行われます。 ユーザーがやる必要のある事は 幾つかの情報を与える事で、インストーラーが残りをやってくれます。 ユーザーは ウィザードを通り抜け、適切な選択をして インストーラーが終わるまで待ちます。 インストーラーが終了した後、ユーザーにはプログラムを実行するだけの単純な仕事が残されます。 必要なステップの全てがインストーラーによってなされるので、ユーザーはやり忘れてしまったかも しれない事について 心配する必要はありません。

NSIS は、そんなインストーラーを作成する製作者の為のツールです。 NSIS は、ただファイルをコピーするだけの基本的なインストーラーから、レジストリーキーを書く、 環境変数をセットする、インターネットから最新ファイルをダウンロードする、コンフィギュレーション ファイルをカスタマイズする、あるいはもっとと言った たくさんの高度な仕事を処理する 非常に 複雑なインストーラーまで 何でも作成する事を可能にします。 NSIS は 非常に柔軟で、そのスクリプティング言語は学び易いものです。

NSIS は、全てのファイルとインストール スクリプトを 1 つの EXE ファイルにコンパイルするので、 あなたのアプリケーションは配布するのが容易です。 NSIS は、データに自身のコードを(デフォルト コンフィギュレーションで)約 34 KB だけ追加します。 NSIS は、その強力なスクリプティング言語と外部プラグインのサポートのおかげで たくさんの オプションを依然として提供していて利用可能でありながらも 最も小さなオーバーヘッドを誇ります。

2.2 スクリプト ファイル

NSIS インストーラーを作成するには、まず NSIS スクリプトを書かなければなりません。 NSIS スクリプトは、特別なシンタックスを持つ ただ通常のテキスト ファイルです。 どのテキスト エディタでもスクリプトを編集できます。 NSIS はエラーがどこにあるのかを示したり警告するのに行番号を使用するので、行番号を表示する テキスト エディタを使う事が推奨されます。 シンタックスの強調表示をサポートするエディタも 推奨されます。 NSIS Wiki で 特に NSIS 用にされたエディタとシンタックスの 強調表示用のファイルを ダウンロードできます。

NSIS スクリプト中では あらゆる行がコマンドとして扱われます。 もしコマンドが 1 行には長すぎるなら、行末でバックスラッシュ - '\' - を使う事ができます。 コンパイラーは新しい行を前の行への追加として扱い、新しいコマンドを期待しません。 例えば:

Messagebox MB_OK|MB_ICONINFORMATION \
"これは、NSIS スクリプト中でより長いコマンドの為に どのように行の中断を使用するかを示すサンプルです。"

もし文字列中で二重引用符を使いたいなら、引用符をエスケープするのに $\" か、` や ' といった 違ったタイプの引用符で文字列を囲むかの どちらかを使う事ができます。

スクリプトの書式についての詳細に関しては、 スクリプトファイルの書式 を見て下さい。

スクリプト ファイルの為のデフォルト拡張子は .nsi です。 ヘッダー ファイルは .nsh 拡張子を持ちます。 ヘッダー ファイルは、スクリプトを 2 つ以上のブロックのコードに分ける事によって それを アレンジするのを助ける事ができ、ヘッダー ファイル中に関数やマクロを置いて 多数のインストーラーに ヘッダー ファイルをインクルードする事もできます。 これはアップデートする事をより容易にして、スクリプトをより読み易くもします。 スクリプト中でヘッダー ファイルをインクルードするには、 !include を使って下さい。 NSIS インストール ディレクトリーの Include ディレクトリーに存在するヘッダー ファイルは、 それらの名前だけでインクルードされ得ます。 例えば:

!include Sections.nsh

2.3 スクリプティング構造

NSIS スクリプトは インストーラー属性とセクション/関数を含む事ができます。 コンパイル時 操作の為にコンパイラー コマンドも使えます。 必要とされるのは、NSIS にインストーラーを書く場所を教える OutFile 命令と 1 つのセクションです。

2.3.1 インストーラー属性

インストーラー属性は、インストーラーの動作と外見を決定します。 これらの属性で、インストールの間に表示されるテキスト、インストール タイプの番号などを変更できます。 これらのコマンドのほとんどは、実行時にはセットだけできて 変更可能ではありません。

そのほかの基本的な命令は、NameInstallDir です。

インストーラー属性についての詳細に関しては、 インストーラー属性 を見て下さい。

2.3.2 Page

非サイレント インストーラーは、ユーザーにインストーラーをコンフィギュレーションさせる ウィザード ページのセットを持っています。 Page コマンド(あるいは より高度な設定の為に PageEx)を使って どのページを表示するかを設定できます。 ページの典型的なセットは このようになります:

Page license
Page components
Page directory
Page instfiles
UninstPage uninstConfirm
UninstPage instfiles

インストーラーに関して、ページのこの典型的なセットは ライセンス同意を表示して、インストールする コンポーネントの選択を可能にして、インストール ディレクトリーの選択を可能にして、最後に instfiles ページで選択されたコンポーネントをインストールします。 アンインストーラーに関しては、確認ページを表示して、instfiles ページでアンインストールします。

2.3.3 Section

一般的なインストーラーでは、ユーザーがインストールできる 幾つかのものがあります。 例えば NSIS 配布インストーラーでは、ソース コード、追加のプラグイン、Example あるいはもっと多くのものを インストールするのを 選ぶ事ができます。 これらのコンポーネントのそれぞれが それ自身の部分のコードを持っています。 もしユーザーがこのコンポーネントをインストールするのを選ぶと、インストーラーはそのコードを 実行します。 スクリプトで、そのコードはセクション中で定義されます。 各セクションは、コンポーネント ページでの 1 つのコンポーネントに一致します。 セクションの名前は 表示されたコンポーネント名であり、もしそのコンポーネントが選択されると セクション コードが実行されます。 セクション 1 つだけでインストーラーをビルドする事は可能ですが、もしコンポーネント ページを 使って ユーザーにインストールするものを選ばせたいなら、2 つ以上のセクションを使わなければ ならないでしょう。

アンインストーラーも 多数のセクションを持つ事ができます。 アンインストーラー セクション名は 'un.' でプリフィックスを付けられます。 例えば:

Section "Installer Section"
SectionEnd

Section "un.Uninstaller Section"
SectionEnd

セクション中で使用され得る命令は インストーラー属性 命令とは非常に異なっていて、実行時に ユーザーのコンピューター上で実行されます。 それらの命令は、ファイルを展開、レジストリー、INI ファイル、通常のファイルを読み書き、 ディレクトリーを作成、ショートカットを作成、あるいはもっとずっと多くの事をできます。 命令 中で もっと情報を得る事ができます。

最も基本的な命令は、インストーラーにファイルを展開する場所を教える SetOutPath と、ファイルを展開する File です。

例:

Section "My Program"
  SetOutPath $INSTDIR
  File "My Program.exe"
  File "Readme.txt"
SectionEnd

セクションについての詳細に関しては、セクション を見て下さい。

2.3.4 Function

関数は、ちょうどセクションのように スクリプト コードを含む事ができます。 セクションと関数の間の違いは、それらの呼ばれ方です。 2 つのタイプの関数、ユーザー関数とコールバック関数があります。

ユーザー関数はユーザーによってセクション内から、あるいは Call 命令を使って他の関数から 呼ばれます。 ユーザー関数は あなたがそれを呼ばない限り 実行されません。 関数のコードが実行された後、関数内でインストールを中止しない限り、インストーラーは Call 命令の後に来る命令を実行し続けます。 インストーラー中にいくつかの場所で実行される必要がある 命令のセットを持っているなら、 ユーザー関数は大変役立ちます。 もしコードを関数中に置くと、コピーする時間を省けて コードをもっと容易に維持できます。

コールバック関数は、インストーラーが開始した時といった ある決められたイベントでインストーラーに よって呼ばれます。 コールバックは オプションです。 例えば もしユーザーをインストーラーに喜んで迎え入れたいなら、.onInit と呼ばれる関数を 定義するでしょう。 NSIS コンパイラーは この関数を名前によってコールバック関数として認識して、インストーラーが 開始する時にそれを呼びます。

Function .onInit
  MessageBox MB_YESNO "このプログラムは My Program をインストールします。続けますか?" IDYES gogogo
    Abort
  gogogo:
FunctionEnd

Abort は コールバック関数中で特別な意味を持っています。 各コールバック関数は それの為のそれ自身の意味を持っています。詳細に関しては コールバック 関数 を見て下さい。 上の例では、Abort は インストーラーにインストーラーを初期化する事を止めるように教えて、 すぐさま終了します。

関数についての詳細に関しては、関数 を見て下さい。

2.3.5 スクリプトでの作業

2.3.5.1 コードの論理的な構造

条件付きでコードを実行する事、あるいは 繰り返しでコードを実行する事は、 StrCmp, IntCmp, IfErrors, Goto あるいはもっとを使って なされる事ができます。 けれど、これをやる もっとずっと容易なやり方があります。 LogicLib は、複雑な論理構造の容易な構築を可能にする いくつかの非常に簡単なマクロを提供します。 LogicLib.nsh 中で説明される そのシンタックスは、他のプログラミング言語と似ていて、初心者にも上級者にとっても同じく より簡単であると証明できます。

例えば、LogicLib 無しでの変数の値の確認は 以下の通りになされ得ます。

StrCmp $0 'ある値' 0 +3
  MessageBox MB_OK '$$0 は ある値です'
  Goto done
StrCmp $0 '他の ある値' 0 +3
  MessageBox MB_OK '$$0 は 他の ある値です'
  Goto done
# else
  MessageBox MB_OK '$$0 は "$0" です'
done:

けれど LogicLib では、以下の例で見る事ができる通り 得られるコードは もっとずっと読み易くて 理解し易いものです。

${If} $0 == 'ある値'
  MessageBox MB_OK '$$0 は ある値です'
${ElseIf} $0 == '他の ある値'
  MessageBox MB_OK '$$0 は 他の ある値です'
${Else}
  MessageBox MB_OK '$$0 は "$0" です'
${EndIf}

以下の例で示される通り、同じ事が Switch を使っても なされ得ます。

${Switch} $0
  ${Case} 'ある値'
    MessageBox MB_OK '$$0 は ある値です'
    ${Break}
  ${Case} '他の ある値'
    MessageBox MB_OK '$$0 は 他の ある値です'
    ${Break}
  ${Default}
    MessageBox MB_OK '$$0 は "$0" です'
    ${Break}
${EndSwitch}

多数の条件も サポートされます。 以下の例は、もし $0 と $1 の両方が空なら ユーザーに知らせます。

${If} $0 == ''
${AndIf} $1 == ''
  MessageBox MB_OK|MB_ICONSTOP '両方が 空!'
${EndIf}

LogicLib は ラベルと相対的なジャンプの必要性を無くし、従って ラベル名が矛盾するのを予防して、 スクリプトが変更される度に毎回 相対的なジャンプ オフセットを手動で調整する必要を 無くします。

一般的な while, do, for ループをサポートする事によっても 繰り返しを単純化できます。 以下の例は全て LogicLib を使って 5 までカウントします。

StrCpy $R1 0
${While} $R1 < 5
  IntOp $R1 $R1 + 1
  DetailPrint $R1
${EndWhile}
${For} $R1 1 5
  DetailPrint $R1
${Next}
StrCpy $R1 0
${Do}
  IntOp $R1 $R1 + 1
  DetailPrint $R1
${LoopUntil} $R1 >= 5

LogicLib を使うには、以下の行を スクリプトの一番上に置く必要があります。

!include LogicLib.nsh

より多くの例が、 LogicLib.nsi 中で 見つかるでしょう。

2.3.5.2 変数

Var コマンドで あなた自身の変数($VARNAME)を宣言できます。 変数はグローバルで、セクションか関数中で使用され得ます。

ユーザー変数の宣言と使用:

Var BLA ;変数を宣言する

Section bla

  StrCpy $BLA "123" ;$BLA 変数を使えます

SectionEnd

さらに、一時ストレージの為にも使用され得る スタックがあります。 スタックを利用するには PushPop コマンドを使用して下さい。 Push はスタックに値を追加して、Pop は 1 つ削除して変数にセットします。

共有されるコードのために、($0 と $R0 のように) 20 のレジスターが利用可能 です。 これらのスタティック変数は 宣言される必要が無くて、名前が衝突する事はありません。 もし共有コードでこれらの変数を使いたいなら、スタック上にオリジナルの値を保存して 後でその オリジナルの値を戻して下さい。

関数を呼んだあと、変数には前と同じ値が入っています。 多数の変数を使っている時には 順番に注意して下さい(最後に入れたものを 最初に出す):

Function bla

  Push $R0
  Push $R1

    ...code...

  Pop $R1
  Pop $R0

FunctionEnd

2.3.5.3 デバッギング スクリプト

NSIS で作業すればするほど、スクリプトは複雑になって行きます。 これは、特に たくさんの変数を扱っている時に ミスをする可能性を増やします。 コードをデバッグするのを助ける いくらかの可能性があります。 変数の内容を表示するには、MessageBoxDetailPrint を使うべきです。 全ての変数についての簡潔な概観を得るには、 DumpState プラグインを使うべきです。 デフォルトでは インストーラーの全てのセクションがログ ウィンドウにプリント アウトされます。 ログ ウィンドウで右クリックして "Copy Details To Clipboard" を選択すると、 ログを利用できます。 直接ファイルに書くやり方もあります。 ここ を見て下さい。

2.3.6 スクリプト 実行

ユーザーがインストーラーやアンインストーラーを実行する時、ページは スクリプト中で定義された 順で 表示されます。 instfiles ページに達した時、選択されたコンポーネントに相当しているセクションが スクリプト中で 定義された順で 実行されます。 もしコンポーネント ページが表示されないなら、選択解除されたり スクリプトでどうにかして無効に されたりしていないと仮定して 全てのセクションが実行されます。

セクション中のコードと並んで、コールバック関数中にもコードがあります。 もし定義されると、セクションのコードの前に実行されるかもしれません。 例えば、.onInit コールバック関数は スクリプト中の他の 何よりも前に 実行されます。 ページ表示プロセスの決まったポイントで実行される ページ コールバック関数 もあります。

2.3.7 コンパイラー コマンド

コンパイラー コマンドは、コンパイル時にあなたのコンピューター上で実行されます。 ヘッダーファイルをインクルード、アプリケーションを実行、作業ディレクトリーを変更、あるいは より多くの事をする 条件コンパイルの為に、それらが使用され得ます。 最も一般的な使用は 定義(define)です。定義は コンパイル時 定数です。 プロダクト バージョン ナンバーを定義して それをスクリプト中で使用できます。 例えば:

!define VERSION "1.0.3"
Name "My Program ${VERSION}"
OutFile "My Program Installer - ${VERSION}.exe"

define についての詳細に関しては、 Conditional Compilation(条件コンパイル) を見て下さい。

もう 1 つの一般的な使用は マクロです。 マクロは、define しだいでその値を使って、コンパイル時にコードを挿入するのに 使われます。 マクロのコマンドは コンパイル時に挿入されます。 これは、一度だけ一般的なコードを書いて、わずかな変更でたくさんの回数それを使用する事を 可能にします。 例えば:

!macro MyFunc UN
Function ${UN}MyFunc
  Call ${UN}DoRegStuff
  ReadRegStr $0 HKLM Software\MyProgram key
  DetailPrint $0
FunctionEnd
!macroend

!insertmacro MyFunc ""
!insertmacro MyFunc "un."

このマクロは、インストーラーとアンインストーラーの両方の為に 同じコードを書く事を 避けるのを 助けます。 2 つの !insertmacros は 2 つの関数、MyFunc と呼ばれるインストーラーの為のものと un.MyFunc と呼ばれるアンインストーラーの為のもの、を挿入して、両方が 厳密に同じ事をやります。

詳細に関しては Compile Time Commands(コンパイル時 コマンド) を見て下さい。

2.4 コンパイラー

スクリプトを作成してしまった後 インストーラーを作成する為にやる必要のある 2 番めの事は、 スクリプトをコンパイルする事です。 MakeNSIS.exe が NSIS コンパイラーです。 スクリプトを読んで、構文解析し、あなたの為のインストーラーを作成します。

コンパイルするには、あなたの .nsi ファイルを右クリックして Compile NSIS Script を選択する 必要があります。 これは、NSIS コンパイラー インターフェース MakeNSISW に、スクリプトをコンパイルするのに MakeNSIS を起動 実行させます。 MakeNSISW は、あなたが見て コピーして インストーラーをテストして それを見て あるいは より多くの事もできる ウィンドウで、MakeNSIS の出力を得て それをあなたにプレゼントします。 コマンドライン プロンプトから makensis.exe を使う事も可能です。

コンパイラーは、スクリプトをチェックして 警告やエラーを出します。 もしエラーが起きる(例えば パラメーターが 2 つ必要だけれど 1 つしか与えられない)と、 コンパイラーは中断して 行番号を含む短いエラーメッセージを表示します。 致命的でないエラーに関しては、コンパイラーは警告を出します(例えば 1 つのスクリプト中で 2 つの DirText コマンド)。 もしスクリプトにエラーが無ければ、あなたが配布する為のインストーラーを出力します。

NSIS は ここ で説明されるとおり、異なった圧縮方式を サポートしています。 ZLIB は、高速でメモリーを少ししか使用しない デフォルトの圧縮方式です。 LZMA は、インターネットでの配布の為の小さなインストーラーの作成の為に 良い方式です。 BZIP2 は普通、LZMA ほどではありませんが ZLIB より良く圧縮して、もしメモリー使用を抑えたり 速いスクリプト コンパイルが必要なら、役立ちます。

Windows 用インストーラーを Linux, BSD, Mac OS X サーバー上でコンパイルする事も可能です。 詳細に関しては Building NSIS を見て下さい。

2.5 Modern UI

ポピュラーな NSIS 用ユーザー インターフェースはモダン ユーザー インターフェースです。 それは 最近のバージョンの Windows のウィザードのようなインターフェースです。 Modern UI はカスタマイズされたリソース ファイルだけではなく、たくさんの新しいインターフェース 要素を持っています。 現在のステップを説明する白いヘッダ、コンポーネント ページでの説明領域、ようこそページ、 ユーザーにアプリケーションの実行やシステムの再起動あるいはもっと多くの事を可能にする 完了ページを 特色としています。

詳細に関しては、 Modern UI 2 Readme英語)と Modern UI Examples をチェックして下さい。

2.6 プラグイン

NSIS は、スクリプトから呼ばれ得るプラグインを サポートしています。 プラグインは C, C++, Delphi, その他のプログラミング言語で書かれた DLL ファイルであり、 従って いっそう強力なコード ベースを NSIS に提供します。

プラグイン コールはこの様になります:

DLLName::FunctionName "パラメーター 1番" "パラメーター 2番" "パラメーター 3番"

パラメーターの事になると あるものは全く必要とせず あるものは送りたいだけ多くのパラメーターを 受け付け、プラグインのあらゆる関数が それ自身の必要条件を持っています。 例:

nsExec::ExecToLog '"${NSISDIR}\makensis.exe" /CMDHELP'
InstallOptions::dialog "$PLUGINSDIR\test.ini"
NSISdl::download http://download.nullsoft.com/winamp/client/winamp291_lite.exe $R0

NSIS が理解するプラグインは、コンパイラーの出力の一番上でリストされます。 NSIS は、あなたの NSIS ディレクトリーの下の Plugins フォルダでプラグインを探して、それら 利用可能なすべての関数をリストします。 NSIS にその他のディレクトリーでも探すように教えるのに !addplugindir を使えます。

NSIS ディストリビューションは 既に多くのプラグインを含んでいます。 InstallOptions は、 NSIS Page コマンド(ページ を見て下さい)との組み合わせで カスタム ページを作成するのを可能にする ポピュラーなプラグインです。 Startmenu プラグイン は、 ユーザーがスタート メニュー フォルダを選択する事ができるページを提供します。 違った目的の為のたくさんのプラグインがあり、ヘルプ ファイルや例の為に <インストール先>\Docs フォルダを見て下さい。 オンラインで追加のプラグインを見つけられます: NSIS Wiki

あなた自身のプラグインも作成できます。 C/C++ と Delphi のヘッダーファイルが既に利用可能で、これのやり方に関しては example プラグイン を見て下さい。 インクルードされたプラグインのソース コードは、ソース コード パッケージでも見つけられます。

2.7 より多くの事

このチュートリアルは、NSIS の基本的な特徴を記述しました。NSIS に出来るあらゆる事について もっと学ぶには、このマニュアルを読むのに 何度も時間をかけて下さい。 (訳注: ほかの章 全部を含めての事です。)

 

Previous | Contents | Next