由于信息产业在不断地发展,特别像电脑里的操作系统更是更新不断。比如
Windows系统,就有WIN NT、Win2000、WIN XP、WIN SERVER等等。下面就来分析这个类的声明代码:
#001 class LLOSInfo
#002 {
#003 public:
构造函数。
#004
LLOSInfo();
把操作系统信息写到流对象。
#005
void stream(std::ostream& s) const;
#006
获取操作系统信息字符串。
#007
const std::string& getOSString() const;
#008
const std::string& getOSStringSimple() const;
#009
操作系统的主版本号。
#010
S32 mMajorVer;
操作系统的次版本号。
#011
S32 mMinorVer;
操作系统的编译号。
#012
S32 mBuild;
#013
获取能打开文件的个数。
#014 #ifndef LL_WINDOWS
#015
static S32 getMaxOpenFiles();
#016 #endif
#017
获取虚拟内存的大小。
#018
static U32 getProcessVirtualSizeKB();
获取保留内存的大小。
#019
static U32 getProcessResidentSizeKB();
#020 private:
#021
std::string mOSString;
#022
std::string mOSStringSimple;
#023 };
接着来分析怎么获取系统的信息,如下:
#001 LLOSInfo::LLOSInfo() :
#002
mMajorVer(0), mMinorVer(0), mBuild(0)
#003 {
#004
#005 #if LL_WINDOWS
#006
OSVERSIONINFOEX osvi;
#007
BOOL bOsVersionInfoEx;
#008
清空操作系统版本信息的结构。
#009
// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
#010
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
设置版本结构的大小。
#011
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
调用
WINDOWS的API函数GetVersionEx得到系统的版本信息。
#012
if(!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi)))
#013
{
#014
// If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
如果
OSVERSIONINFOEX获取不成功,就调用旧的API函数。
#015
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
#016
if(!GetVersionEx( (OSVERSIONINFO *) &osvi))
#017
return;
#018
}
保存
WINDOWS的主版本号和次版本号。
#019
mMajorVer = osvi.dwMajorVersion;
#020
mMinorVer = osvi.dwMinorVersion;
保存
WINDOWS编译号。
#021
mBuild = osvi.dwBuildNumber;
#022
根据
WINDOWS平台ID来分析是那一个WINDOWS版本。
#023
switch(osvi.dwPlatformId)
#024
{
这是
WIN NT技术的版本。
#025
case VER_PLATFORM_WIN32_NT:
#026
{
是否是
WIN NT。
#027
// Test for the product.
#028
if(osvi.dwMajorVersion <= 4)
#029
{
#030
mOSStringSimple = "Microsoft Windows NT ";
#031
}
是否是
WIN 2000.
#032
else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
#033
{
#034
mOSStringSimple = "Microsoft Windows 2000 ";
#035
}
是否是
WIN XP。
#036
else if(osvi.dwMajorVersion ==5 && osvi.dwMinorVersion == 1)
#037
{
#038
mOSStringSimple = "Microsoft Windows XP ";
#039
}
是否
WIN2003或XP 64位版本。
#040
else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
#041
{
#042
if(osvi.wProductType == VER_NT_WORKSTATION)
#043
mOSStringSimple = "Microsoft Windows XP x64 Edition ";
#044
else
#045
mOSStringSimple = "Microsoft Windows Server 2003 ";
#046
}
是否是
WIN VISTA。
#047
else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0)
#048
{
#049
if(osvi.wProductType == VER_NT_WORKSTATION)
#050
mOSStringSimple = "Microsoft Windows Vista ";
#051
else mOSStringSimple = "Microsoft Windows Vista Server ";
#052
}
如果根据版本号都找不到,就直接读取注册表的信息。
#053
else // Use the registry on early versions of Windows NT.
#054
{
#055
HKEY hKey;
#056
WCHAR szProductType[80];
#057
DWORD dwBufLen;
#058
RegOpenKeyEx( HKEY_LOCAL_MACHINE,
#059
L"SYSTEM//CurrentControlSet//Control//ProductOptions",
#060
0, KEY_QUERY_VALUE, &hKey );
#061
RegQueryValueEx( hKey, L"ProductType", NULL, NULL,
#062
(LPBYTE) szProductType, &dwBufLen);
#063
RegCloseKey( hKey );
#064
if ( lstrcmpi( L"WINNT", szProductType) == 0 )
#065
{
#066
mOSStringSimple += "Professional ";
#067
}
#068
else if ( lstrcmpi( L"LANMANNT", szProductType) == 0 )
#069
{
#070
mOSStringSimple += "Server ";
#071
}
#072
else if ( lstrcmpi( L"SERVERNT", szProductType) == 0 )
#073
{
#074
mOSStringSimple += "Advanced Server ";
#075
}
#076
}
#077
#078
std::string csdversion = utf16str_to_utf8str(osvi.szCSDVersion);
#079
// Display version, service pack (if any), and build number.
#080
char tmp[MAX_STRING]; /* Flawfinder: ignore */
#081
if(osvi.dwMajorVersion <= 4)
#082
{
#083
snprintf( /* Flawfinder: ignore */
#084
tmp,
#085
sizeof(tmp),
#086
"version %d.%d %s (Build %d)",
#087
osvi.dwMajorVersion,
#088
osvi.dwMinorVersion,
#089
csdversion.c_str(),
#090
(osvi.dwBuildNumber & 0xffff));
#091
}
#092
else
#093
{
#094
snprintf( /* Flawfinder: ignore */
#095
tmp,
#096
sizeof(tmp),
#097
"%s (Build %d)",
#098
csdversion.c_str(),
#099
(osvi.dwBuildNumber & 0xffff));
#100
}
#101
mOSString = mOSStringSimple + tmp;
#102
}
#103
break;
#104
下面是
WIN95,WIN98,WIN ME的版本号识别。
#105
case VER_PLATFORM_WIN32_WINDOWS:
#106
// Test for the Windows 95 product family.
#107
if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
#108
{
#109
mOSStringSimple = "Microsoft Windows 95 ";
#110
if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' )
#111
{
#112
mOSStringSimple += "OSR2 ";
#113
}
#114
}
#115
if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
#116
{
#117
mOSStringSimple = "Microsoft Windows 98 ";
#118
if ( osvi.szCSDVersion[1] == 'A' )
#119
{
#120
mOSStringSimple += "SE ";
#121
}
#122
}
#123
if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
#124
{
#125
mOSStringSimple = "Microsoft Windows Millennium Edition ";
#126
}
#127
mOSString = mOSStringSimple;
#128
break;
#129
}
#130 #else
下面
LINUX的版本号识别。
#131
struct utsname un;
#132
if(uname(&un) != -1)
#133
{
#134
mOSStringSimple.append(un.sysname);
#135
mOSStringSimple.append(" ");
#136
mOSStringSimple.append(un.release);
#137
#138
mOSString = mOSStringSimple;
#139
mOSString.append(" ");
#140
mOSString.append(un.version);
#141
mOSString.append(" ");
#142
mOSString.append(un.machine);
#143
#144
// Simplify 'Simple'
#145
std::string ostype = mOSStringSimple.substr(0, mOSStringSimple.find_first_of(" ", 0));
#146
if (ostype == "Darwin")
#147
{
#148
// Only care about major Darwin versions, truncate at first '.'
#149
S32 idx1 = mOSStringSimple.find_first_of(".", 0);
#150
std::string simple = mOSStringSimple.substr(0, idx1);
#151
if (simple.length() > 0)
#152
mOSStringSimple = simple;
#153
}
#154
else if (ostype == "Linux")
#155
{
#156
// Only care about major and minor Linux versions, truncate at second '.'
#157
S32 idx1 = mOSStringSimple.find_first_of(".", 0);
#158
S32 idx2 = (idx1 != std::string::npos) ? mOSStringSimple.find_first_of(".", idx1+1) : std::string::npos;
#159
std::string simple = mOSStringSimple.substr(0, idx2);
#160
if (simple.length() > 0)
#161
mOSStringSimple = simple;
#162
}
#163
}
#164
else
#165
{
#166
mOSStringSimple.append("Unable to collect OS info");
#167
mOSString = mOSStringSimple;
#168
}
#169 #endif
#170
#171 }
上面主要通过
WINDOWS的API函数GetVersionEx来获取版本信息,然后根据版本号获取相应的字符串信息。至于这个版本函数的使用,请参考我写的《Windows API一日一练》这本书。