今日は「アタッシェケース」でも使っているインストーラの話です。
現在、カレントバージョン(ver.2.75以前)では、EXEpress CXというツールを使っています。
配布したいファイル群をcab圧縮しておけば(※圧縮ツールも添付されています)、そのままインストーラとマージして簡単に作成されます。
EXEpress CX
http://www.webtech.co.jp/onlinesoft/exepress/index.html
商用でないならフリーで使えますし、高機能です。何より安定感があり、好んで使っていました。
しかし、ちょっと難しいことをしようと思うと、とたんに行き詰まってしまいました。。。
「アタッシェケース」を最終的な配布状態にするには、自己実行形式ファイルのマージと、ヘルプファイルのコンパイル、UPXでの本体圧縮など、一連の流れをバッチファイルで処理します。
その中で、最後にインストーラへと吐き出すのですが、これがEXEpressですとバッチファイルからの扱いが非常に面倒なのです。
そこで、次の新バージョン(現在βテスト中)からは、商用でも利用可能で、オープンソース化されている「Inno Setup」を使うことにしました。
Inno Setup
http://www.jrsoftware.org/isinfo.php
日本語にも対応していて、翻訳データはページ左メニューの「Translation」をクリックして、「Japanese」でダウンロードできます。
Inno Setupは、スクリプトが組めて、かなり自由度の高い作りになっています。それ故、取っつきにくいという部分もありますが、いざいじって慣れてくると、その便利さに驚きます。簡単ながらデバッガも付いているので、ブレークポイントを設定してのデバッグも可能です。
また、インストーラのフロントにある「絵」も、正直残念な感じで好きではなかったのですが(スミマセン‥‥)、これも自分で作って差し替えが可能だと知り、これはもう使うしかないと。
Inno Setupのスクリプトファイルは、全体を俯瞰した方が分かりやすいと思いますので、GitHubに上がっている「アタッシェケース」のインストーラ設定ファイルを参照しながらがいいかもしれません。
https://github.com/hibara/AttacheCase/blob/master/installer/AttacheCase.iss
以下に、導入したとき引っかかった点、便利だと思った点を挙げてみます。
これは他のサイトでも山ほど記事を見つけられますので、詳しくは書きませんが、前述した翻訳データをダウンロードし、自分のアプリケーションのissファイル内で、以下のように宣言します。
[pascal]
[Languages]
Name: japanese; MessagesFile: compiler:Languages\Japanese.isl
[/pascal]
これでインストーラの各所で出るメッセージなど、主な部分は日本語化されます。
これが何より便利でした。スクリプトファイル冒頭で、
[pascal]
#define MyAppVer GetFileVersion("..\AttacheCase.exe")
[/pascal]
としておけば、MyAppVerという変数に代入され、以降{#MyAppVer}と書けば「2.8.0.3」などと参照可能になります。つまり、インストーラ画面中に「アタッシェケース ver.2.8.0.3 をインストールします」といった感じで出すことができます。
しかも、その次の、
[pascal]
#define MyAppVerNum StringChange(MyAppVer, ".", "")
[/pascal]
では、文字列操作する関数まであって、「2.8.0.3」の中のピリオドを削除して、変数に代入しています。つまり「2803」という数字を取得しています。
これを後に出てくるバージョン付きフォルダーにナンバリングして生成したりだとか、バージョン番号が付いたファイルを見つけてくるときに役立ちます。
EXEpressでは、これができなくて、手製のツールであちこちを書き換えてからインストーラを作成していたので、これは、僕的にはかなりうれしい機能でした。
{app}
と書けば、僕の環境ですと、「C:\Program Files (x86)」と取得できます。
当然、これはインストールされるユーザーさんごとに環境が異なりますので(OSによって大きくパスが変わります)、これらの定数でその差異を吸収してくれます。
他にもたくさんの環境定数が定義されていますが、ざっと使えそうなものを挙げると、
{win} ならば、C:\WINDOWS
{commonappdata} だと、AppData(C:\Users\[ユーザー名]\AppData\Roaming)
{commondesktop} だと、ユーザーごとのデスクトップへのパス。
珍しいものですと、{fonts}でフォントフォルダーパスなんかも取得できたりします。
Inno Setupといえば、
ですが‥‥ これも差し替えられます。
164×314 dotで用意し、以下の場所で指定しておきます。
[pascal]
[Setup]
;ウィザードページに表示されるグラフィック(*.bmp: 164 x 314)
WizardImageFile=bmp\installer_pic_01.bmp
;ウィザードページに表示されるグラフィックが拡大されない
WizardImageStretch=no
;その隙間色
WizardImageBackColor=$ffffff
[/pascal]
なお、次のウィンドウで出る左上の画像も差し替えられます。
これ。
55×58 dotで用意したファイルへのパスを以下のように指定します。
[pascal]
;ウィザードページの右上部分のグラフィック(*.bmp: 55 x 58)
WizardSmallImageFile=bmp\installer_pic_02.bmp
[/pascal]
もちろん、インストーラのアイコン自体も変更可能です。
僕はデフォルトのがわかりやすいのでそのまま使っていますが、こちらもデザインにこだわって作り替えることが可能です。
その場合は、
[pascal]
SetupIconFile=icon\main_icon.ico
[/pascal]
と、します。
はじめてインストーラを作成してテストしたときにハマったので、これもメモ。
基本的に Inno Setup では「問題」というより、「仕様」です。
同じバージョンでも強制的に上書きインストールを行わせるには、Flagsの中に「ignoreversion」を含めます。
[pascal]
[Files]
Source: "bin\AttacheCase.exe"; DestDir: "{app}"; Flags: ignoreversion
[/pascal]
これで何度でも上書きでインストールのテストができます。
もちろんですが、この Flagsを書かなければ、同バージョンは上書きされないという設定にすることができます。
よくインストール完了後に、チェックが入っていてウザいアレです(笑)。
これも簡単に指定できます。
以下のように、Flagsの中に「isreadme」と加えるだけです。
[pascal]
[Files]
Source: "bin\readme.txt"; DestDir: "{app}"; Flags: isreadme ignoreversion
[/pascal]
じゃあ、インストール完了後に、「本体を実行する」には、どうするのか?
これは別のセクションで指定することになります。
[pascal]
[Run]
Filename: "{app}\AttacheCase.exe"; Flags: postinstall
[/pascal]
postinstallと指定することで、インストールが完了した後に実行されます。
[Run]セクションが出てきたので、ついでに少し高度な使い方です。
アタッシェケースでは、*.atcという拡張子のファイルを関連付けているのですが、それをインストーラの途中で行います。
ついでに、デスクトップにショートカットファイルも作ってしまいましょう。
それらはすべて[Tasks]に記述します。
[pascal]
[Tasks]
Name: desktopicon; Description: "デスクトップにショートカットアイコンを作成する";
Name: association; Description: "*.ATCファイルをアタッシェケースに関連付けする";
[/pascal]
これはややこしいのですが、Nameが各データをひもづける役目をしています。これは変数というか、ラベルみたいなもので、自分で名前を付けます。
「desktopicon」は、
[pascal]
[Icons]
Name: "{commondesktop}\アタッシェケース"; Filename: "{app}\AttacheCase.exe"; WorkingDir: "{app}"; Tasks: desktopicon
[/pascal]
「アイコンを作る」というだけなので、[Icons]セクションのTasksに書きます。
また、関連付けの方は、「実行」させますので、前述の[Run]セクションに書いてひもづけます。
[pascal]
[Run]
Filename: "{app}\AtcSetup.exe"; Parameters: "0"; Tasks: association; Flags: nowait skipifsilent runascurrentuser
[/pascal]
実行の際にはパラメーターも渡せます。たとえば「インストール後、初回起動時だけメッセージを表示」とかできたりするでしょう。
また、関連付けにはやや深いところのレジストリ操作が入りますので、Flagsに「runascurrentuser」を付けています。
これにより、管理者権限昇格(UACエレベーション)の確認ダイアログが出るようになります(当然ですが、権限昇格をユーザーがキャンセルすれば実行は失敗します)。
ほとんどインストーラ生成の情報は、Inno Setupのスクリプトファイル(*.iss)に含まれていますので、バッチファイルから呼び出してコンパイルをかけるのは、
[code]
ISCC.exe AttacheCase.iss
[/code]
これだけで済みます。
すべて所定の位置にファイルをコピーして実行すれば良いだけです。
Inno Setupのヘルプファイルを見ると、さらに細かい制御やオプション付加が可能になっていますが、いかんせん英文なので敷居を上げているかもしれませんね。
それさえ気にならなければ、かなり高機能で完成度の高いインストーラだと思います。
Inno SetupがDelphiで書かれている関係上、pascalでの、さらに細かいプログラミングも可能になっています。
これも僕が公開している「MarkDown#Editor」の方のインストーラでは、.NET Frameworkのインストール状況を確認してからインストールするというトリッキーな方法をとっていますが、これはpascalで書かれたものを参考にさせていただきました。
http://stackoverflow.com/questions/4104011/innosetup-how-to-check-the-framework-4-0
おそらく細部をつらつら書くよりは、全体を見ていただいた方が早いと思いますので、GitHubに上げている「アタッシェケース」のissファイルを眺めてみてください。コメントアウトも入れてありますので、わかりやすいと思います。
https://github.com/hibara/AttacheCase/blob/master/installer/AttacheCase.iss
さらに、実際にアタッシェケース(ver.2.8.0~)をダウンロードしてインストーラを実行していただければ、その挙動と見比べられると思います。
実際のインストーラはこちら。
http://hibara.org/software/attachecase/#new_version
このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください。
日々の開発作業で気づいたこと共有を。同じところで躓いている人が、 検索で辿り着けたら良いな、というスタンスで記事を書くので不定期更新になります。
コメントする