需要在win7、windows server 2008、windows server 2012、win10上获取系统的版本号,综合了各类方法,最终代码如下所示,在4个平台可用。
#include <iostream>
#include <Windows.h>
#define REG_NT_VERSION "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
struct Info {
char os_name[MAX_PATH];
char installation[MAX_PATH];
DWORD dwMajorVer, dwMinorVer, dwBuildNumber;
};
int get_os_info(Info& sysinfo, std::string& err) {
HKEY hKey = NULL;
LSTATUS lret = RegOpenKeyExA(
HKEY_LOCAL_MACHINE,
REG_NT_VERSION,
0,
KEY_READ,
&hKey
);
if (lret != ERROR_SUCCESS) {
char buf[1024];
snprintf(buf, sizeof(buf), "RegOpenKeyExA error: %u", GetLastError());
err = buf;
return -1;
}
DWORD dwType = 0;
DWORD dwSize = sizeof(sysinfo.os_name) / sizeof(sysinfo.os_name[0]);
lret = RegQueryValueExA(hKey,
"ProductName",
NULL,
&dwType,
(LPBYTE)sysinfo.os_name,
(DWORD*)&dwSize);
if (lret != ERROR_SUCCESS) {
char buf[1024];
snprintf(buf, sizeof(buf), "RegQueryValueExA ProductName error: %u", GetLastError());
err = buf;
return -1;
}
dwSize = sizeof(sysinfo.installation) / sizeof(sysinfo.installation[0]);
lret = RegQueryValueExA(hKey,
"InstallationType",
NULL,
&dwType,
(LPBYTE)sysinfo.installation,
(DWORD*)&dwSize);
if (lret != ERROR_SUCCESS) {
char buf[1024];
snprintf(buf, sizeof(buf), "RegQueryValueExA error: %u", GetLastError());
err = buf;
return -1;
}
RegCloseKey(hKey);
BOOL bRet = FALSE;
HMODULE hModNtdll = NULL;
if (hModNtdll = ::LoadLibraryW(L"ntdll.dll"))
{
typedef void (WINAPI* pfRTLGETNTVERSIONNUMBERS)(DWORD*, DWORD*, DWORD*);
pfRTLGETNTVERSIONNUMBERS pfRtlGetNtVersionNumbers;
pfRtlGetNtVersionNumbers = (pfRTLGETNTVERSIONNUMBERS)::GetProcAddress(hModNtdll, "RtlGetNtVersionNumbers");
if (pfRtlGetNtVersionNumbers)
{
pfRtlGetNtVersionNumbers(&sysinfo.dwMajorVer, &sysinfo.dwMinorVer, &sysinfo.dwBuildNumber);
sysinfo.dwBuildNumber &= 0x0ffff;
bRet = TRUE;
}
::FreeLibrary(hModNtdll);
hModNtdll = NULL;
}
if (!bRet) {
char buf[1024];
snprintf(buf, sizeof(buf), "get version error: %u", GetLastError());
err = buf;
return -1;
}
return 0;
}
int main()
{
Info info = { 0 };
std::string err;
if (get_os_info(info, err)) {
std::cerr << err << std::endl;
}
else {
std::cout << " OS: " << info.os_name << std::endl;
std::cout << "Installation: " << info.installation << std::endl;
std::cout << " MajorVer: " << info.dwMajorVer << std::endl;
std::cout << " MinorVer: " << info.dwMinorVer << std::endl;
std::cout << " BuildNumber: " << info.dwBuildNumber << std::endl;
}
char d;
std::cin >> d;
return 0;
}
采用VS2019编译。
win10上运行结果如下。
win7上结果如下。
windows server 2008上结果如下。
windows server 2012上结果如下。