Microsoft Visual Studio Installer Projects から、WiXに移行すべく、調べて調べて、約10日間ほどかかりました。
先人の情報に頼りつつ、それでも出てくる不明な点を解決するのに、ずいぶん時間がかかりました。
難しかったところや、日本語では書かれていない参考になる事柄を、記しておきます。
前提
Visual Studio 2019
WiX v3.11.2
で、セットアッププロジェクトを作成。
準備
- WixUIExtension.dll
- WixUtilExtension.dll
を、セットアッププロジェクトの参照に追加します。
C:\Program Files (x86)\WiX Toolset v3.11\bin\
にありますね。
アップグレードの時に、前のバージョンを削除する
UpgradeCodeを一致させたままにして、MajorUpgrade を行えば良いのですが、UpgradeCodeの一致が十分条件でないのが、はまったところです。
Installer Projectsで、インストールしたものを、WiXで作成したmsiで、削除したいのに、なぜだかできない。
InstallScopeが、前のと新しくしたいものとで異なると、前のバージョンのものだと認識出来ないのが原因でした。
.wxsのファイルから、
<Package InstallScope="perMachine"
の、InstallScope="perMachine"を削除して、対応できました。
- Wix to replace installations from Visual Studio installers
- How do I fix the upgrade logic of a wix setup after changing InstallScope to “perMachine”
heat.exe を使わざるえない
NuGetで多くのDLLを参照して利用しているので、DLLのアップデートをしたら、Setupプロジェクトの、.wxsファイルも変更しなくてはいけません。
ヘルプには、セットアッププロジェクトを作成する際に、heat.exeは最初の一回行って、その後手作業で修正していくのが前提、とか書かれていますが、それでは間に合いません。
heat.exeで出力したある.wxsは、5万行を超えているので、自動化しないわけにはいきません。
そのためには、不要なフォルダ・ファイルを削除します。
削除を、heat.exeで行うには、xmlを操作するxsltファイルを作成するのがセオリーのようです。
heat.exeで利用するのに必要な、簡単なXSLTの構文を理解・作成するのに、1日がかりでした。
- DLLと一緒に、xmlファイルがついてくることがあるのですが、おそらくいらないはずなので、その削除。
- もしあるなら、不要な言語リソースを削除。
- .pdbファイルは、releaseにも含めると良いようなので、削除しません。
XSLTについて
COM登録
DLLと、TLBをレジストリに登録しないといけないようです。
regsvr32.exeをインストーラーの中で利用するのではなく、インストーラーが直接レジストリに登録する処理を行うと良いようです。
これも、heat.exeで、引数に、hoge.dll, hoge.tlb をそれぞれ指定して、登録する項目を集めます。
Windowsのあるドライブ
<SetDirectory Id="WINDOWSVOLUME" Value="[WindowsVolume]"/>
<Directory Id="WINDOWSVOLUME">
</Directory>
のようにします。
- http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Error-using-WindowsVolume-predefined-folder-td3313078.html
- https://stackoverflow.com/a/1641315/9924249
ROOTDRIVEは、最も空きスペースのあるドライブになったりするため、Windowsのあるドライブになるわけではありません。Cドライブのすぐ下にインストールしたいのに、Dドライブの下になったりしました。
アイコン指定
<Icon Id="icon.ico" SourceFile="$(var.HOGE_TargetDir)HOGE.exe"/>
みたいに、SourceFileに、exeを指定しても良いようです。
$(var.HOGE_TargetDir)は、パスの変数。SourceFileなので、ビルドした時に、プロジェクトフォルダのbinに作成されるexeを指定しました。
重複するDLL
複数のプロジェクトがソリューションにあると、重複するDLLが出ますが、1つだけ.wxsに含めれば良いようです。私の場合、最もDLLを使うプロジェクトを、heat.exeでDLLを集めるので間に合いました。そうでなければ、DLLを集めるためだけのプロジェクトを作成し、そこにソリューション全体に渡って利用するDLLをNuGetで参照してビルドで出力・heat.exeで集めるという方法があるようです。
Orca
Orcaの利用までに手間がかかるので、
SuperOrca
を利用するのも良いです。
Directory Id="TARGETDIR" Name="SourceDir" とは
ディレクトリの構成の最初の、
<Directory Id="TARGETDIR" Name="SourceDir">
ってなんでしょうか。
によると、.msiの内部的な処理用であって開発者は気にする必要がないようです。
WiX Edit
WiX Editで、.msiを開くと、内部構成を確認できて、wxsファイルも出力されるので、参考になります。
Visual Studio Installer Projectsで作成した、.msiがあるなら、それを開いて、参考にするとWiXに移行しやすくなるでしょう。
使用許諾契約書の表示が、最初、真っ白になる
rtfによっては、表示した時に文章が何も表示されず、スクロールしたりしてから表示される不具合があります。
<WixVariable Id="WixUILicenseRtf" Value="license.rtf"/>
rtfを、WordPadで保存し直すと解決します。Wordで作成すると、複雑なrtfになるのが駄目なのかもしれません。
ショートカットの配置で、レジストリ登録
ショートカットを配置するときに、レジストリ登録を利用します。
Nameの"installed"を、ショートカット毎に変更しないといけないのかどうか、確認したいと考えました。
<RegistryValue Root="HKCU" Key="Software\MyCompany\MyApplicationName" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
How To: Create a Shortcut on the Start Menu
調べてもはっきりしなかったのは、この登録はKeyPathの確認のためだけで、アンインストール時には利用していないのでは、ということです。
複数のショートカットの配置で、同じName("installed")にしていますが、問題なくアンインストールされるようです。
32bit 64bitインストーラー
本体のプロジェクトは、Any CPUでビルドしています。そのため、Windows(64bit)なら、Program Files (x86)ではなくて、Program Filesにインストールする方法がないか調べました。
Using Wix to create 32bit and 64bit installers from one .wxs file
Build WiX 3.6 project targeting x64?
「x86とx64用に2つの別々のMSIを構築する必要がある」「両方をブートストラップされたexeファイルに入れることはできる」とコメント欄にあるので、これ以上、時間をかけて調べることを止めて終了しました。
Visual Studio Installer ProjectsのDetected Dependencies と、heat.exeで集めるDLLの数の違い
理由は分かりませんが、Installer Projectsの、Detected Dependenciesでは、プロジェクトのbinフォルダに出力されていないDLLが含まれることがあるようです。
例えば、画像の例では、System.ServiceModel.Duplex.dll~System.ServiceModel.Security.dllまで、Detected Dependenciesにはありますが、プロジェクトのbinには出力されていません。従って、heat.exeでは集められませんし、実際のアプリにも必要無いのでしょう。
履歴
- 2020/12/28 追記