Windows Installer手引書 Part.10 VCで作ったアプリとマージモジュール

[**前の記事へ**](https://qiita.com/tohshima/items/0a197917042d705e5568)　　[**目次へ**](https://qiita.com/tohshima/items/dc4c4721d50a2ad70c7a)　　[**次の記事へ**](https://qiita.com/tohshima/items/f5aca8154ec6bcead8cd)

## マージモジュールとは
マージモジュールとは、MSIファイルと結合できるインストーラーの一部を切り離した、ライブラリのようなものです。マージモジュールはインストーラー作成時にMSIと結合するもので、結合後はどの部分がマージモジュールに含まれていたものか、MSIファイルを見ても区別がつかなくなります[^6]。そのため、ユーザーにはインストーラーにどのようなマージモジュールをマージしたか知ることはできません。

## マージモジュールの使いどころ
今回は、Visual C++のランタイムライブラリのインストールについて書いていきます。実は、これ以外の用途でマージモジュールを使ったことがありません[^1]。

従来からあるWin32 APIを使ったプログラミングでは、ほとんどの場合Visual C++が使われるのではないでしょうか。そして、Visual C++で開発されたほとんどのプログラムが、実行時にVCランタイムライブラリを必要とします[^2]。

## VCランタイムのマージモジュール
マージモジュールのファイル拡張子は`.msm`です。マージモジュールは、インストールするプログラムを開発する開発機から取得します。例えば私の開発機にはVisual Studio 2017が入っていますが、拡張子`*.msm`で検索すると、下記のフォルダにありました。
> C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Redist\MSVC\14.16.27012\MergeModules

ここにはいくつかファイルがありますが、どのファイルをマージすべきかは実装担当者が決めることです。プログラムが必要としているライブラリが何かを知っているのは、実装担当者なのですから。Win32 APIを使った一般的なプログラミムでは、たいていファイル名に`CRT`が含まれたマージモジュールを入れることになると思います。また、昔のVCでは、マージモジュール間で依存関係があり、複数のマージモジュールが必要になるケース[^5]もありました。

このほかに、マイクロソフトのサイトからダウンロードできる`再配布可能モジュール`というものもあり、拡張子が`.EXE`の実行形式のプログラムとして提供されています。これをMSI形式のインストーラーから直接呼び出すと、カスタムアクションが必要になるのと、UIに工夫が必要となる[^3]ので、あまりお勧めしません。

## VC14ランタイムライブラリは注意が必要
Windows7やWindows8の場合、VC14ランタイムライブラリは依存関係にあるライブラリ(Universal CRTというもの)が、Windows Updateで配布されています。Windows Updateは、よく不具合を起こしていて、PCに不慣れなユーザーはそれもよくわかっていない場合があります。こういう環境でVC14ランタイムライブラリを必要とするアプリを起動すると、必要なDLLが足りない、というエラーダイアログが出てしまうことがあります。そこでよく採られる手段は、アプリのインストール先にUniversal CRTのDLLも一緒にインストールしてしまう方法（[詳細はこちらのページの「Visual C++ 2015 での CRT ローカル配置について」を参照](https://blogs.msdn.microsoft.com/jpvsblog/2016/08/04/ucrt_local_deployment/)）です。Windows Update用のファイルをインストーラーに同梱する手も考えられますが、インストール時間もそれなりにかかるのと、UIを整える手間を考えると、ファイル単位で同梱したほうが簡単です。2020年1月にはWindows7のサポートも切れることですし、サポートの手間を惜しまないのであれば、Universal CRTをアプリに同梱しないのも手です。Windows10であれば、Universal CRTは最初からOSに同梱されています。

## 再配布可能VC14ランタイムライブラリの中身を見る
最近のVCランタイムライブラリはWiX Toolsetを使って`.EXE`形式にしてある[^4]ので、WiX Toolset付属のツールでバラすことができます。例えばこんな感じでコマンドを実行すると、expandディレクトリに中身が展開されます。

```
"C:\Program Files (x86)\WiX Toolset v3.11\bin\dark.exe" vcredist_x86.exe -o expand
```

以下に展開したファイルの一部を示します。
![vcredist_expanded.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83170/72af6ba0-187d-83b3-714d-d7145cfe54b2.png)
ここにある拡張子が`MSI`のファイルがVC14ランタイムインストーラーの本体。拡張子が`.msu`のファイルはWindows Updateで配布されるファイルと同等のものです。再配布可能VC14ランタイムライブラリは、確実にライブラリが機能するように、Windows Update用のファイルを同梱していることがわかります。

[**前の記事へ**](https://qiita.com/tohshima/items/0a197917042d705e5568)　　[**目次へ**](https://qiita.com/tohshima/items/dc4c4721d50a2ad70c7a)　　[**次の記事へ**](https://qiita.com/tohshima/items/f5aca8154ec6bcead8cd)

[^1]: 便利だったり有用な使い道があったら教えてほしいです。
[^2]: Visual C++の開発環境で、VCランタイムを必要としないプログラムの開発もできます。
[^3]: これをWindows Installerで呼ぼうと考えると、カスタムアクションを使用したり、UIと整えたり、結構面倒です。また、再配布可能ライブラリは、”vcredist_x86.exe /?”のようにオプションを付けて実行すると、コマンドラインオプションの一覧が表示されます。UIを最小限にしたり、UIを表示しないコマンドラインオプションがあることがわかります。
[^4]: WiX Toolsetの世界ではBundleと呼ばれる。
[^5]: 例えば、Microsoft_VC80_CRT_x86.msmはpolicy_8_0_Microsoft_VC80_CRT_x86.msmに依存しているので、両方インストールする必要があります。
[^6]: とはいえ、VCランタイムのようにいろいろな製品に汎用的に使われるマージモジュールは、各項目のIDが他とかぶらない様に長い名前がついていて、区別は容易です。