本文转自https://zhuanlan.zhihu.com/p/111005951,这篇写的很详细,但是macos相关的只有一部分太少了,基本都是Windows的,我个人后续也会把相关的系统调用方式上传整理到本文章中。
在项目开发过程中,我们经常要获取系统的相关信息,从而了解系统和程序进程的运行情况,特别是在程序调试过程中,这些系统信息对我们定位bug更加重要。本文将全面归纳总结获取系统信息的一些接口方法,并用代码实现之,以便同行的你在开发过程中参考。如果觉得文章不错,请收藏并顺手点个赞,作为一个开发者,业余坚持写总结性的文章,确属不易。
1.获取计算机操作系统相关信息
在使用Qt框架进行项目开发时,获取系统信息相对比较简单,框架已经为我们提供了QSysInfo类,此类为我们提供了当前系统的一些底层接口信息,其中包括:
ByteOrder :代表当前系统是大端模式还是小端模式;
WordSize:代表编译应用程序的当前系统的指针大小,值为(sizeof(void*)<<3);
WindowsVersion代表当前运行应用程序的windows系统版本; MacintoshVersion :代表当前运行应用程序的Mac系统的版本;
因为Qt是跨平台的,所以此类在不同的平台会有不同的接口,因此在使用时可以用预定义符号:Q_OS_WIN和Q_OS_OSX来判断,应用程序是在哪个系统下编译。此类的方法全部是静态成员函数,可以方便地调用。
QString QSysInfo::buildAbi() 接口返回的是Qt程序平台的架构全部信息,包含三个或三个以上的部分,用-分隔,具体说明如下表:
**QString QSysInfo::buildCpuArchitecture()**接口返回编译Qt程序的CPU架构。这个架构可能与Qt程序实际运行的CPU不同,因为可能存在仿真层或该CPU支持多个架构。接口通常的返回值有:arm、arm64、i386、ia64、mips、mips64、power、power64、sparc、sparcv9、x86_64等。
QString QSysInfo::currentCpuArchitecture() 接口返回的是Qt程序当前运行的CPU架构。
获取系统信息的示例代码如下:
#include <QCoreApplication>
#include <QSysInfo>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "WindowsVersion: " << QSysInfo::WindowsVersion;
qDebug() << "buildAbi: " << QSysInfo::buildAbi();
qDebug() << "buildCpuArchitecture: " << QSysInfo::buildCpuArchitecture();
qDebug() << "currentCpuArchitecture: " << QSysInfo::currentCpuArchitecture();
qDebug() << "kernelType: " << QSysInfo::kernelType(); //内核类型
qDebug() << "kernelVersion: " << QSysInfo::kernelVersion(); //内核版本
qDebug() << "machineHostName: " << QSysInfo::machineHostName(); // 主机名称
qDebug() << "prettyProductName: " << QSysInfo::prettyProductName(); //操作系统的产品名称
qDebug() << "productType: " << QSysInfo::productType();
qDebug() << "productVersion: " << QSysInfo::productVersion(); //产品版本
return a.exec();
}
- 获取计算主机的相关信息
在网络通信过程中,我们需要获得计算机的主机信息。在QT中,可以用类QHostInfo的接口。此类提供网络中计算主机的相关信息,并且所有接口全部为静态函数,调用非常方便。示例如下:
#include <QCoreApplication>
#include <QHostInfo>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug()<<QHostInfo::localHostName();
qDebug()<<QHostInfo::localDomainName();
return a.exec();
}
- 获取本机的IP地址
获取本机的IP时,需要用到类QNetworkInterface、QNetworkAddressEntry两个类。其代码示例如下:
#include <QCoreApplication>
#include <QNetworkAddressEntry>
#include <QNetworkInterface>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString ip="";
QList<QNetworkInterface> interFaceList = QNetworkInterface::allInterfaces();
for(int i=0; i< interFaceList.size(); i++)
{
QNetworkInterface interface = interFaceList.at(i);
if(interface.flags().testFlag(QNetworkInterface::IsRunning))
{
QList<QNetworkAddressEntry> entryList = interface.addressEntries();
foreach(QNetworkAddressEntry entry, entryList)
{
if(QAbstractSocket::IPv4Protocol == entry.ip().protocol() &&
entry.ip() != QHostAddress::LocalHost && entry.ip().toString().startsWith("192.168."))
{
ip = entry.ip().toString();
break;
}
}
}
}
qDebug()<<ip;
return a.exec();
}
- 获取计算机的MAC地址
要想知道计算的MAC地址也比较容易,也要用到QNetworkInterface类。其代码示例如下:
#include <QCoreApplication>
#include <QNetworkInterface>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString strMac;
QList<QNetworkInterface> netList = QNetworkInterface::allInterfaces();
foreach(QNetworkInterface item, netList)
{
if((QNetworkInterface::IsUp & item.flags()) && (QNetworkInterface::IsRunning & item.flags()))
{
if(strMac.isEmpty() || strMac < item.hardwareAddress())
{
strMac = item.hardwareAddress();
}
}
}
qDebug()<<strMac;
return a.exec();
}
- 获取计算CPU相关信息
可以用QSettings类的相关接口来获取相关的信息。此类提供独立于平台的应用程序设置信息接口。 获取CPU信息,可以直接访问注册表 中相应的键值。其示例代码如下:
#include <QCoreApplication>
#include <QSettings>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSettings *CPU = new QSettings("HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",QSettings::NativeFormat);
QString m_cpuDescribe = CPU->value("ProcessorNameString").toString();
delete CPU;
qDebug()<<m_cpuDescribe;
return a.exec();
}
获取计算机的显卡信息也是类似的,我也将其方法归纳如下:
#include <QCoreApplication>
#include <QSettings>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString dcard;
QSettings *DCard = new QSettings("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\nvlddmkm\\Device0",QSettings::NativeFormat);
QString type = DCard->value("Device Description").toString();
delete DCard;
QString dType = type;
dType.trimmed();
if(!dType.isEmpty())
dcard = dType;
DCard = new QSettings("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\igfx\\Device0",QSettings::NativeFormat);
type = DCard->value("Device Description").toString();
delete DCard;
dType = type;
dType.trimmed();
if(!dType.isEmpty())
dcard = dcard + "\n" +dType;
DCard = new QSettings("HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\amdkmdap\\Device0",QSettings::NativeFormat);
type = DCard->value("Device Description").toString();
delete DCard;
dType = type;
dType.trimmed();
if(!dType.isEmpty())
dcard = dcard + "\n" +dType;
dcard.trimmed();
qDebug()<<dcard;
return a.exec();
}
- 获取计算机内存信息
获取计算机内存信息,要使用window.h中 结构体 MEMORYSTATUEX 。其示例代码如下:
#include <QCoreApplication>
#include <windows.h>
#include <QDebug>
#define GB (1024*1024*1024)
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx(&statex);
qDebug()<<"物理内存总量:"<<statex.ullTotalPhys *1.0/GB;
qDebug()<<"可用的物理内存:"<<statex.ullAvailPhys *1.0/GB;
qDebug()<<"虚拟内存总量:"<<statex.ullTotalVirtual *1.0/GB;
return a.exec();
}
- 获取计算屏幕的个数及像素情况
获取计算机屏幕要用到QDesktopWidget类, 这就要求QT项目中要包含widgets模块。其示例代码如下:
#include <QApplication>
#include <QDesktopWidget>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString m_screenDescribe = "";
QList<QSize> screenSizeList;
QList <int> screenCountList;
for(int i=0; i<QApplication::desktop()->screenCount(); i++)
{
QRect screenRect = QApplication::desktop()->screenGeometry(i);
QSize size(screenRect.width(), screenRect.height());
bool bExist = false;
for(int j=0; j<screenSizeList.length(); j++)
{
QSize existSize = screenSizeList.at(j);
if(size == existSize)
{
screenCountList[j]++;
bExist = true;
break;
}
}
if(!bExist)
{
screenSizeList.append(size);
screenCountList.append(1);
}
}
QSize m_maxScreenSize = screenSizeList.at(0);
for(int i=0; i<screenSizeList.length(); i++)
{
int width = screenSizeList.at(i).width();
int height = screenSizeList.at(i).height();
if(width > m_maxScreenSize.width() && height > m_maxScreenSize.height())
m_maxScreenSize = screenSizeList.at(i);
m_screenDescribe += QString ("(%1像素 x %2像素) x %3个").arg(width).arg(height).arg(screenCountList.at(i));
if(i!= screenSizeList.length()-1)
m_screenDescribe += "、 ";
}
qDebug()<<m_screenDescribe;
return a.exec();
}
- 获取计算机硬盘信息
获取硬盘的信息,首先我们要通过QDir::drives()来获得磁盘的文件信息列表,这是个静态函数,可以直接调用。其获取硬盘信息的示例代码如下:
#include <QApplication>
#include <QFileInfoList>
#include <QDir>
#include <windows.h>
#include <QDebug>
#define GB (1024*1024*1024)
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString m_diskDescribe = "";
QFileInfoList list = QDir::drives();
double m_maxFreeDisk = 0.0;
foreach (QFileInfo dir, list)
{
QString dirName = dir.absolutePath();
dirName.remove("/");
LPCWSTR lpcwstrDriver = (LPCWSTR)dirName.utf16();
ULARGE_INTEGER liFreeBytesAvailable, liTotalBytes, liTotalFreeBytes;
if(GetDiskFreeSpaceEx(lpcwstrDriver, &liFreeBytesAvailable, &liTotalBytes, &liTotalFreeBytes) )
{
QString free = QString::number((double) liTotalFreeBytes.QuadPart / GB, 'f', 1);
free += "G";
QString all = QString::number((double) liTotalBytes.QuadPart / GB, 'f', 1);
all += "G";
QString str = QString("%1 %2/%3 ").arg(dirName, free, all);
m_diskDescribe += str;
double freeMem = (double) liTotalFreeBytes.QuadPart / GB;
if(freeMem > m_maxFreeDisk)
m_maxFreeDisk = freeMem;
}
}
qDebug()<<m_diskDescribe;
return a.exec();
}
- 判断计算机是否可以联外网
我们可以看计算机是否可以连接外网的某一个IP,如百度等,其代码示例如下:
#include <QApplication>
#include <QTcpSocket>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTcpSocket tcpClient;
tcpClient.abort();
tcpClient.connectToHost("202.108.22.5", 80);
//300毫秒没有连接上则判断不在线
qDebug()<<"haha:"<<tcpClient.waitForConnected(300);
return a.exec();
}
- 获取系统安装的office版本
获取软件的版本信息,还是通过QSettings类找到注册表中的键值。其它软件的版本获取方式类似。其示例代码如下:
#include <QApplication>
#include <QSettings>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString m_officeDecsribe;
QString describe;
QSettings settings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\excel.exe", QSettings::NativeFormat);
QString path = settings.value("Path").toString();
if(!path.isEmpty())
{
QSettings versionSettings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Excel.Application\\CurVer", QSettings::NativeFormat);
QString version = versionSettings.value(".").toString();
if(!version.isEmpty())
{
version = version.split(".").last();
int versionNum = version.toInt();
switch (versionNum)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
m_officeDecsribe = "Office 95以前版本";
break;
case 6:
m_officeDecsribe = "Office 95";
break;
case 8:
m_officeDecsribe = "Office 97";
break;
case 9:
m_officeDecsribe = "Office 2000";
break;
case 10:
m_officeDecsribe = "Office XP";
break;
case 11:
m_officeDecsribe = "Office 2003";
break;
case 12:
m_officeDecsribe = "Office 2007";
break;
case 13:
case 14:
m_officeDecsribe = "Office 2010";
break;
case 15:
m_officeDecsribe = "Office 2013";
break;
case 16:
case 17:
case 18:
case 19:
m_officeDecsribe = "Office 2013以后版本";
break;
default:
break;
}
if(versionNum >= 13)//office 2010
describe = "已安装Office 版本:" + m_officeDecsribe;
else
describe = "建议安装Microsoft Offce2010以上版本。";
}
else
describe = "建议安装Microsoft Offce2010以上版本。";
}
else
describe = "建议安装Microsoft Offce2010以上版本。";
qDebug()<<"hehe:"<<describe;
return a.exec();
}
本文所归纳的几个例子,在项目开发过程中经常用到,可以收藏,以备查阅参考。
本文到此结束!
如果对你有帮助,请随手 点个赞 或 点喜欢!随手点赞,手留余香!