Windows8.1のバージョン番号

以前の検証でもう一つ気になっていたバージョン番号の件。
Win8.1Previewでは8.2.9200というWin8と全く同じ値を返していましたが、あくまで「プレビューだから」だろうと思っていました。

ところがWin8.1RTMで検証したところ、やっぱり8.2.9200という値が。
「何で?」と思って調べたところ驚愕の結果が…

  • Win8.1RTMの内部バージョンは6.3.9600
  • ただし"Win8.1 Native Mode"で動作することを宣言しないとWin8と同じ6.2.9200というバージョン番号しか取得不能

以前Win7がリリースされたときにも

他で問題になった「実は.NETアセンブリではOSの互換モード(EXEのプロパティ>互換性タブ>互換モードでこのプログラムを実行する)は効かないのが正しい仕様でした。いままで効いていたのがバグだったので、次から効かなくなるように修正します」というトンデモないことがあったわけですが、今回のはそれをさらに上回る「ナニそれ!?」状態ですよ、まったく…

で、Win8.1 Native Modeの宣言はCompatibility manifestで行うことになります。その具体的な方法は

に解説がありますが、そこに掲示されているmanifestは一部間違っている(app→application)ので以下に正しいものを掲示しておきます。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
        <application> 
            <!-- Windows 7 -->
            <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
            <!-- Windows 8 -->
            <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
            <!-- Windows 8.1 -->
            <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
        </application> 
    </compatibility>
</assembly>

これをcompatibility.manifestというファイル名で保存しプロジェクトに登録しておくと、Visual Studio 2010のC#ではプロジェクトのプロパティで

のように選択することで、またC++ではプロジェクトに登録した時点で

となり、いずれも以降ビルドすると自動的にCompatibility manifestが埋め込まれます。

これで6.3.9600を返すようにはなるのですが、一方でこのmanifestを埋め込むとプロセスの挙動が一部変わります。
Win8.1での挙動は未だ書かれていませんが、Win7及びWin8での挙動の違いは

に説明があります。

なので、今までCompatibility manifestを埋め込んでいなかった(=Vistaモードで動いていた)既存プログラムについては、動作テストをやり直す覚悟がないと、なかなかこの対応方法は厳しいものがあります。
インストーラ系は「PCA回避」という点からもmanifestでの対応を取るしかないが…)
ということで、次回はmanifest以外での対策について。