在实际编程中,我们经常遇到要获取系统信息的需要,比如现在流行双核CPU,这个时候可以获取系统信息,如果发现是双核,那么程序可以采用另一种方法,
加快相关数据的处理,以及做出更好的用户交流界面,下面我给出相关系统信息获取的函数,希望对大家有用:
BOOL CAboutDlg::ShowSysInfo()//显示系统信息
{
CString sData;
CString processor,operatingsystem,memory,language;//本来language是用来显示语言的,现在用来显示虚拟内存
MEMORYSTATUS MemStat;
MemStat.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus(&MemStat);
memory.Format("%ld(MB), %ld(MB) use, %d%%",MemStat.dwTotalPhys/1048576L,(MemStat.dwTotalPhys-MemStat.dwAvailPhys)/1048576L,MemStat.dwMemoryLoad);
language.Format("%ld(MB), %ld(MB) use",MemStat.dwTotalPageFile/1048576L,MemStat.dwTotalPageFile/1048576L-MemStat.dwAvailPageFile/1048576L);
DWORD h1,h2;
double h3;
h1 = MemStat.dwTotalPageFile - MemStat.dwAvailPageFile;
h2 = MemStat.dwTotalPageFile;
h3 = (double)h1/(double)h2*100;
sData.Format(" ,%.0f%%",h3);
language += sData;
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
//下面是对CPU类型的判断,如果需要更精确的判断,请查阅厂家提供的更详细型号说明
if(sysInfo.dwProcessorType == PROCESSOR_INTEL_386)
{
processor = _T("Intel 386");
}
else if(sysInfo.dwProcessorType == PROCESSOR_INTEL_486)
{
processor = _T("Intel 486");
}
else if (sysInfo.dwProcessorType == PROCESSOR_INTEL_PENTIUM)
{
processor = _T("Intel Pentium");
}
else if(sysInfo.dwProcessorType == PROCESSOR_MIPS_R4000)
{
processor = _T("MIPS");
}
else if(sysInfo.dwProcessorType == PROCESSOR_ALPHA_21064)
{
processor = _T("Alpha");
}
else
{
processor = _T("Unknown");
}
if(sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
{
switch (sysInfo.wProcessorLevel)
{
case 3:
processor = _T("Intel 80386");
break;
case 4:
processor = _T("Intel 80486");
break;
case 5:
processor = _T("Pentium");
if (IsProcessorFeaturePresent (PF_MMX_INSTRUCTIONS_AVAILABLE))
{
processor += _T("Pentium MMX");
}
break;
case 6:
processor = _T("Intel Pentium (R)");
break;
}
}
else if(sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_MIPS)
{
if(sysInfo.wProcessorLevel == 0004)
{
processor += _T("MIPS R4000");
}
else
{
processor += _T("Unknown");
}
}
else if(sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA)
{
sData.Format("%d",sysInfo.wProcessorLevel);
processor = "Alpha" + sData;
}
else if(sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_PPC)
{
switch(sysInfo.wProcessorLevel)
{
case 1:
processor += _T("PPC 601");
break;
case 3:
processor += _T("PPC 603");
break;
case 4:
processor += _T("PPC 604");
break;
case 6:
processor += _T("PPC 603+");
break;
case 9:
processor += _T("PPC 604+");
break;
case 20:
processor += _T("PPC 620");
break;
}
}
else if(sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_UNKNOWN)
{
processor += _T("Unknown");
}
int speed = CpuSpeed();//这是获取CPU频率的函数,随后附上.
double dSpeed = (double)speed/1000.00;
if(sysInfo.dwNumberOfProcessors==2)//双核CPU
{
sData.Format(" Dual Core @ %.2fG",dSpeed);
}
else if(sysInfo.dwNumberOfProcessors==1)//单一CPU
{
sData.Format(" @ %.2fG",dSpeed);
}
else
{
sData.Format(" %d cpu @ %.2fG",sysInfo.dwNumberOfProcessors,dSpeed);
}
processor += sData;
DWORD win95Info;
OSVERSIONINFO versionInfo;
//设定OSVERSIONINFO的大小
versionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
// 获得Windows版本信息
if (!::GetVersionEx(&versionInfo))
{
operatingsystem = (_T ("Not able to get OS information"));
}
if (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
operatingsystem = (_T ("Windows NT"));
// 检查版本号
if(versionInfo.dwMajorVersion <= 4)
{
operatingsystem = (_T ("Windows NT"));
}
else if((versionInfo.dwMajorVersion==5) && (versionInfo.dwMinorVersion==0))//5.0是Windows2000
{
operatingsystem = (_T ("Windows 2000"));
}
else if((versionInfo.dwMajorVersion==5) && (versionInfo.dwMinorVersion==1))//5.1几WindowsXP
{
operatingsystem = (_T ("Windows XP"));
}
else if((versionInfo.dwMajorVersion==5) && (versionInfo.dwMinorVersion==2))//5.2是否属于Windows2003?我没有尝试,只是推测的
{
operatingsystem = (_T ("Windows 2003"));
}
else if(versionInfo.dwMajorVersion==6)//6.0是Microsoft目前的最新Vista版本,如果是7.0以上的可能要等Microsoft的最新命名了
{
operatingsystem = (_T ("Windows Vista"));
}
sData.Format(" %ld.%ld(%ld) ",versionInfo.dwMajorVersion,versionInfo.dwMinorVersion,versionInfo.dwBuildNumber);
operatingsystem += sData;
}
else if (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
operatingsystem = _T ("Windows 95");
if ((versionInfo.dwMajorVersion > 4) || ((versionInfo.dwMajorVersion == 4)&& (versionInfo.dwMinorVersion > 0)))
{
operatingsystem = _T ("Windows 98");
}
//对win95,build number是低字节
win95Info = (DWORD)(LOBYTE(LOWORD(versionInfo.dwBuildNumber)));
sData.Format("%ld",win95Info);
operatingsystem += sData;
}
else
{
operatingsystem = _T ("Windows 3.1");
}
// 获得service pack信息
sData.Format("%s",versionInfo.szCSDVersion);
operatingsystem += sData;
//这时相关信息已获取完毕,你可以进行自己的相关处理
return TRUE;
}
下面给出的是获取CPU频率的函数:
int _stdcall CpuSpeed()
{
#define TOLERANCE 1 // Number of MHz to allow
#define ROUND_THRESHOLD 6
typedef struct
{
unsigned long in_cycles; // Internal clock cycles during
// test
unsigned long ex_ticks; // Microseconds elapsed during
// test
unsigned long raw_freq; // Raw frequency of CPU in MHz
unsigned long norm_freq; // Normalized frequency of CPU
// in MHz.
}FREQ_INFO;
/*
typedef struct _ASTAT_
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff[ 30 ];
}ASTAT,*PASTAT;
ASTAT Adapter;
*/
FREQ_INFO cpu_speed;
LARGE_INTEGER t0,t1; // Variables for High-
// Resolution Performance
// Counter reads
unsigned long freq =0; // Most current frequ. calculation
unsigned long freq2 =0; // 2nd most current frequ. calc.
unsigned long freq3 =0; // 3rd most current frequ. calc.
unsigned long total; // Sum of previous three frequency
// calculations
int tries=0; // Number of times a calculation has
// been made on this call to
// cpuspeed
unsigned long total_cycles=0, cycles; // Clock cycles elapsed
// during test
unsigned long stamp0, stamp1; // Time Stamp Variable
// for beginning and end
// of test
unsigned long total_ticks=0, ticks; // Microseconds elapsed
// during test
LARGE_INTEGER count_freq; // High Resolution
// Performance Counter
// frequency
#ifdef WIN32
int iPriority;
HANDLE hThread = GetCurrentThread();
#endif // WIN32;
memset(&cpu_speed, 0x00, sizeof(cpu_speed));
// return cpu_speed;
QueryPerformanceFrequency ( &count_freq );
// On processors supporting the Read
// Time Stamp opcode, compare elapsed
// time on the High-Resolution Counter
// with elapsed cycles on the Time
// Stamp Register.
do { // This do loop runs up to 20 times or
// until the average of the previous
// three calculated frequencies is
// within 1 MHz of each of the
// individual calculated frequencies.
// This resampling increases the
// accuracy of the results since
// outside factors could affect this
// calculation
tries++; // Increment number of times sampled
// on this call to cpuspeed
freq3 = freq2; // Shift frequencies back to make
freq2 = freq; // room for new frequency
// measurement
QueryPerformanceCounter(&t0);
// Get high-resolution performance
// counter time
t1.LowPart = t0.LowPart; // Set Initial time
t1.HighPart = t0.HighPart;
#ifdef WIN32
iPriority = GetThreadPriority(hThread);
if ( iPriority != THREAD_PRIORITY_ERROR_RETURN )
{
SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
}
#endif // WIN32
while ( (unsigned long)t1.LowPart - (unsigned long)t0.LowPart<50) {
// Loop until 50 ticks have
// passed since last read of hi-
// res counter. This accounts for
// overhead later.
QueryPerformanceCounter(&t1);
_asm {
RDTSC // Read Time Stamp
MOV stamp0, EAX
}
}
t0.LowPart = t1.LowPart; // Reset Initial
t0.HighPart = t1.HighPart; // Time
while ((unsigned long)t1.LowPart-(unsigned long)t0.LowPart<1000 ) {
// Loop until 1000 ticks have
// passed since last read of hi-
// res counter. This allows for
// elapsed time for sampling.
QueryPerformanceCounter(&t1);
__asm {
RDTSC // Read Time Stamp
MOV stamp1, EAX
}
}
#ifdef WIN32
// Reset priority
if ( iPriority != THREAD_PRIORITY_ERROR_RETURN )
{
SetThreadPriority(hThread, iPriority);
}
#endif // WIN32
cycles = stamp1 - stamp0; // Number of internal
// clock cycles is
// difference between
// two time stamp
// readings.
ticks = (unsigned long) t1.LowPart - (unsigned long) t0.LowPart;
// Number of external ticks is
// difference between two
// hi-res counter reads.
// Note that some seemingly arbitrary mulitplies and
// divides are done below. This is to maintain a
// high level of precision without truncating the
// most significant data. According to what value
// ITERATIIONS is set to, these multiplies and
// divides might need to be shifted for optimal
// precision.
ticks = ticks * 100000;
// Convert ticks to hundred
// thousandths of a tick
ticks = ticks / ( count_freq.LowPart/10 );
// Hundred Thousandths of a
// Ticks / ( 10 ticks/second )
// = microseconds (us)
total_ticks += ticks;
total_cycles += cycles;
if ( ticks%count_freq.LowPart > count_freq.LowPart/2 )
ticks++; // Round up if necessary
freq = cycles/ticks; // Cycles / us = MHz
if ( cycles%ticks > ticks/2 )
freq++; // Round up if necessary
total = ( freq + freq2 + freq3 );
// Total last three frequency
// calculations
}while ( (tries < 3 ) ||
(tries < 20)&&
((abs(3 * freq -total) > 3*TOLERANCE )||
(abs(3 * freq2-total) > 3*TOLERANCE )||
(abs(3 * freq3-total) > 3*TOLERANCE )));
// Compare last three calculations to
// average of last three calculations.
// Try one more significant digit.
freq3 = ( total_cycles * 10 ) / total_ticks;
freq2 = ( total_cycles * 100 ) / total_ticks;
if ( freq2 - (freq3 * 10) >= ROUND_THRESHOLD )
freq3++;
cpu_speed.raw_freq = total_cycles / total_ticks;
cpu_speed.norm_freq = cpu_speed.raw_freq;
freq = cpu_speed.raw_freq * 10;
if( (freq3 - freq) >= ROUND_THRESHOLD )
cpu_speed.norm_freq++;
cpu_speed.ex_ticks = total_ticks;
cpu_speed.in_cycles = total_cycles;
return (int)cpu_speed.norm_freq;
}
以上程序经VC6.0,WinXP下编译调试通过,在这里就不给出下载地址了,各位看官可以直接COPY到你的VC6.0中编译通过,
如果有不当的地方,欢迎指正,谢谢!
转载请注明:本文出自www.vcfans.cn/bbs