19 #if defined(__APPLE__)
20 #include <sys/sysctl.h>
21 extern char **environ;
22 #elif defined(unix) || defined(__unix) || defined(__unix__)
24 #include <sys/utsname.h>
29 extern char **environ;
31 #if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
34 #define STATUS_SUCCESS 0x00000000
48 #if defined(__APPLE__)
50 #elif defined(linux) || defined(__linux) || defined(__linux__)
52 return (stat(
"/lib64/ld-linux-x86-64.so.2", &buffer) == 0);
53 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
56 #elif defined(_WIN32) || defined(__CYGWIN__)
57 BOOL bWow64Process = FALSE;
58 return IsWow64Process(GetCurrentProcess(), &bWow64Process) && bWow64Process;
61 #error Unsupported platform
72 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
73 #if defined(__x86_64__) || defined(__amd64__) || defined(__aarch64__) || defined(__ia64__) || defined(__ppc64__)
78 #elif defined(_WIN32) || defined(_WIN64)
85 #error Unsupported platform
105 char16_t test = 0x0102;
106 return ((
char*)&test)[0] == 0x01;
111 char16_t test = 0x0102;
112 return ((
char*)&test)[0] == 0x02;
117 #if defined(__APPLE__)
119 size_t size =
sizeof(result);
120 if (sysctlbyname(
"kern.osrelease", result, &size,
nullptr, 0) == 0)
124 #elif defined(__CYGWIN__)
126 if (uname(&name) == 0)
128 std::string result(name.sysname);
130 result.append(name.release);
132 result.append(name.version);
137 #elif defined(linux) || defined(__linux) || defined(__linux__)
138 static std::regex pattern(
"DISTRIB_DESCRIPTION=\"(.*)\"");
141 std::ifstream stream(
"/etc/lsb-release");
142 while (getline(stream, line))
145 if (std::regex_match(line, matches, pattern))
150 #elif defined(_WIN32) || defined(_WIN64)
151 static NTSTATUS(__stdcall *RtlGetVersion)(OUT PRTL_OSVERSIONINFOEXW lpVersionInformation) = (NTSTATUS(__stdcall*)(PRTL_OSVERSIONINFOEXW))GetProcAddress(GetModuleHandle(
"ntdll.dll"),
"RtlGetVersion");
152 static void(__stdcall *GetNativeSystemInfo)(OUT LPSYSTEM_INFO lpSystemInfo) = (
void(__stdcall*)(LPSYSTEM_INFO))GetProcAddress(GetModuleHandle(
"kernel32.dll"),
"GetNativeSystemInfo");
153 static BOOL(__stdcall *GetProductInfo)(IN DWORD dwOSMajorVersion, IN DWORD dwOSMinorVersion, IN DWORD dwSpMajorVersion, IN DWORD dwSpMinorVersion, OUT PDWORD pdwReturnedProductType) = (BOOL(__stdcall*)(DWORD, DWORD, DWORD, DWORD, PDWORD))GetProcAddress(GetModuleHandle(
"kernel32.dll"),
"GetProductInfo");
155 OSVERSIONINFOEXW osvi;
156 ZeroMemory(&osvi,
sizeof(OSVERSIONINFOEXW));
157 osvi.dwOSVersionInfoSize =
sizeof(OSVERSIONINFOEXW);
159 if (RtlGetVersion !=
nullptr)
161 NTSTATUS ntRtlGetVersionStatus = RtlGetVersion(&osvi);
162 if (ntRtlGetVersionStatus != STATUS_SUCCESS)
167 #if defined(_MSC_VER)
168 #pragma warning(push)
169 #pragma warning(disable: 4996)
171 BOOL bOsVersionInfoEx = GetVersionExW((OSVERSIONINFOW*)&osvi);
172 if (bOsVersionInfoEx == 0)
174 #if defined(_MSC_VER)
180 ZeroMemory(&si,
sizeof(SYSTEM_INFO));
182 if (GetNativeSystemInfo !=
nullptr)
183 GetNativeSystemInfo(&si);
187 if ((osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) || (osvi.dwMajorVersion <= 4))
192 std::stringstream os;
196 if (osvi.dwMajorVersion >= 6)
198 if (osvi.dwMajorVersion == 10)
200 if (osvi.dwMinorVersion == 0)
202 if (osvi.wProductType == VER_NT_WORKSTATION)
204 if (osvi.dwBuildNumber >= 22000)
211 if (osvi.dwBuildNumber >= 20348)
212 os <<
"Windows Server 2022 ";
213 else if (osvi.dwBuildNumber >= 17763)
214 os <<
"Windows Server 2019 ";
216 os <<
"Windows Server 2016 ";
220 else if (osvi.dwMajorVersion == 6)
222 if (osvi.dwMinorVersion == 3)
224 if (osvi.wProductType == VER_NT_WORKSTATION)
225 os <<
"Windows 8.1 ";
227 os <<
"Windows Server 2012 R2 ";
229 else if (osvi.dwMinorVersion == 2)
231 if (osvi.wProductType == VER_NT_WORKSTATION)
234 os <<
"Windows Server 2012 ";
236 else if (osvi.dwMinorVersion == 1)
238 if (osvi.wProductType == VER_NT_WORKSTATION)
241 os <<
"Windows Server 2008 R2 ";
243 else if (osvi.dwMinorVersion == 0)
245 if (osvi.wProductType == VER_NT_WORKSTATION)
246 os <<
"Windows Vista ";
248 os <<
"Windows Server 2008 ";
253 if ((GetProductInfo !=
nullptr) && GetProductInfo(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType))
257 case PRODUCT_ULTIMATE:
258 os <<
"Ultimate Edition";
260 case PRODUCT_PROFESSIONAL:
261 os <<
"Professional";
263 case PRODUCT_HOME_PREMIUM:
264 os <<
"Home Premium Edition";
266 case PRODUCT_HOME_BASIC:
267 os <<
"Home Basic Edition";
269 case PRODUCT_ENTERPRISE:
270 os <<
"Enterprise Edition";
272 case PRODUCT_BUSINESS:
273 os <<
"Business Edition";
275 case PRODUCT_STARTER:
276 os <<
"Starter Edition";
278 case PRODUCT_CLUSTER_SERVER:
279 os <<
"Cluster Server Edition";
281 case PRODUCT_DATACENTER_SERVER:
282 os <<
"Datacenter Edition";
284 case PRODUCT_DATACENTER_SERVER_CORE:
285 os <<
"Datacenter Edition (core installation)";
287 case PRODUCT_ENTERPRISE_SERVER:
288 os <<
"Enterprise Edition";
290 case PRODUCT_ENTERPRISE_SERVER_CORE:
291 os <<
"Enterprise Edition (core installation)";
293 case PRODUCT_ENTERPRISE_SERVER_IA64:
294 os <<
"Enterprise Edition for Itanium-based Systems";
296 case PRODUCT_SMALLBUSINESS_SERVER:
297 os <<
"Small Business Server";
299 case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
300 os <<
"Small Business Server Premium Edition";
302 case PRODUCT_STANDARD_SERVER:
303 os <<
"Standard Edition";
305 case PRODUCT_STANDARD_SERVER_CORE:
306 os <<
"Standard Edition (core installation)";
308 case PRODUCT_WEB_SERVER:
309 os <<
"Web Server Edition";
314 else if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 2))
316 if (GetSystemMetrics(SM_SERVERR2))
317 os <<
"Windows Server 2003 R2, ";
318 else if (osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER)
319 os <<
"Windows Storage Server 2003";
320 else if (osvi.wSuiteMask & VER_SUITE_WH_SERVER)
321 os <<
"Windows Home Server";
322 else if ((osvi.wProductType == VER_NT_WORKSTATION) && (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64))
323 os <<
"Windows XP Professional x64 Edition";
325 os <<
"Windows Server 2003, ";
326 if (osvi.wProductType != VER_NT_WORKSTATION)
328 if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
330 if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
331 os <<
"Datacenter Edition for Itanium-based Systems";
332 else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
333 os <<
"Enterprise Edition for Itanium-based Systems";
335 else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
337 if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
338 os <<
"Datacenter x64 Edition";
339 else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
340 os <<
"Enterprise x64 Edition";
342 os <<
"Standard x64 Edition";
346 if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER)
347 os <<
"Compute Cluster Edition";
348 else if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
349 os <<
"Datacenter Edition";
350 else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
351 os <<
"Enterprise Edition";
352 else if (osvi.wSuiteMask & VER_SUITE_BLADE)
355 os <<
"Standard Edition";
359 else if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 1))
362 if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
363 os <<
"Home Edition";
365 os <<
"Professional";
367 else if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0))
369 os <<
"Windows 2000 ";
370 if (osvi.wProductType == VER_NT_WORKSTATION)
371 os <<
"Professional";
374 if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
375 os <<
"Datacenter Server";
376 else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
377 os <<
"Advanced Server";
384 std::wstring sp_version(osvi.szCSDVersion);
385 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
386 if (std::wcslen(osvi.szCSDVersion) > 0)
387 os <<
" " << convert.to_bytes(sp_version.data(), sp_version.data() + sp_version.size());
390 os <<
" (build " << osvi.dwBuildNumber <<
")";
393 if (osvi.dwMajorVersion >= 6)
395 if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
397 else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
399 else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
400 os <<
", Intel Itanium";
401 else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM)
403 #if !defined(__MINGW32__) && !defined(__MINGW64__)
404 else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)
411 #error Unsupported platform
417 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
419 #elif defined(_WIN32) || defined(_WIN64)
422 #error Unsupported platform
438 std::map<std::string, std::string> result;
439 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
443 int offset = (envar[0] ==
'=') ? 1 : 0;
444 char* separator = std::strchr(envar + offset,
'=');
445 std::string key(envar, separator - envar);
447 char* pvalue = separator + 1;
448 std::string value(pvalue);
452 #elif defined(_WIN32) || defined(_WIN64)
454 auto envars =
resource(GetEnvironmentStringsW(), [](
wchar_t* penv) { FreeEnvironmentStringsW(penv); });
456 for (
const wchar_t* envar =
envars.get(); *envar != L
'\0'; )
458 int offset = (envar[0] ==
'=') ? 1 : 0;
459 const wchar_t* separator = std::wcschr(envar + offset, L
'=');
460 std::wstring key(envar, separator - envar);
462 const wchar_t* pvalue = separator + 1;
463 std::wstring value(pvalue);
467 envar = pvalue + value.size() + 1;
475 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
476 char* envar = getenv(name.c_str());
477 return (envar !=
nullptr) ? std::string(envar) : std::string();
478 #elif defined(_WIN32) || defined(_WIN64)
480 std::vector<wchar_t> buffer(MAX_PATH);
482 DWORD size = GetEnvironmentVariableW(wname.c_str(), buffer.data(), (DWORD)buffer.size());
483 if (size > buffer.size())
486 size = GetEnvironmentVariableW(wname.c_str(), buffer.data(), (DWORD)buffer.size());
489 return (size > 0) ?
Encoding::ToUTF8(std::wstring(buffer.data(), size)) : std::string();
495 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
496 if (setenv(name.c_str(), value.c_str(), 1) != 0)
498 #elif defined(_WIN32) || defined(_WIN64)
506 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
507 if (unsetenv(name.c_str()) != 0)
509 #elif defined(_WIN32) || defined(_WIN64)
static std::wstring FromUTF8(std::string_view str)
Convert UTF-8 encoded string to system wide-string.
static std::string ToUTF8(std::wstring_view wstr)
Convert system wide-string to UTF-8 encoded string.
static bool IsBigEndian()
Is big-endian system?
static bool Is64BitProcess()
Is 64-bit running process?
static std::string UnixEndLine()
Get Unix text end line separator.
static bool Is64BitOS()
Is 64-bit OS?
static bool Is32BitProcess()
Is 32-bit running process?
static void SetEnvar(const std::string name, const std::string value)
Set environment variable value by the given name.
static bool IsRelease()
Is compiled in release mode?
static void ClearEnvar(const std::string name)
Clear environment variable by the given name.
static std::map< std::string, std::string > envars()
Get all environment variables.
static bool IsDebug()
Is compiled in debug mode?
static std::string OSVersion()
Get OS version string.
static bool Is32BitOS()
Is 32-bit OS?
static bool IsLittleEndian()
Is little-endian system?
static std::string EndLine()
Get text end line separator.
static std::string WindowsEndLine()
Get Windows text end line separator.
static std::string GetEnvar(const std::string name)
Get environment variable value by the given name.
Encoding utilities definition.
Environment management definition.
#define throwex
Throw extended exception macro.
C++ Common project definitions.
auto resource(T handle, TCleaner cleaner)
Resource smart cleaner pattern.
Resource smart cleaner pattern definition.