web-dev-qa-db-ja.com

Windows 10バージョンの検出

私の目的は、クロスプラットフォームだけでなく、Windowsのさまざまなバージョン(少なくとも7以降)で動作する必要があるコードでWindows 10を検出することです。 Windowsはこの問題に取り組むためにIsWindows10OrGreater()を提供していますが、これには別の問題があり、この関数は以前のバージョンのWindowsには存在しません。

無数のブログとSOこれに関する質問だけでなく、このような関数やgetversionなどの関数が正しいバージョンではなく別のバージョンを返すマニフェストの狂気を見つけるでしょう。

たとえば、私のマシンでは、メソッドIsWindows10OrGreater()はコンパイルできません(Win10 SDKをインストールする必要があります)。また、IsWindowsVersionOrGreater()は、メジャーバージョンとして6を報告します。

それで、この問題を解決できる健全なマルチバージョンの方法はありますか?

21
hg_git

IsWindows10OrGreater()VersionHelpers.hから

MSDNの Version Helper functionsでメモを確認してください

ファイルVersionHelpers.hはWindows 10 SDKに付属していますが、以前のバージョンでも機能します。開発環境にコピーするだけです。

これは、ヘッダーのみが定義された小さなlibであり、VerSetConditionMaskおよびVerifyVersionInfoW関数を使用します。どちらもWindows 2000以降のWinAPIで使用できます。

Updソースコードにマニフェストファイルを含めることができない場合は、単純なハックを使用できます。たとえば、kernel32.dllなどのシステムDLLのバージョンを取得するだけですGetFileVersionInfo関数を使用します。

2
vladon

レジストリから実際のビルド番号を読み取り、それからWindowsバージョンを推測できます。アプリケーションは、この作業のためにマニフェストを持つ必要はありません。私のマシンでは、OSビルド番号を10586として正しく検出します。次に例を示します。

#include <Windows.h>
#include <sstream>

struct HKeyHolder
{
private:
    HKEY m_Key;

public:
    HKeyHolder() :
        m_Key(nullptr)
    {
    }

    HKeyHolder(const HKeyHolder&) = delete;
    HKeyHolder& operator=(const HKeyHolder&) = delete;

    ~HKeyHolder()
    {
        if (m_Key != nullptr)
            RegCloseKey(m_Key);
    }

    operator HKEY() const
    {
        return m_Key;
    }

    HKEY* operator&()
    {
        return &m_Key;
    }
};

bool IsRunningOnWindows10()
{
    HKeyHolder currentVersion;
    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, LR"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", 0, KEY_QUERY_VALUE, &currentVersion) != ERROR_SUCCESS)
        return false;

    DWORD valueType;
    BYTE buffer[256];
    DWORD bufferSize = 256;

    if (RegQueryValueExW(currentVersion, L"CurrentBuild", nullptr, &valueType, buffer, &bufferSize) != ERROR_SUCCESS)
        return false;

    if (valueType != REG_SZ)
        return false;

    int version;
    std::wistringstream versionStream(reinterpret_cast<wchar_t*>(buffer));
    versionStream >> version;

    return version > 9800;
}
0
Sunius