现在的位置: 首页 > 综合 > 正文

用VC获取系统信息

2013年08月15日 ⁄ 综合 ⁄ 共 9846字 ⁄ 字号 评论关闭

在实际编程中,我们经常遇到要获取系统信息的需要,比如现在流行双核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

抱歉!评论已关闭.