【发布时间】:2011-02-22 01:36:52
【问题描述】:
如何获取所有windows的操作系统版本,至少win95,98,me,xp,vista,7的名称?
我正在使用 Visual c++ 2010,我想将此功能包含在纯 win32 应用程序中。
【问题讨论】:
标签: c++ windows winapi operating-system
如何获取所有windows的操作系统版本,至少win95,98,me,xp,vista,7的名称?
我正在使用 Visual c++ 2010,我想将此功能包含在纯 win32 应用程序中。
【问题讨论】:
标签: c++ windows winapi operating-system
这样的事情怎么样:
#include <windows.h>
#include <string>
#include <lm.h>
#pragma comment(lib, "netapi32.lib")
bool GetWinMajorMinorVersion(DWORD& major, DWORD& minor)
{
bool bRetCode = false;
LPBYTE pinfoRawData = 0;
if (NERR_Success == NetWkstaGetInfo(NULL, 100, &pinfoRawData))
{
WKSTA_INFO_100* pworkstationInfo = (WKSTA_INFO_100*)pinfoRawData;
major = pworkstationInfo->wki100_ver_major;
minor = pworkstationInfo->wki100_ver_minor;
::NetApiBufferFree(pinfoRawData);
bRetCode = true;
}
return bRetCode;
}
std::string GetWindowsVersionString()
{
std::string winver;
OSVERSIONINFOEX osver;
SYSTEM_INFO sysInfo;
typedef void(__stdcall *GETSYSTEMINFO) (LPSYSTEM_INFO);
__pragma(warning(push))
__pragma(warning(disable:4996))
memset(&osver, 0, sizeof(osver));
osver.dwOSVersionInfoSize = sizeof(osver);
GetVersionEx((LPOSVERSIONINFO)&osver);
__pragma(warning(pop))
DWORD major = 0;
DWORD minor = 0;
if (GetWinMajorMinorVersion(major, minor))
{
osver.dwMajorVersion = major;
osver.dwMinorVersion = minor;
}
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2)
{
OSVERSIONINFOEXW osvi;
ULONGLONG cm = 0;
cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_EQUAL);
ZeroMemory(&osvi, sizeof(osvi));
osvi.dwOSVersionInfoSize = sizeof(osvi);
osvi.dwMinorVersion = 3;
if (VerifyVersionInfoW(&osvi, VER_MINORVERSION, cm))
{
osver.dwMinorVersion = 3;
}
}
GETSYSTEMINFO getSysInfo = (GETSYSTEMINFO)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetNativeSystemInfo");
if (getSysInfo == NULL) getSysInfo = ::GetSystemInfo;
getSysInfo(&sysInfo);
if (osver.dwMajorVersion == 10 && osver.dwMinorVersion >= 0 && osver.wProductType != VER_NT_WORKSTATION) winver = "Windows 10 Server";
if (osver.dwMajorVersion == 10 && osver.dwMinorVersion >= 0 && osver.wProductType == VER_NT_WORKSTATION) winver = "Windows 10";
if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 3 && osver.wProductType != VER_NT_WORKSTATION) winver = "Windows Server 2012 R2";
if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 3 && osver.wProductType == VER_NT_WORKSTATION) winver = "Windows 8.1";
if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2 && osver.wProductType != VER_NT_WORKSTATION) winver = "Windows Server 2012";
if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2 && osver.wProductType == VER_NT_WORKSTATION) winver = "Windows 8";
if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1 && osver.wProductType != VER_NT_WORKSTATION) winver = "Windows Server 2008 R2";
if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1 && osver.wProductType == VER_NT_WORKSTATION) winver = "Windows 7";
if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0 && osver.wProductType != VER_NT_WORKSTATION) winver = "Windows Server 2008";
if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0 && osver.wProductType == VER_NT_WORKSTATION) winver = "Windows Vista";
if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 2 && osver.wProductType == VER_NT_WORKSTATION
&& sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) winver = "Windows XP x64";
if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 2) winver = "Windows Server 2003";
if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 1) winver = "Windows XP";
if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 0) winver = "Windows 2000";
if (osver.dwMajorVersion < 5) winver = "unknown";
if (osver.wServicePackMajor != 0)
{
std::string sp;
char buf[128] = { 0 };
sp = " Service Pack ";
sprintf_s(buf, sizeof(buf), "%hd", osver.wServicePackMajor);
sp.append(buf);
winver += sp;
}
return winver;
}
【讨论】:
【讨论】:
Minimum supported client: Windows 2000 Professional
GetVersionEx 已被弃用,它将为高于 8 的任何 Windows 返回 8,除非您在清单中明确定位更高版本。
看看MSDN文章Getting the System Version
虽然本文仅提及当前支持的 Windows 版本,但请参阅 knowledge base article 了解您将在 Win 95、98 等的 OSVERSIONINFO 结构中看到的数字。
【讨论】:
这完全取决于您为什么需要知道操作系统版本:
使用旧操作系统中可能不可用的某些功能。在这种情况下,我强烈建议使用LoadLibrary 和GetProcAddress 函数检查API 本身是否可用。否则,我想您可以从ntdll.dll 动态导入RtlGetVersion 并使用它,但同样,它可以返回不准确信息的方式太多(想到的是兼容模式和API trampolines 可以由恶意软件、AVP 甚至操作系统本身安装。)
仅用于显示目的。(例如:在您的应用程序的 About 窗口中,或将其包含在您的诊断事件日志中等)在这种情况下,一个快速简单的hack 是将其作为文本从系统注册表中读取:
不过,这种方法的缺点是名称和数字可以针对最终用户的系统进行本地化。
使用自 Windows XP 以来可用的以下密钥:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
及其以下REG_SZ(或字符串)值:
ProductName = 操作系统名称CurrentVersion = 适用于操作系统版本BuildLab = 完整版本号BuildLabEx = 扩展版本号(自 Windows 7 起可用)ReleaseId = 版本号(自 Windows 10 起可用)【讨论】:
我遇到了类似的问题。这是一些支持 Win 11 的代码。它不适用于服务器版本,但添加此功能很容易实现(只是服务器的另一个映射)。
// To Workaround Win 10 problem for User Mode VerifyVersionInfo
bool VerifyWindowsVersionInfo(PRTL_OSVERSIONINFOEXW versionInfo, ULONG typeMask, ULONGLONG conditionMask)
{
HMODULE hMod = nullptr;
if ((TRUE != ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L"ntdll.dll", &hMod)) || !hMod)
return false;
typedef NTSTATUS(WINAPI* _RtlVerifyVersionInfo)(PRTL_OSVERSIONINFOEXW, ULONG, ULONGLONG);
const auto RtlVerifyVersionInfo =
reinterpret_cast<_RtlVerifyVersionInfo>(::GetProcAddress(hMod, "RtlVerifyVersionInfo"));
if (!RtlVerifyVersionInfo)
return false;
return NT_SUCCESS(RtlVerifyVersionInfo(versionInfo, typeMask, conditionMask));
}
bool IsWindowsVersionOrGreater(int wMajorVersion, int wMinorVersion, int wBuildNumber, int wServicePackMajor)
{
RTL_OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
osvi.dwMajorVersion = wMajorVersion;
osvi.dwMinorVersion = wMinorVersion;
osvi.dwBuildNumber = wBuildNumber;
osvi.wServicePackMajor = static_cast<WORD>(wServicePackMajor);
DWORDLONG dwlConditionMask = 0;
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
return VerifyWindowsVersionInfo(&osvi,
VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER | VER_SERVICEPACKMAJOR,
dwlConditionMask);
}
std::wstring GetVerbalOsVersion()
{
// see https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms724832(v=vs.85).aspx for details
using OsMajorVersion = int;
using OsMinorVersion = int;
using OsBuildVersion = int;
using OsServicePackMajorVersion = int;
using VersionStrWithNumberPair =
std::pair<std::wstring, std::tuple<OsMajorVersion, OsMinorVersion, OsBuildVersion, OsServicePackMajorVersion>>;
const auto win11BuildNumber = 22000;
const std::vector<VersionStrWithNumberPair> winVersionMapping = {
{L"Windows 11 ",
std::make_tuple(HIBYTE(_WIN32_WINNT_WIN10), LOBYTE(_WIN32_WINNT_WIN10), win11BuildNumber, 0)},
{L"Windows 10 ", std::make_tuple(HIBYTE(_WIN32_WINNT_WIN10), LOBYTE(_WIN32_WINNT_WIN10), 0, 0)},
{L"Windows 8.1", std::make_tuple(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0, 0)},
{L"Windows 8 ", std::make_tuple(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0, 0)},
{L"Windows 7 Service Pack 1", std::make_tuple(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0, 1)},
{L"Windows 7 ", std::make_tuple(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0, 0)},
{L"Windows Vista Service Pack 2",
std::make_tuple(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0, 2)},
{L"Windows Vista Service Pack 1",
std::make_tuple(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0, 1)},
{L"Windows Vista", std::make_tuple(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0, 0)},
{L"Windows XP Service Pack 3",
std::make_tuple(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0, 3)},
{L"Windows XP Service Pack 2",
std::make_tuple(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0, 2)},
{L"Windows XP Service Pack 1",
std::make_tuple(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0, 1)},
{L"Windows XP ", std::make_tuple(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0, 0)} };
const auto it = std::find_if(std::begin(winVersionMapping),
std::end(winVersionMapping),
[](const VersionStrWithNumberPair& el)
{
return IsWindowsVersionOrGreater(std::get<0>(el.second),
std::get<1>(el.second),
std::get<2>(el.second),
std::get<3>(el.second));
});
if (it == std::end(winVersionMapping))
return L"Unknown windows version";
return it->first;
}
【讨论】: