Windowsアプリ開発でVisualStudio Express 2017 と WiX toolset を使ってインストーラを作成したみたが、そこそこ苦労したのでメモ書きしておく。
ダウンロードインストール
WiX toolset 3.11、WiX Toolset Visual Studio 2017 Extensionをダウンロード、インストール。
ダウンロードページ:http://wixtoolset.org/releases/
VS2017でいきなりXMLに取り組むのはしんどいので、WiX Editを使って試行し、XMLの原型を作る。
ダウンロードページ:http://wixedit.sourceforge.net/
WiX Editで簡単サンプル作成
Toru Takahashi さんの「Windows上でWixおよびWixEditを使ったインストーラ作成
」に従ってサンプルを作る。
サンプル拡張
次の二点に対応するため、サンプルを作り直す。
・exeと多言語対応のresources.dllを含める。
・デスクトップショートカットとスタートメニューを追加する。
このチュートリアルでは後半の方で紹介される「WiXで指定ディレクトリ以下をまとめてインポート」する方法を新規作成時に行う。
このチュートリアルにはショートカット追加が含まれていないので、ウィザードでの新規作成の際にフィーチャーを追加。
ダウンロードインストール
WiX toolset 3.11、WiX Toolset Visual Studio 2017 Extensionをダウンロード、インストール。
ダウンロードページ:http://wixtoolset.org/releases/
VS2017でいきなりXMLに取り組むのはしんどいので、WiX Editを使って試行し、XMLの原型を作る。
ダウンロードページ:http://wixedit.sourceforge.net/
WiX Editで簡単サンプル作成
Toru Takahashi さんの「Windows上でWixおよびWixEditを使ったインストーラ作成
」に従ってサンプルを作る。
サンプル拡張
次の二点に対応するため、サンプルを作り直す。
・exeと多言語対応のresources.dllを含める。
・デスクトップショートカットとスタートメニューを追加する。
以下、Toru Takahashi さんのチューアルと共通する手順は割愛。
斜体部分は実際の対象の名前で置き換える。
exeとresoucesが含まれるRelaseフォルダを選択。
フォルダ内の全ファイルがインポートされるので、不要なファイルを削除する。
削除後はこんな感じ。
"Add User Interface"、"Desktop application shortcut"、"Startmenu application shortcut"、"Startmenu uninstall shortcut"にチェックを入れる。
”Add a userinterface”に"WixUI_InstallDir"が含まれていないので、仮設定しておき、あとで修正する。
デスクトップのショートカットを設定する。
下段はショートカットアイコンの下に表示される名前。
スタートメニューのショートカットを設定する。
中段はスタートメニューのアプリ起動ショートカットに表示される名前(XMLに反映されないようだが)。
exeを起動するだけのショートカットなら下段は空欄のままにしておく。
スタートメニューのアンインストールショートカットを設定する。
適宜情報を変更してウィザード終了。
VS2017でculture指定で日本語版msiを作る場合は、Languageの変更、Codepageの追加はしなくてもよい。
左ペインFiles > 中ペインPFiles > Release を選択。
ReleaseはImportしたフォルダ名。
右ペインのId=Nameの値をProgramFilesFolderの下に作るフォルダ名(通常はアプリケーション名と同じ)に変更する。
私はIdもAppNameAppFolderに変更したが、FeaturesでこのIdを参照している項目も同時に変更する必要がある。
左ペインGlobal > 中ペインUIRefを選択。
右ペインのIdの値を"WixUI_InstallDir"に変更する。
左ペインProperties > 中ペイン右クリック > Add Newで表示されるダイアログで"WIXUI_INSTALLDIR"を追加し、その値にアプリケーションフォルダのIdを入力する。この例では”Release"、あるいは変更した場合は"AppNameAppFolder"。
これを行わない場合、ビルドはされるがインストーラ実行時にエラーが発生する。(下記error code 2819参照)
VisualStudioのソリューションにSetupプロジェクト追加
詳しくは(といってもとてもシンプルな)http://wixtoolset.org/のVisualStudioへのプロジェクト追加手順のページを参照してください。
WiX toolsetがインストールされると、新規プロジェクト追加の際のプロジェクトタイプに”WiX Toolset”が追加される。3.11をインストールしたので"Setup Project for WiX v3"を選択。
wixtoolset.orgの手順では独立したソリューションを作り、既存アプリを参照に追加しているが、私はもとのアプリのソリューションにSetupプロジェクトを追加してみた。
プロジェクト追加ダイアログ左下の選択肢で"ソリューションに追加"を選択。
名前は"Setup”とした。
Setup > References に次のdllを追加する。
C:\Program Files (x86)\WiX Toolset v3.11\bin\WixUIExtension.dll
この参照がないとビルド時に次のエラーが発生する。
Unresolved reference to symbol 'WixUI:WixUI_InstallDir' ...
Setup > Product.wxs にWiX Editで作成したwxsをコピー/ペースト。
wxsのReleaseフォルダへのパスをソリューションに合わせて変更。
..\AppName\bin\Release\
ビルド構成マネージャーで構成変更・追加。(一例)
Debug、ReleaseのビルドからプロジェクトSetupを除く(チェックをはずす)。
新規構成”Setup"を追加。Release、Setupをビルドに追加。
ビルド構成Setupでビルドすると構成に従った出力フォルダ(この例では...\Setup\bin\Release\)内にSetup.msiが出力される。
多言語対応
プロジェクトSetupのプロパティー画面 > Build > General > Cultures to buildに対象カルチャーを追加。en-US;ja-JPのように複数のときはセミコロンで句切る。
ビルドすると構成に従った出力フォルダ(この例では...\Setup\bin\Release\)内に対象カルチャー毎のサブフォルダが作られ、その中にSetup.msiが出力される。
エラーと対策
warning CNDL1113 : Because it is an advertised shortcut, the target of shortcut 'desktopShortcut' will be the keypath of component 'APPNAME.EXE' rather than parent file 'APPNAME.EXE'. To eliminate this warning, you can (1) make the Shortcut element a child of the File element that is the keypath of component 'APPNAME.EXE', (2) make file 'APPNAME.EXE' the keypath of component 'APPNAME.EXE', or (3) remove the @Advertise attribute so the shortcut is a non-advertised shortcut.
この警告が出ても正常に動作するmsiが作られる。
WiX Editは次のようなタグ構造を作る。
<Component Id="APPNAME.EXE” ...>
<File Id="APPNAME.EXE" ...>
<Shortcut Id="desktopShortcut" ... />
<Shortcut Id="ExeShortcut" ... />
</File>
</Component>
これを、Shortcut要素がComponent要素の直接の子要素になるように変更する。
<Component Id="APPNAME.EXE” ...>
<File Id="APPNAME.EXE" ...></File>
<Shortcut Id="desktopShortcut" ... />
<Shortcut Id="ExeShortcut" ... />
</Component>
WiX EditのUIでは変更できないので、Tools > Launch External Editorでwxsを開き、編集する。
WiX EditがComponent とFileに同じIdを振るため、メッセージが分かりにくなっている。
WiX toolsetのマニュアルの例ではこの場合のComponent のIdをMainExecutableとしている。このIdを変更する場合はFeaturesのComponentRefでの参照も変更すること。(次項のエラー参照)
error LGHT0094 : Unresolved reference to symbol 'Component:APPNAME.EXE' in section 'Product:GUID'.
上記警告でComponent要素のIdを変更したが、それを参照しているRefのIdを一致させていない場合に発生する。当該要素のIdを変更する。
error CNDL0006 : The Directory/@Name attribute's value cannot be an empty string. If you want the value to be null or empty, simply remove the entire attribute.
値が必須の要素で、値がブランクになっている。
上記手順で作成した場合、Files > ProgramMenuFolder > Dictionary のNameの値が(ウィザードで入力したはずだが?)ブランクになっている。スタートメニューのアプリ起動ボタンに表示される名前を入力する。
error LGHT0267 : Found orphaned Component 'SomeCompnent'. If this is a Product, every Component must have at least one parent Feature. To include a Component in a Module, you must include it directly as a Component element of the Module element or indirectly via ComponentRef, ComponentGroup, or ComponentGroupRef elements.
Component 要素が出現したが、ComponentRef, ComponentGroup, ComponentGroupRef のいずれとも関連付けられていない。
私が作った範囲ではFiles >Features の DefaultFeatures から漏れている場合に発生。DefaultFeatures に追加する。
error LGHT0130 : The primary key 'UninstallProduct' is duplicated in table 'Shortcut'. Please remove one of the entries or rename a part of the primary key to avoid the collision.
どういう手順で発生したか不明だが、Component Id="UninstallProduct"が二つできたときに発生。不要な方を削除する。
error code 2819
This installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code 2819.
インストーラ実行時に発生するエラー。
"UIRef"を"WixUI_InstallDir"にした場合で、"Properties"に"WIXUI_INSTALLDIR"を
追加しなった場合に発生する。
"Properties"に"WIXUI_INSTALLDIR"を追加し、その値にアプリケーションフォルダのIdを入力する。