2016年12月4日

主な実装における EUC-JIS-2004, Shift_JIS-2004 から Unicode への変換結果の違い

まとめました。


nkfとiconvの差異
https://nathancorvussolis.blogspot.jp/2015/05/difference-between-nkf-and-iconv.html

Pythonとiconvの差異
https://nathancorvussolis.blogspot.jp/2016/11/difference-between-python-and-iconv.html

JavaのShift_JIS-2004については下記のブログを引用させていただきました。
iconv、Java、PythonのJISX0213 - yuan-jiu blog
http://yuan-jiu.asablo.jp/blog/2013/05/11/6807043


バージョン

libiconv 1.14
nkf 2.1.4
Python 3.4.5
Java 1.7.0_21


EUC-JIS-2004


EUC-JIS-2004iconvnkfPython
0xA1B1 U+FFE3 U+203E U+FFE3
0xA1EF U+FFE5 ¥U+00A5U+FFE5
0xA1BD U+2014 U+2014 U+2015
0xA2D6 U+FF5F U+FF5FU+2985
0xA2D7 U+FF60 U+FF60 U+2986

http://x0213.org/codetable/euc-jis-2004-std.txt より抜粋
0xA1B1  U+203E  # OVERLINE  Windows: U+FFE3
0xA1BD  U+2014  # EM DASH  Windows: U+2015
0xA1EF  U+00A5  # YEN SIGN  Windows: U+FFE5
0xA2D6  U+FF5F  # FULLWIDTH LEFT WHITE PARENTHESIS  [2000]  [Unicode3.2]
0xA2D7  U+FF60  # FULLWIDTH RIGHT WHITE PARENTHESIS  [2000]  [Unicode3.2]

EUC-JIS-2004 については FULLWIDTH かどうかの違いくらいしかないので、それほど問題はなさそうです。
Python の 0xA2D6 → U+2985 と 0xA2D7 → U+2986 はちょっとどうなの?と思ってしまいますが。


Shift_JIS-2004


Shift_JIS-2004iconvnkfPythonJava
0x5C ¥U+00A5 \U+005C ¥U+00A5 \U+005C
0x7E U+203E ~U+007E U+203E ~U+007E
0x8150 U+FFE3 U+203E U+FFE3 U+FFE3
0x815C U+2014 U+2014 U+2015 U+2014
0x815F U+FF3C U+FF3C \U+005C U+FF3C
0x818F U+FFE5 ¥U+00A5 U+FFE5 U+FFE5
0x81B0 U+FF5E U+FF5E ~U+007E U+FF5E
0x81D4 U+FF5F U+FF5F U+2985 U+FF5F
0x81D5 U+FF60 U+FF60 U+2986 U+FF60

http://x0213.org/codetable/sjis-0213-2004-std.txt より抜粋
0x5C    U+00A5  # YEN SIGN
0x7E    U+203E  # OVERLINE
0x8150  U+FFE3  # FULLWIDTH MACRON
0x815C  U+2014  # EM DASH  Windows: U+2015
0x815F  U+005C  # REVERSE SOLIDUS  Fullwidth: U+FF3C
0x818F  U+FFE5  # FULLWIDTH YEN SIGN
0x81B0  U+007E  # TILDE  [2000]  Fullwidth: U+FF5E
0x81D4  U+FF5F  # FULLWIDTH LEFT WHITE PARENTHESIS  [2000]  [Unicode3.2]
0x81D5  U+FF60  # FULLWIDTH RIGHT WHITE PARENTHESIS  [2000]  [Unicode3.2]

こうして見てみると、Python の 0x815F → U+005C がはまりポイントになりそうですね。

2016年11月30日

Pythonとiconvの差異

PythonとiconvとでJIS系文字コードとUnicodeとの変換にどれくらい違いがあるのか調べてみました。

EUC-JIS-2004とShift_JIS-2004のファイルをそれぞれUTF-8に変換して、その結果を比較します。

Python
https://www.python.org/
 
libiconv
http://www.gnu.org/software/libiconv/

変換元となるファイルについては、プロジェクトX0213の「JIS X 0213とUnicodeの対応表」から、文字付き版のファイルを使用しました。

JIS X 0213とUnicodeの対応表
http://x0213.org/codetable/

EUC-JIS-2004とUnicodeの対応表 文字付き版
http://x0213.org/codetable/euc-jis-2004-with-char.txt
Shift_JIS-2004とUnicodeの対応表  文字付き版
http://x0213.org/codetable/sjis-0213-2004-with-char.txt

今回使用した環境、バージョンは以下の通りです。

  • cygwin 2.6.0 (0.304/5/3)
  • Python 3.4.5
  • libiconv 1.14

追記: Pythonでの変換に使用した pconv.py は以下のようなコードです。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#

import codecs
import sys

if __name__ == "__main__":
    if (len(sys.argv) != 5):
        print('usage: python pconv.py <enc_from> <inputfile> <enc_to> <outputfile>')
        sys.exit(1)

    for arg in sys.argv:
        print(arg)

    output = codecs.open(sys.argv[4], 'w', sys.argv[3])

    for line in codecs.open(sys.argv[2], 'r', sys.argv[1]):
        try:
            output.write(line)
        except UnicodeEncodeError:
            print('UnicodeEncodeError')
            break

    output.close()

EUC-JIS-2004

$ python3 pconv.py euc_jis_2004 euc-jis-2004-with-char.txt utf_8 euc-jis-2004-python.txt
$ iconv -f EUC-JIS-2004 -t UTF-8 euc-jis-2004-with-char.txt > euc-jis-2004-iconv.txt
$ diff euc-jis-2004-python.txt euc-jis-2004-iconv.txt > diff-euc-jis-2004.txt
追記: diff-euc-jis-2004.txt
216c216
< ―    0xA1BD    U+2014    # EM DASH    Windows: U+2015
---
> —    0xA1BD    U+2014    # EM DASH    Windows: U+2015
335,336c335,336
< ⦅    0xA2D6    U+FF5F    # FULLWIDTH LEFT WHITE PARENTHESIS    [2000]    [Unicode3.2]
< ⦆    0xA2D7    U+FF60    # FULLWIDTH RIGHT WHITE PARENTHESIS    [2000]    [Unicode3.2]
---
> ⦅    0xA2D6    U+FF5F    # FULLWIDTH LEFT WHITE PARENTHESIS    [2000]    [Unicode3.2]
> ⦆    0xA2D7    U+FF60    # FULLWIDTH RIGHT WHITE PARENTHESIS    [2000]    [Unicode3.2]

EUC-JIS-2004の変換では、3つの文字で異なる変換結果が得られました。

  • 0xA1BD EM DASH
    • Python U+2015
    • iconv U+2014
  • 0xA2D6 FULLWIDTH LEFT WHITE PARENTHESIS
    • Python U+2985
    • iconv U+FF5F
  • 0xA2D7 FULLWIDTH RIGHT WHITE PARENTHESIS
    • Python U+2986
    • iconv U+FF60

Shift_JIS-2004

$ python3 pconv.py shift_jis_2004 sjis-0213-2004-with-char.txt utf_8 sjis-0213-2004-python.txt
$ iconv -f Shift_JIS-2004 -t UTF-8  sjis-0213-2004-with-char.txt > sjis-0213-2004-iconv.txt
$ diff sjis-0213-2004-python.txt sjis-0213-2004-iconv.txt > diff-sjis-0213-2004.txt
追記: diff-sjis-0213-2004.txt
310c310
< ―    0x815C    U+2014    # EM DASH    Windows: U+2015
---
> —    0x815C    U+2014    # EM DASH    Windows: U+2015
313c313
< \    0x815F    U+005C    # REVERSE SOLIDUS    Fullwidth: U+FF3C
---
> \    0x815F    U+005C    # REVERSE SOLIDUS    Fullwidth: U+FF3C
393c393
< ~    0x81B0    U+007E    # TILDE    [2000]    Fullwidth: U+FF5E
---
> ~    0x81B0    U+007E    # TILDE    [2000]    Fullwidth: U+FF5E
429,430c429,430
< ⦅    0x81D4    U+FF5F    # FULLWIDTH LEFT WHITE PARENTHESIS    [2000]    [Unicode3.2]
< ⦆    0x81D5    U+FF60    # FULLWIDTH RIGHT WHITE PARENTHESIS    [2000]    [Unicode3.2]
---
> ⦅    0x81D4    U+FF5F    # FULLWIDTH LEFT WHITE PARENTHESIS    [2000]    [Unicode3.2]
> ⦆    0x81D5    U+FF60    # FULLWIDTH RIGHT WHITE PARENTHESIS    [2000]    [Unicode3.2]

Shift_JIS-2004の変換では、5つの文字で異なる変換結果が得られました。

  • 0x815C EM DASH
    • Python U+2015
    • iconv U+2014
  • 0x815F REVERSE SOLIDUS
    • Python U+005C
    • iconv U+FF3C
  • 0x81B0 TILDE
    • Python U+007E
    • iconv U+FF5E
  • 0x81D4 FULLWIDTH LEFT WHITE PARENTHESIS
    • Python U+2985
    • iconv U+FF5F
  • 0x81D5 FULLWIDTH RIGHT WHITE PARENTHESIS
    • Python U+2986
    • iconv U+FF60

まとめ


FULLWIDTH LEFT WHITE PARENTHESIS と FULLWIDTH RIGHT WHITE PARENTHESIS が FULLWIDTH でなくなってしまうのが、Pythonのいまいちな点でしょうか。

今回の使用・作成したファイルをGitHubに上げていますので、興味のある方はご覧ください。
https://github.com/nathancorvussolis/difference-between-python-and-iconv

さらに追記:
すでにShift_JIS-2004の変換をまとめている方がおられたのでリンクしておきます。
iconv、Java、PythonのJISX0213 - yuan-jiu blog
http://yuan-jiu.asablo.jp/blog/2013/05/11/6807043

2016年10月15日

Universal CRT in Wix Bootstrapper (3)

Universal CRT を含めた WiX の Bootstrapperwxs ファイルのサンプルです。

今回は、DownloadUrl 属性を使ってみました。インストール時に自動的にダウンロードされます。

Universal CRT は VC++再配布パッケージに含まれているので、そのサンプルも貼っておきます。

注意点ですが、MsuPackage / ExePackage タグの Name 属性と同じ名前のファイルが ブートストラップの exe と同じディレクトリに存在していると、DownloadUrl 属性の URL からダウンロードされずにローカルのファイルが使われてしまいます。

こんな感じでビルドしてください。

> "%WIX%bin\candle.exe" xxx.wxs -nologo -out "xxx.wixobj" -ext WixBalExtension -ext WixUtilExtension
> "%WIX%bin\light.exe" "xxx.wixobj" -nologo -out "xxx.exe" -ext WixBalExtension -ext WixUtilExtension

【参考】

ExePackage Element
http://wixtoolset.org/documentation/manual/v3/xsd/wix/exepackage.html

MsuPackage Element
http://wixtoolset.org/documentation/manual/v3/xsd/wix/msupackage.html

RemotePayload Element
http://wixtoolset.org/documentation/manual/v3/xsd/wix/remotepayload.html

Download Microsoft Visual C++ 2015 Redistributable Update 3 from Official Microsoft Download Center
https://www.microsoft.com/en-us/download/details.aspx?id=53840

Update for Universal C Runtime in Windows
https://support.microsoft.com/en-us/kb/2999226






2016年7月9日

オンラインストレージとCorvusSKK


CorvusSKKの設定ファイルや個人辞書は、"%AppData%\CorvusSKK" ディレクトリに保存されます。

次の記事を参考に、自動的にオンラインストレージへバックアップするためのコマンドプロンプトでの設定方法をまとめてみました。

Windows の CorvusSKK で Azik + Google 日本語入力の変換を利用。設定ファイルはクラウドへ保存。

Tech TIPS:Windowsのシンボリックリンクとジャンクションとハードリンクの違い


私はOneDriveで確認しましたが、Google Drive、Dropboxなどでも同様の設定で使えると思います。

ここでは、オンラインストレージソフトが管理するディレクトリを仮に "C:\OnlineStorage\CorvusSKK" としています。適宜環境に合わせて変更してください。

  1. 辞書管理プロセスを終了します。
  2. > taskkill /im imcrvmgr.exe
  3. %AppData%\CorvusSKK ディレクトリをオンラインストレージソフトが管理するディレクトリにコピーします。
  4. > xcopy /ei "%AppData%\CorvusSKK" "C:\OnlineStorage\CorvusSKK"
  5. %AppData%\CorvusSKK ディレクトリを削除します。
  6. > rd /s /q "%AppData%\CorvusSKK"
  7. オンラインストレージソフトが管理するディレクトリへのシンボリックリンク %AppData%\CorvusSKK を作成します。(要管理者権限)
  8. > mklink /d "%AppData%\CorvusSKK" "C:\OnlineStorage\CorvusSKK"
    追記 : ジャンクションでも良いようです。こちらであれば管理者権限は不要です。
    > mklink /j "%AppData%\CorvusSKK" "C:\OnlineStorage\CorvusSKK"
  9. 辞書管理プロセスを再開します。
  10. > "%SystemRoot%\System32\IME\IMCRVSKK\imcrvmgr.exe"

ちなみに、複数のPCやユーザーで、ローカルおよびリモートの同じディレクトリを使ってしまうとお互いに上書きしあってしまいますので注意してください。

オンラインストレージサービスの規約や使い方をよく確認してご利用ください。

2016年4月20日

Disable Light Bulb

Visual Studio 2015 Update 2 の C++ のプロジェクトですが、緑の下線と共に電球が表示されて、関数定義が無いとのメッセージが表示されることがあります。




これ、Visual Studio 2015 の新機能だそうで、light bulb (電球?)と呼ぶそうです。

Perform quick actions with light bulbs
https://msdn.microsoft.com/en-us/library/dn872466.aspx

しかし、まだあまり賢くないようなので無効にしました。

Option → Text Editor → C/C++ → Advanced → Refactoring → Disable Create Declaration/Definition Light Bulbs を、False から True に変更します。




 警告が消えました。


2016年4月11日

Universal CRT in Wix Bootstrapper (2)

前回、Universal CRTを含めたWiXのBootstrapperwxsファイルを作ってみましたが、インストール条件が長ったらしくなってしまいました。
そこで、ucrtbase.dllファイルのチェックをSystem32ディレクトリに限定し、MsuPackage要素にDetectCondition属性を使ってみました。
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
  xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
  xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

  <Bundle Name="Example Product" Version="1.2.3.4" Manufacturer="John Doe"
    Copyright="© 2016 John Doe" AboutUrl="https://example.com/"
    UpgradeCode="01234567-89AB-CDEF-0123-456789ABCDEF" Condition="VersionNT &gt;= v5.1">

    <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
      <bal:WixStandardBootstrapperApplication
        LicenseFile="license.rtf" ShowVersion="yes" SuppressOptionsUI="yes" />
    </BootstrapperApplicationRef>

    <!-- v6.0 Service Pack 2 -->
    <bal:Condition Message="This application requires Service Pack 2 for Windows Vista / Server 2008.">
      (VersionNT &lt;&gt; v6.0) OR (VersionNT = v6.0 AND ServicePackLevel &gt;= 2)
    </bal:Condition>

    <!-- v6.1 Service Pack 1 -->
    <bal:Condition Message="This application requires Service Pack 1 for Windows 7 / Server 2008 R2.">
      (VersionNT &lt;&gt; v6.1) OR (VersionNT = v6.1 AND ServicePackLevel &gt;= 1)
    </bal:Condition>

    <!-- v6.3 KB2919355 -->
    <util:FileSearch Id="HAL.DLL" Path="[WindowsFolder]System32\hal.dll"
      Result="version" Variable="NT603HALVER" Condition="VersionNT = v6.3" />
    <bal:Condition Message="This application requires S14 Update (KB2919355) for Windows 8.1 / Server 2012 R2.">
      (VersionNT &lt;&gt; v6.3) OR (VersionNT = v6.3 AND NT603HALVER &gt; v6.3.9600.16500)
    </bal:Condition>

    <!-- ucrtbase.dll version -->
    <util:FileSearch Id="UCRTBASE.DLL" Path="[WindowsFolder]System32\ucrtbase.dll"
      Result="version" Variable="UCRTBASEVER" />
    <!-- universal crt version -->
    <Variable Name="UCRTVER" Type="version" Value="10.0.10586.0" />

    <Chain>

      <!-- Windows Vista / Windows Server 2008 (x86) -->
      <MsuPackage Name="Windows6.0-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows6.0-KB3118401-x86.msu" InstallCondition="VersionNT = v6.0 AND NOT VersionNT64"
        DetectCondition="VersionNT = v6.0 AND NOT VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows Vista / Windows Server 2008 (x64) -->
      <MsuPackage Name="Windows6.0-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows6.0-KB3118401-x64.msu" InstallCondition="VersionNT = v6.0 AND VersionNT64"
        DetectCondition="VersionNT = v6.0 AND VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows 7 (x86) -->
      <MsuPackage Name="Windows6.1-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows6.1-KB3118401-x86.msu" InstallCondition="VersionNT = v6.1 AND NOT VersionNT64"
        DetectCondition="VersionNT = v6.1 AND NOT VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows 7 / Windows Server 2008 R2 (x64) -->
      <MsuPackage Name="Windows6.1-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows6.1-KB3118401-x64.msu" InstallCondition="VersionNT = v6.1 AND VersionNT64"
        DetectCondition="VersionNT = v6.1 AND VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows 8 (x86) -->
      <MsuPackage Name="Windows8-RT-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows8-RT-KB3118401-x86.msu" InstallCondition="VersionNT = v6.2 AND NOT VersionNT64"
        DetectCondition="VersionNT = v6.2 AND NOT VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows 8 / Windows Server 2012 (x64) -->
      <MsuPackage Name="Windows8-RT-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows8-RT-KB3118401-x64.msu" InstallCondition="VersionNT = v6.2 AND VersionNT64"
        DetectCondition="VersionNT = v6.2 AND VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows 8.1 (x86) -->
      <MsuPackage Name="Windows8.1-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows8.1-KB3118401-x86.msu" InstallCondition="VersionNT = v6.3 AND NOT VersionNT64"
        DetectCondition="VersionNT = v6.3 AND NOT VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- Windows 8.1 / Windows Server 2012 R2 (x64) -->
      <MsuPackage Name="Windows8.1-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Cache="no" Compressed="yes" Permanent="yes"
        SourceFile="Windows8.1-KB3118401-x64.msu" InstallCondition="VersionNT = v6.3 AND VersionNT64"
        DetectCondition="VersionNT = v6.3 AND VersionNT64 AND UCRTBASEVER &gt;= UCRTVER" />

      <!-- x64 modules -->
      <MsiPackage Id="X64" DisplayName="x64 modules" ForcePerMachine="yes" Compressed="yes"
        SourceFile="x64.msi" InstallCondition="VersionNT64" />

      <!-- x86 modules -->
      <MsiPackage Id="X86" DisplayName="x86 modules" ForcePerMachine="yes" Compressed="yes"
        SourceFile="x86.msi" After="X64" />

    </Chain>

  </Bundle>

</Wix>

ちょっとすっきり。

2016年3月23日

Universal CRT in WiX Bootstrapper


Visual Studio 2013 の Visual C++ の各種ライブラリを配布するには以下の方法があります。
  1. スタティックリンクでビルドする
  2. マージモジュールを使用する (Microsoft_VC120_CRT_x86.msm, Microsoft_VC120_CRT_x64.msm など)
  3. Visual C++ 再頒布可能パッケージをインストールする (vcredist_x86.exe, vcredist_x64.exe)
  4. インストーラーにDLLを同梱する (msvr120.dll, msvcp120.dll など)
Visual Studio 2015 の Visual C++ では Universal CRT が導入された影響で配布方法に若干の変更が入っています。

Introducing the Universal CRT | Visual C++ Team Blog
https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/

既に解説されている方々がおられるのでいくつかリンクしておきます。

VC++2015製のアプリを配る際のランタイムDLLの扱い | イグトランスの頭の中
http://dev.activebasic.com/egtra/2015/08/30/831/

Visual C++ 14 (VS2015RC)のランタイムをインストールする | espresso3389の日記
http://espresso3389.hatenablog.com/entry/2015/05/08/033946



上記1番のスタティックリンクと3番の再配布可能パッケージについては、まあ従来通りですね。

上記4番のDLL同梱では、"%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\redist" ディレクトリ内のファイル (vcruntime140.dll, msvcp140.dll など) に加えて、"%ProgramFiles(x86)%\Windows Kits\10\Redist" ディレクトリ内のファイル (ucrtbase.dll, api-ms-win-core-******.dll, api-ms-win-crt-******.dll) を同梱します。

上記2番のマージモジュールでは、従来のマージモジュールに加えて以下の Universal CRT の msu ファイルをインストーラーに含めてインストールするために、WiX であれば Bootstrapper にしてしまうのが良さそうです。再頒布可能パッケージと同じような方法ですね。

Windows 10 Universal C Runtime (KB2999226) (10.0.10240)
https://www.microsoft.com/ja-JP/download/details.aspx?id=48234
https://support.microsoft.com/en-us/kb/2999226

Windows 10 Universal C Runtime (KB3118401) (10.0.10586)
https://www.microsoft.com/ja-JP/download/details.aspx?id=50410
https://support.microsoft.com/en-us/kb/3118401

msu ファイルには現在2つのバージョンがあるのですが、Windows Update で降ってくるのはKB3118401、Visual Studio 2015 Update 1 の Visual C++ 再頒布可能パッケージに含まれているのはKB2999226になっています。どちらでも使えそうなのですが、とりあえず新しいKB3118401のほうを 使ってみます。

Visual Studio 2015 Update 1 の Visual C++ 再頒布可能パッケージ
https://www.microsoft.com/ja-jp/download/details.aspx?id=49984

XP 用の msu ファイルが見当たらないですが、XP 用の Universal CRT はマージモジュール (Microsoft_VC140_CRT_x86.msm, Microsoft_VC140_CRT_x64.msm) に含まれているようです。

で、msu ファイルを含めた Bootstrapper をさっくりと作ってみました。msu ファイルのシステム要件のチェックも入れつつ、インストール済みかどうかも一応チェックしています。msi ファイルについてはマージモジュールを含んだものとします。所々枠からはみ出してしまっていますがご容赦を。

追記 : 下記のwxsを書き直しました。
Universal CRT in Wix Bootstrapper (2)


TestUCRT.wxs

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
  xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
  xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

  <Bundle Name="program name" Version="1.0.0.0" Manufacturer="author name"
    UpgradeCode="12345678-9012-3456-7890-123456789012"
    Condition="VersionNT &gt;= v5.1" >

    <BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
      <bal:WixStandardBootstrapperApplication
        LicenseFile="license.rtf" SuppressOptionsUI="yes" />
    </BootstrapperApplicationRef>

    <!-- v6.0 Service Pack 2 -->
    <bal:Condition Message="This application requires Service Pack 2 for Windows Vista / Server 2008.">
      (VersionNT &lt;&gt; v6.0) OR ((VersionNT = v6.0) AND (ServicePackLevel &gt;= 2))
    </bal:Condition>

    <!-- v6.1 Service Pack 1 -->
    <bal:Condition Message="This application requires Service Pack 1 for Windows 7 / Server 2008 R2.">
      (VersionNT &lt;&gt; v6.1) OR ((VersionNT = v6.1) AND (ServicePackLevel &gt;= 1))
    </bal:Condition>

    <!-- v6.3 KB2919355 -->
    <util:FileSearch Id="HAL.DLL" Path="[WindowsFolder]System32\hal.dll"
      Result="version" Variable="NT603HALVER" Condition="VersionNT = v6.3" />
    <bal:Condition Message="This application requires S14 Update (KB2919355) for Windows 8.1 / Server 2012 R2.">
      (VersionNT &lt;&gt; v6.3) OR ((VersionNT = v6.3) AND (NT603HALVER &gt; v6.3.9600.16500))
    </bal:Condition>

    <!-- installed ucrtbase.dll version -->
    <util:FileSearch Id="UCRTBASE.DLL_SYS" Path="[WindowsFolder]System32\ucrtbase.dll"
      Result="version" Variable="UCRTVERSYS" />
    <util:FileSearch Id="UCRTBASE.DLL_X86" Path="[WindowsFolder]SysWOW64\ucrtbase.dll"
      Result="version" Variable="UCRTVERX86" Condition="VersionNT64" />
    <!-- KB3118401 ucrtbase.dll version -->
    <Variable Name="UCRTVER" Type="version" Value="10.0.10586.9" />

    <Chain>

      <!-- Windows Vista / Windows Server 2008 (x86) -->
      <MsuPackage Name="Windows6.0-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows6.0-KB3118401-x86.msu"
        InstallCondition="(VersionNT = v6.0) AND (NOT VersionNT64) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER))" />

      <!-- Windows Vista / Windows Server 2008 (x64) -->
      <MsuPackage Name="Windows6.0-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows6.0-KB3118401-x64.msu"
        InstallCondition="(VersionNT64 = v6.0) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER) OR (NOT UCRTVERX86) OR (UCRTVERX86 &lt; UCRTVER))" />

      <!-- Windows 7 (x86) -->
      <MsuPackage Name="Windows6.1-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows6.1-KB3118401-x86.msu"
        InstallCondition="(VersionNT = v6.1) AND (NOT VersionNT64) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER))" />

      <!-- Windows 7 / Windows Server 2008 R2 (x64) -->
      <MsuPackage Name="Windows6.1-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows6.1-KB3118401-x64.msu"
        InstallCondition="(VersionNT64 = v6.1) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER) OR (NOT UCRTVERX86) OR (UCRTVERX86 &lt; UCRTVER))" />

      <!-- Windows 8 (x86) -->
      <MsuPackage Name="Windows8-RT-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows8-RT-KB3118401-x86.msu"
        InstallCondition="(VersionNT = v6.2) AND (NOT VersionNT64) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER))" />

      <!-- Windows 8 / Windows Server 2012 (x64) -->
      <MsuPackage Name="Windows8-RT-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows8-RT-KB3118401-x64.msu"
        InstallCondition="(VersionNT64 = v6.2) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER) OR (NOT UCRTVERX86) OR (UCRTVERX86 &lt; UCRTVER))" />

      <!-- Windows 8.1 (x86) -->
      <MsuPackage Name="Windows8.1-KB3118401-x86.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows8.1-KB3118401-x86.msu"
        InstallCondition="(VersionNT = v6.3) AND (NOT VersionNT64) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER))" />

      <!-- Windows 8.1 / Windows Server 2012 R2 (x64) -->
      <MsuPackage Name="Windows8.1-KB3118401-x64.msu"
        DisplayName="Universal CRT" KB="KB3118401" Permanent="yes" Cache="no"
        SourceFile="Windows8.1-KB3118401-x64.msu"
        InstallCondition="(VersionNT64 = v6.3) AND ((NOT UCRTVERSYS) OR (UCRTVERSYS &lt; UCRTVER) OR (NOT UCRTVERX86) OR (UCRTVERX86 &lt; UCRTVER))" />

      <!-- x64 modules -->
      <MsiPackage Id="X64" DisplayName="x64 modules" ForcePerMachine="yes"
        Compressed="yes" SourceFile="x64.msi" InstallCondition="VersionNT64" />

      <!-- x86 modules -->
      <MsiPackage Id="X86" DisplayName="x86 modules" ForcePerMachine="yes"
        Compressed="yes" SourceFile="x86.msi" />

    </Chain>
  </Bundle>
</Wix>

で、ビルトはこんな感じで。
> candle.exe TestUCRT.wxs -out TestUCRT.wixobj -ext WixBalExtension -ext WixUtilExtension
> light.exe TestUCRT.wixobj -out TestUCRT.exe -ext WixBalExtension -ext WixUtilExtension

msu ファイルの替わりにExePackageタグを使って再配布可能パッケージを入れてもいいのですが、再配布パッケージに含まれる msu ファイルが VC_redist.x86.exe と VC_redist.x64.exe とで重複してしまうので、x86とx64両方のバイナリをインストールする必要がある場合はファイルサイズがその分大きくなってしまうのが難点ですね。
再配布パッケージの内容物は次のコマンドで展開することで確認できます。
> dark.exe VC_redist.x86.exe -x x86
> dark.exe VC_redist.x64.exe -x x64