スキップしてメイン コンテンツへ

 none
Windows8.1 で GetVersionEx を実行すると Windows8 として返ってくる RRS feed

  • 質問

  • Windows8.1 Enterprise 64ビット版 をインストールし、バージョンチェックのコードを実行したところ、バージョン6.3ではなく、6.2が返ってきてしまいました

    実行コードは以下のようなものです

    #define WIN32_LEAN_AND_MEAN
    #include <Windows.h>
    
    #include <iostream>
    
    int main(int agc, char* agv[])
    {
    	OSVERSIONINFOEX os = {0};
    	os.dwOSVersionInfoSize = sizeof(os);
    	std::cout << "retrive os version via GetVersionEx API" << std::endl;
    	if (!GetVersionEx((OSVERSIONINFO*)&os)) {
    		std::cerr << "GetVersionEx failed by " << GetLastError() << std::endl;
    		return 1;
    	}
    	std::cout << "Major:\t" << os.dwMajorVersion << std::endl;
    	std::cout << "Minor:\t" << os.dwMinorVersion << std::endl;
    	std::cout << "Build:\t" << os.dwBuildNumber << std::endl;
    	std::cout << "CSDVer:\t" << os.szCSDVersion << std::endl;
    	std::cout << "Platform:\t" << os.dwPlatformId << std::endl;
    	std::cout << "SPMajor:\t" << os.wServicePackMajor << std::endl;
    	std::cout << "SPMinor:\t" << os.wServicePackMinor << std::endl;
    	return 0;
    }
    

    実行結果は

    retrive os version via GetVersionEx API
    Major:  6
    Minor:  2
    Build:  9200
    CSDVer: 000000C9F90AFB54
    Platform:       2
    SPMajor:        0
    SPMinor:        0

    ところが、ver コマンドの出力は以下のようで

    Microsoft Windows [Version 6.3.9600]

    確かに 6.3 のようです

    上記の、コードは32ビットコンパイルでも64ビットコンパイルでも結果は同じでした

    これはOSのバグだから、修正されるまでは、このコードが使えないということでしょうか?

    あるいは既知の問題なのであれば、代表的な代替案などがあるのでしょうか?

    2014年7月15日 7:07

回答

  • GetVersionEx()に説明されています。manifestにWindows 8.1対応の記述がない場合、8.0のバージョンが返されます。

    なおこの判定はプロセス単位で行われるため、例えばIEに読み込まれたActiveXの場合、IEがWindows 8.1対応しているためにActiveX DLLは自動的に8.1の値が得られてしまいます。

    • 回答としてマーク ishizawa 2014年7月15日 8:33
    2014年7月15日 7:41

すべての返信

  • GetVersionEx()に説明されています。manifestにWindows 8.1対応の記述がない場合、8.0のバージョンが返されます。

    なおこの判定はプロセス単位で行われるため、例えばIEに読み込まれたActiveXの場合、IEがWindows 8.1対応しているためにActiveX DLLは自動的に8.1の値が得られてしまいます。

    • 回答としてマーク ishizawa 2014年7月15日 8:33
    2014年7月15日 7:41
  • なるほど、英語版には解説がありましたか

    ただ、その解説では、マニフェスト対応してしまうとOSが変わってしまっても設定した同じバージョン情報が返ってきてしまうと読よめました

    代わりに Version Helper API を使えと書いてありましたが、それらは単に、あるバージョン以降かどうかの判定しかなく、現在のOSバージョンが何なのかを GetVersionEx のように直接取得するものではないようです

    そうだとすると、 GetVersionEx は obsolete 扱いということになり、既存のプログラムのこうした部分はみな書き換えないと正しく動作しなくなると考えた方がよさそうですね

    2014年7月15日 8:33
  • もしかして日本語版ページを読まれていたのでしょうか? あればWindows 2000 / xpについて加筆されて以降、10年以上も放置されている代物です。読むほうが間違っているかと。

    OSバージョンがOS名を表すわけでもありませんし、(manifestに記載のない)未知のOSバージョン番号を表示できるようになってもあまり意味がないのでは、と思います。

    2014年7月16日 1:11
  • 自分自身を バージョン偽装する 変な Windows 8.1

    Windows 10対応アプリを作るためのマニフェスト互換情報

    あくまでも GetVersion はアプリケーションの互換性のため、そのアプリケーションを、低位のOSバージョンとして実行して不具合をなくすためのものです。

    厳密にバージョンチェックしたいのであれば、 NTDLL.DLL の RtlGetVersion や DLLからバージョン取得する方法があります。

    ちなみに、マニフェストはOSバージョンが記述されたものについてはオリジナルのOSバージョンで実行するためのもので、

    アプリケーションを固定のOSバージョンで実行するというものではありませんので誤解なきように。

    2015年6月3日 8:23