Windows 10 SDK を使って開発されたアプリケーションを動作させるためには、システムに Universal CRT (Windows 10 Universal C Runtime) がインストールされている必要があります。
そこで Universal CRT がインストールされているかどうか確認するためのプログラムを書いてみました。
BOOL IsUniversalCRTInstalled() { LPCWSTR lpszSearchPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\SideBySide\\Winners"; std::vector<std::wstring>keylist; WCHAR szTemp[1024]; HKEY hKey; if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, lpszSearchPath, 0, KEY_READ | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS) { DWORD cSubKeys = 0; if (RegQueryInfoKeyW(hKey, 0, 0, 0, &cSubKeys, 0, 0, 0, 0, 0, 0, 0) == ERROR_SUCCESS && cSubKeys) { for (DWORD i = 0; i < cSubKeys; ++i) { DWORD cbName = _countof(szTemp); if (RegEnumKeyExW(hKey, i, szTemp, &cbName, 0, 0, 0, 0) == ERROR_SUCCESS) { for (auto architecture : { L"x86", L"amd64", L"wow64" }) { if (szTemp[0] != architecture[0]) continue; WCHAR szKey[1024]; lstrcpyW(szKey, architecture); lstrcatW(szKey, L"_microsoft-windows-ucrt_31bf3856ad364e35"); const int nKeyLength = lstrlenW(szKey); if (CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, szKey, nKeyLength, szTemp, nKeyLength) == CSTR_EQUAL) { keylist.push_back(szTemp); } } } } } RegCloseKey(hKey); } if (keylist.size() == 0) { return FALSE; } for (auto key : keylist) { lstrcpyW(szTemp, lpszSearchPath); lstrcatW(szTemp, L"\\"); lstrcatW(szTemp, key.c_str()); if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szTemp, 0, KEY_READ | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS) { DWORD dwType = REG_SZ; DWORD cbName = _countof(szTemp); if (RegQueryValueEx(hKey, 0, 0, &dwType, (LPBYTE)szTemp, &cbName) == ERROR_SUCCESS) { if (lstrlenW(szTemp) > 0) { RegCloseKey(hKey); return TRUE; } } RegCloseKey(hKey); } } return FALSE; }
Universal CRT がインストールがインストールされている環境では、レジストリのパス “SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide\Winners” に
- x86_microsoft-windows-ucrt_31bf3856ad364e35
- amd64_microsoft-windows-ucrt_31bf3856ad364e35
- wow64_microsoft-windows-ucrt_31bf3856ad364e35
から始まるレジストリキーが存在し、そのレジストリキーに対する “(既定)” 値にデータが入っているようだったので、データが入っているかどうかで判定処理を行っています。
もっと単純に、LoadLibrary 関数で Universal CRT のメインの DLL である “ucrtbase.dll” がロードできるかどうかで判定を行ってもよいかもしれません。
HMODULE hModule = LoadLibrary(TEXT("ucrtbase.dll")); if (hModule) { MessageBox(hWnd, TEXT("Universal CRT はインストールされています。"), TEXT("確認"), 0); FreeLibrary(hModule); } else { MessageBox(hWnd, TEXT("Universal CRT はインストールされていません。"), TEXT("確認"), 0); }
上記のプログラムで「上手く判定できなかった」などがございましたらコメントにてお伝えいただければ幸いです。