Jump to content

How do I get CPU, mobo, RAM, GPU, PSU info with C++?

ClobberXD

I'm creating a system-info sorta program in C++, and I tried using GetSystemInfo(SYSTEM_INFO *) method, but in the end, excluding obsolete struct members, there are only 3 members, namely no. of logical cores, processor type, and processor architecture. That's not enough at all! I want to know the following:

  • CPU name, manufacturer, cores, architecture, speed, cache, temp, TDP
  • Mobo name, brand, chipset,
  • RAM name, capacity, speed
  • GPU name, speed, brand, temp

      Optional:

  • no. of GPU (if multi-GPU)
  • PSU name, brand, wattage, temp

Is there any library to achieve this? CPUID?

 

Thanks!

Nothing to see here ;)

Link to comment
Share on other sites

Link to post
Share on other sites

CPU info:  "CPUID" assembly instruction: https://en.wikipedia.org/wiki/CPUID

 

Motherboard: Using the windows management instruentation: https://msdn.microsoft.com/en-us/library/windows/desktop/aa393964(v=vs.85).aspx

 

RAM: Maybe trough WMI also, otherwise you'll have to find a way to probe the I²C bus. Each DIMM contains a I²C eeprom containing information about the DIMM. It's what the bios uses to auto-configure the RAM. If you can access this eeprom trough the I²C then you can pull all the info off of it.

 

GPU: WMI Win32_VideoController class: https://msdn.microsoft.com/en-us/library/aa394512(v=vs.85).aspx

 

PSU: There's no standard way as most PSU's don't even have a data connection to the actual PC. Some PSU's (high end corsair for example) have a USB connection that allows communication but that's proprietary.

Link to comment
Share on other sites

Link to post
Share on other sites

5 minutes ago, Unimportant said:

CPU info:  "CPUID" assembly instruction: https://en.wikipedia.org/wiki/CPUID

 

Motherboard: Using the windows management instruentation: https://msdn.microsoft.com/en-us/library/windows/desktop/aa393964(v=vs.85).aspx

 

RAM: Maybe trough WMI also, otherwise you'll have to find a way to probe the I²C bus. Each DIMM contains a I²C eeprom containing information about the DIMM. It's what the bios uses to auto-configure the RAM. If you can access this eeprom trough the I²C then you can pull all the info off of it.

 

GPU: WMI Win32_VideoController class: https://msdn.microsoft.com/en-us/library/aa394512(v=vs.85).aspx

 

PSU: There's no standard way as most PSU's don't even have a data connection to the actual PC. Some PSU's (high end corsair for example) have a USB connection that allows communication but that's proprietary.

I've searched online for CPUID tutorials, but all of them are complicated... Can you help me with that?

 

Thank you very much!

Nothing to see here ;)

Link to comment
Share on other sites

Link to post
Share on other sites

The question is: Do you just want to copy/paste some code or do you want to understand how it actually works?

 

In the first case there's a example from MSDN: https://msdn.microsoft.com/en-us/library/xs6aek1h(v=vs.80).aspx

 

In the second case you'll have to study some basic assembly. The CPUID instruction is actually very easy. You just have to preload some CPU registers with certain values about the kind of info you want and execute a CPUID instruction. Then inspect the CPU registers for the results.

 

Search for "inline assembly" if you want to include some assembly code in your C++ code.

Link to comment
Share on other sites

Link to post
Share on other sites

4 hours ago, Unimportant said:

The question is: Do you just want to copy/paste some code or do you want to understand how it actually works?

 

In the first case there's a example from MSDN: https://msdn.microsoft.com/en-us/library/xs6aek1h(v=vs.80).aspx

 

In the second case you'll have to study some basic assembly. The CPUID instruction is actually very easy. You just have to preload some CPU registers with certain values about the kind of info you want and execute a CPUID instruction. Then inspect the CPU registers for the results.

 

Search for "inline assembly" if you want to include some assembly code in your C++ code.

In fact google already directed me to this page, but I couldn't understand parts of it... And where is the 'sample' that is mentioned in the web-page? Moreover, I want only the CPU name primarily - instruction sets are optional when it comes to the CPU. Can you post the simplest possible code to derive the name of the CPU?

 

To answer your question, even if I want to copy-paste code, I will try to atleast understand the basics, and only then proceed... :)

 

Thanks for your help!

Nothing to see here ;)

Link to comment
Share on other sites

Link to post
Share on other sites

Give me some time and I can probably throw together a C++ library for you. Do you want it for Windows only?

Link to comment
Share on other sites

Link to post
Share on other sites

Just now, Pinguinsan said:

Give me some time and I can probably throw together a C++ library for you. Do you want it for Windows only?

Whoa! Please don't stress yourself unnecessarily - unless you are totally OK with it, I don't wanna trouble you :|. And also, I don't see me using all this again and again, just one utility for now, like a basic version of msinfo32.exe (although I might use it within other applications)

 

And yes, Windows for now - I wanna start learning, and then do cross-platform stuff... Preference: Static Library.

 

Thanks a billion!!! 9_9

Nothing to see here ;)

Link to comment
Share on other sites

Link to post
Share on other sites

The CPUID instruction does not return the CPU name as a string. It returns stepping, model, family and so on. If you want to print an actual name you have to build a database holding the names for each possible model and family so you can cross reference.

 

I don't have a windows box atm, only linux, so the following example code is for g++. You can compile it with MinGW in windows, but the inline assembly bit will probably not compile in visual studio. The essence is the same though.

Following example executes CPUID subfunctions 0 and 1 to return the vendor ID, highest supported subfunction and CPU model information:

 

#include <iostream>
#include <stdint.h>
#include <string>
#include <cstring>

//X86 CPU registers relevant to CPUID, in a struct to keep them together.
struct X86Regs
{
	uint32_t	eax;
	uint32_t	ebx;
	uint32_t	ecx;
	uint32_t	edx;
};

//Information returned by CPUID subfunction 1, in a struct to keep them together.
struct	X86CPUInfo
{
	uint32_t	Stepping;
	uint32_t	Model;
	uint32_t	Family;
	uint32_t	Type;
	uint32_t	ExtendedModel;
	uint32_t	ExtendedFamily;
};


/*The actual inline assembly CPUID function.
  This is roughly equivalent (simplified) to:

	mov eax, eax_in
	cpuid
	mov Regs_out->eax, eax
	mov Regs_out->ebx, ebx
	mov Regs_out->ecx, ecx
	mov Regs_out->edx, edx
*/
static inline void
cpuid(uint32_t eax_in, X86Regs* Regs_out)
{
	asm volatile ("cpuid"	: 	"=a"(Regs_out->eax), 
					"=b"(Regs_out->ebx),
					"=c"(Regs_out->ecx),
					"=d"(Regs_out->edx)
			 	:	"a"(eax_in));
}

//Copies the given cpu register to given char buffer.
void
CopyRegToBuff(uint32_t Reg, char* Buff)
{
	for (int i = 0; i < 4; i++)
	{
		Buff[i] = Reg & 0xFF;
		Reg >>= 8;
	}		
}

//Calls CPUID subfunction 0 to retrieve highest supported subfunction in eax.
uint32_t
GetHighestFunction()
{
	X86Regs	Regs;
	cpuid(0, &Regs);
	
	return Regs.eax;
}

//Calls CPUID subfunction 0 to retrieve vendor ID string in ebx, edx, ecx.
std::string 
GetVendorID()
{
	X86Regs	Regs;
	cpuid(0, &Regs);

	char	VendorID[13];
	memset(VendorID, 0, sizeof(VendorID));
	CopyRegToBuff(Regs.ebx, VendorID);
	CopyRegToBuff(Regs.edx, VendorID + 4);
	CopyRegToBuff(Regs.ecx, VendorID + 8);
	
	return std::string(VendorID); 
}

//Calls CPUID subfunction 1 to retrieve CPUinfo, bitmasks are explained here: 
// https://en.wikipedia.org/wiki/CPUID#EAX.3D1:_Processor_Info_and_Feature_Bits
void
GetCPUInfo(X86CPUInfo& CPUInfo)
{
	X86Regs Regs;
	cpuid(1, &Regs);

	CPUInfo.Stepping = Regs.eax & 0x0F;
	CPUInfo.Model = (Regs.eax & 0xF0) >> 4;
	CPUInfo.Family = (Regs.eax & 0xF00) >> 8;
	CPUInfo.Type = (Regs.eax & 0x3000) >> 12;
	CPUInfo.ExtendedModel = (Regs.eax & 0xF0000) >> 16;
	CPUInfo.ExtendedFamily = (Regs.eax & 0xFF00000) >> 20;
}

int main()
{
	std::cout << '\n';
	std::cout << "Vendor.............................: " << GetVendorID() << '\n';
	std::cout << "Highest supported CPUID subfunction: " << GetHighestFunction() << '\n';

	X86CPUInfo CPUInfo;
	GetCPUInfo(CPUInfo);
	std::cout << "Stepping...........................: " << CPUInfo.Stepping << '\n';
	std::cout << "Model..............................: " << CPUInfo.Model << '\n';
	std::cout << "Family.............................: " << CPUInfo.Family << '\n';
	std::cout << "Type...............................: " << CPUInfo.Type << '\n';
	std::cout << "Extended Model.....................: " << CPUInfo.ExtendedModel << '\n';
	std::cout << "Extended Family....................: " << CPUInfo.ExtendedFamily << "\n\n";

	return 0;
}

 

Link to comment
Share on other sites

Link to post
Share on other sites

9 hours ago, Anand_Geforce said:

Whoa! Please don't stress yourself unnecessarily - unless you are totally OK with it, I don't wanna trouble you :|. And also, I don't see me using all this again and again, just one utility for now, like a basic version of msinfo32.exe (although I might use it within other applications)

 

And yes, Windows for now - I wanna start learning, and then do cross-platform stuff... Preference: Static Library.

 

Thanks a billion!!! 9_9

Well, you should start thinking multi-platform straight away, before it's too late, before you get too used to Windows-specific libraries and such.

Link to comment
Share on other sites

Link to post
Share on other sites

15 hours ago, Unimportant said:

The CPUID instruction does not return the CPU name as a string. It returns stepping, model, family and so on. If you want to print an actual name you have to build a database holding the names for each possible model and family so you can cross reference.

 

I don't have a windows box atm, only linux, so the following example code is for g++. You can compile it with MinGW in windows, but the inline assembly bit will probably not compile in visual studio. The essence is the same though.

Following example executes CPUID subfunctions 0 and 1 to return the vendor ID, highest supported subfunction and CPU model information:

 


#include <iostream>
#include <stdint.h>
#include <string>
#include <cstring>

//X86 CPU registers relevant to CPUID, in a struct to keep them together.
struct X86Regs
{
	uint32_t	eax;
	uint32_t	ebx;
	uint32_t	ecx;
	uint32_t	edx;
};

//Information returned by CPUID subfunction 1, in a struct to keep them together.
struct	X86CPUInfo
{
	uint32_t	Stepping;
	uint32_t	Model;
	uint32_t	Family;
	uint32_t	Type;
	uint32_t	ExtendedModel;
	uint32_t	ExtendedFamily;
};


/*The actual inline assembly CPUID function.
  This is roughly equivalent (simplified) to:

	mov eax, eax_in
	cpuid
	mov Regs_out->eax, eax
	mov Regs_out->ebx, ebx
	mov Regs_out->ecx, ecx
	mov Regs_out->edx, edx
*/
static inline void
cpuid(uint32_t eax_in, X86Regs* Regs_out)
{
	asm volatile ("cpuid"	: 	"=a"(Regs_out->eax), 
					"=b"(Regs_out->ebx),
					"=c"(Regs_out->ecx),
					"=d"(Regs_out->edx)
			 	:	"a"(eax_in));
}

//Copies the given cpu register to given char buffer.
void
CopyRegToBuff(uint32_t Reg, char* Buff)
{
	for (int i = 0; i < 4; i++)
	{
		Buff[i] = Reg & 0xFF;
		Reg >>= 8;
	}		
}

//Calls CPUID subfunction 0 to retrieve highest supported subfunction in eax.
uint32_t
GetHighestFunction()
{
	X86Regs	Regs;
	cpuid(0, &Regs);
	
	return Regs.eax;
}

//Calls CPUID subfunction 0 to retrieve vendor ID string in ebx, edx, ecx.
std::string 
GetVendorID()
{
	X86Regs	Regs;
	cpuid(0, &Regs);

	char	VendorID[13];
	memset(VendorID, 0, sizeof(VendorID));
	CopyRegToBuff(Regs.ebx, VendorID);
	CopyRegToBuff(Regs.edx, VendorID + 4);
	CopyRegToBuff(Regs.ecx, VendorID + 8);
	
	return std::string(VendorID); 
}

//Calls CPUID subfunction 1 to retrieve CPUinfo, bitmasks are explained here: 
// https://en.wikipedia.org/wiki/CPUID#EAX.3D1:_Processor_Info_and_Feature_Bits
void
GetCPUInfo(X86CPUInfo& CPUInfo)
{
	X86Regs Regs;
	cpuid(1, &Regs);

	CPUInfo.Stepping = Regs.eax & 0x0F;
	CPUInfo.Model = (Regs.eax & 0xF0) >> 4;
	CPUInfo.Family = (Regs.eax & 0xF00) >> 8;
	CPUInfo.Type = (Regs.eax & 0x3000) >> 12;
	CPUInfo.ExtendedModel = (Regs.eax & 0xF0000) >> 16;
	CPUInfo.ExtendedFamily = (Regs.eax & 0xFF00000) >> 20;
}

int main()
{
	std::cout << '\n';
	std::cout << "Vendor.............................: " << GetVendorID() << '\n';
	std::cout << "Highest supported CPUID subfunction: " << GetHighestFunction() << '\n';

	X86CPUInfo CPUInfo;
	GetCPUInfo(CPUInfo);
	std::cout << "Stepping...........................: " << CPUInfo.Stepping << '\n';
	std::cout << "Model..............................: " << CPUInfo.Model << '\n';
	std::cout << "Family.............................: " << CPUInfo.Family << '\n';
	std::cout << "Type...............................: " << CPUInfo.Type << '\n';
	std::cout << "Extended Model.....................: " << CPUInfo.ExtendedModel << '\n';
	std::cout << "Extended Family....................: " << CPUInfo.ExtendedFamily << "\n\n";

	return 0;
}

 

Nice, but how do I make it work in Visual Studio?

Nothing to see here ;)

Link to comment
Share on other sites

Link to post
Share on other sites

Sorry, I'm still working on it. Getting the temperature for the GPU is proving to be the hardest. It's doable with some Nvidia/AMD *.dll's, but there's no real native Windows way to do it. Standby though, I'm still working on it.

Link to comment
Share on other sites

Link to post
Share on other sites

2 hours ago, Anand_Geforce said:

Nice, but how do I make it work in Visual Studio?

#include <iostream>
#include <stdint.h>
#include <string>
#include <cstring>

//X86 CPU registers relevant to CPUID, in a struct to keep them together.
struct X86Regs
{
	uint32_t	eax;
	uint32_t	ebx;
	uint32_t	ecx;
	uint32_t	edx;
};

//Information returned by CPUID subfunction 1, in a struct to keep them together.
struct	X86CPUInfo
{
	uint32_t	Stepping;
	uint32_t	Model;
	uint32_t	Family;
	uint32_t	Type;
	uint32_t	ExtendedModel;
	uint32_t	ExtendedFamily;
};


//The actual inline assembly CPUID function.
static inline void
cpuid(uint32_t eax_in, X86Regs* Regs_out)
{
	__asm
	{
		mov eax, eax_in				//load eax_in argument to actual eax register
		cpuid					//perform cpuid instruction
		push edx				//save edx on stack
		mov edx, Regs_out			//copy value of Regs_out pointer to edx register
		mov [edx].eax, eax			
		mov [edx].ebx, ebx
		mov [edx].ecx, ecx			//save eax, ebx and ecx to struct 
		mov ebx, edx				//now copy Regs_out pointer to ebx
		pop edx					//retrieve edx from stack
		mov [ebx].edx, edx			//save edx to struct
	}
}

//Copies the given cpu register to given char buffer.
void
CopyRegToBuff(uint32_t Reg, char* Buff)
{
	for (int i = 0; i < 4; i++)
	{
		Buff[i] = Reg & 0xFF;
		Reg >>= 8;
	}
}

//Calls CPUID subfunction 0 to retrieve highest supported subfunction in eax.
uint32_t
GetHighestFunction()
{
	X86Regs	Regs;
	cpuid(0, &Regs);

	return Regs.eax;
}

//Calls CPUID subfunction 0 to retrieve vendor ID string in ebx, edx, ecx.
std::string
GetVendorID()
{
	X86Regs	Regs;
	cpuid(0, &Regs);

	char	VendorID[13];
	memset(VendorID, 0, sizeof(VendorID));
	CopyRegToBuff(Regs.ebx, VendorID);
	CopyRegToBuff(Regs.edx, VendorID + 4);
	CopyRegToBuff(Regs.ecx, VendorID + 8);

	return std::string(VendorID);
}

//Calls CPUID subfunction 1 to retrieve CPUinfo, bitmasks are explained here: 
// https://en.wikipedia.org/wiki/CPUID#EAX.3D1:_Processor_Info_and_Feature_Bits
void
GetCPUInfo(X86CPUInfo& CPUInfo)
{
	X86Regs Regs;
	cpuid(1, &Regs);

	CPUInfo.Stepping = Regs.eax & 0x0F;
	CPUInfo.Model = (Regs.eax & 0xF0) >> 4;
	CPUInfo.Family = (Regs.eax & 0xF00) >> 8;
	CPUInfo.Type = (Regs.eax & 0x3000) >> 12;
	CPUInfo.ExtendedModel = (Regs.eax & 0xF0000) >> 16;
	CPUInfo.ExtendedFamily = (Regs.eax & 0xFF00000) >> 20;
}

int main()
{
	std::cout << '\n';
	std::cout << "Vendor.............................: " << GetVendorID() << '\n';
	std::cout << "Highest supported CPUID subfunction: " << GetHighestFunction() << '\n';

	X86CPUInfo CPUInfo;
	GetCPUInfo(CPUInfo);
	std::cout << "Stepping...........................: " << CPUInfo.Stepping << '\n';
	std::cout << "Model..............................: " << CPUInfo.Model << '\n';
	std::cout << "Family.............................: " << CPUInfo.Family << '\n';
	std::cout << "Type...............................: " << CPUInfo.Type << '\n';
	std::cout << "Extended Model.....................: " << CPUInfo.ExtendedModel << '\n';
	std::cout << "Extended Family....................: " << CPUInfo.ExtendedFamily << "\n\n";

	int i;
	std::cin >> i;

	return 0;
}

Visual c++ version, untested.

Link to comment
Share on other sites

Link to post
Share on other sites

2 hours ago, Pinguinsan said:

Sorry, I'm still working on it. Getting the temperature for the GPU is proving to be the hardest. It's doable with some Nvidia/AMD *.dll's, but there's no real native Windows way to do it. Standby though, I'm still working on it.

Again, I don't wanna force you or trouble you. Thank you very much for helping me in a big way! :)

Nothing to see here ;)

Link to comment
Share on other sites

Link to post
Share on other sites

Hey, no problem man. The library is done but it doesn't hit all of the things you initially wanted. A few things (CPU temp, GPU temp) are extremely involved and there isn't a good hardware-independent way of doing it. As well, getting the Motherboard chipset seemed almost impossible as well (at least using WMIC, which the entire library is built around). Otherwise, this was my "main.cpp", testing out the library (the "xxxxinfodelegate.h" classes are used to populate the information about all of the items):

#include <iostream>
#include <string>
#include <vector>

#include "stdafx.h"
#include "cpuinfodelegate.h"
#include "motherboardinfodelegate.h"
#include "raminfodelegate.h"
#include "gpuinfodelegate.h"


int main(int argc, char *argv[])
{
    //First make a delegate object that handles the cases where the computer has multiple CPUs
	CPUInfoDelegate *cpuInfo = new CPUInfoDelegate();

    //Then extract the separate CPUs into a vector (of CPUInfo objects)
	std::vector<CPUInfo> cpuInfoVector = cpuInfo->cpuInfoVector();

    //Print out the number of CPUs, directory from the delegate object
	std::cout << "This computer has " << cpuInfo->numberOfCPUInfoItems() << " CPU(s) installed" << std::endl;
    
    //Iterate through all of the CPUs and print out the information for all of them
	int CPUCount = 1;
	for (std::vector<CPUInfo>::iterator iter = cpuInfoVector.begin(); iter != cpuInfoVector.end(); iter++) {
		std::cout << "Information for CPU #" << CPUCount << ": " << std::endl;
		std::cout << "CPU Name = " << iter->name() << std::endl;
		std::cout << "CPU Manufacturer = " << iter->manufacturer() << std::endl;
		std::cout << "Number of CPU Cores = " << iter->numberOfCores() << std::endl;
		std::cout << "Current CPU Clock Speed = " << iter->currentClockSpeed() << std::endl;
		std::cout << "CPU Architecture = " << iter->architecture() << std::endl;
		std::cout << "CPU L2 Cache Size = " << iter->L2CacheSize() << std::endl;
		std::cout << "CPU L3 Cache Size = " << iter->L3CacheSize() << std::endl;
		std::cout << "Current CPU Temperature = " << iter->currentTemperature() << std::endl;
		std::cout << std::endl;
		CPUCount++;
	}
    delete cpuInfo;

	MotherboardInfoDelegate *moboInfo = new MotherboardInfoDelegate();
	std::vector<MotherboardInfo> moboInfoVector = moboInfo->motherboardInfoVector();
    std::cout << "This computer has " << moboInfo->numberOfMotherboardInfoItems() << " motherboard(s) installed" << std::endl;
	int motherboardCount = 1;
	for (std::vector<MotherboardInfo>::const_iterator iter = moboInfoVector.begin(); iter != moboInfoVector.end(); iter++) {
		std::cout << "Information for motherboard #" << motherboardCount << ": " << std::endl;
		std::cout << "Motherboard Name = " << iter->name() << std::endl;
		std::cout << "Motherboard Manufacturer = " << iter->manufacturer() << std::endl;
		std::cout << "Motherboard Chipset = " << iter->chipset() << std::endl;
		std::cout << "Motherboard Serial Number = " << iter->serialNumber() << std::endl;
		std::cout << "Motherboard Version = " << iter->version() << std::endl;
		std::cout << std::endl;
		motherboardCount++;
	}
    delete moboInfo;

    RAMInfoDelegate *ramInfo = new RAMInfoDelegate();
    std::vector<RAMInfo> ramInfoVector = ramInfo->ramInfoVector();
    std::cout << "This computer has " << ramInfo->numberOfRAMInfoItems() << " RAM stick(s) installed" << std::endl;
    int ramCount = 1;
    for (std::vector<RAMInfo>::const_iterator iter = ramInfoVector.begin(); iter != ramInfoVector.end(); iter++) {
        std::cout << "Information for RAM stick #" << ramCount << ": " << std::endl;
        std::cout << "RAM Name = " << iter->name() << std::endl;
        std::cout << "RAM Manufacturer = " << iter->manufacturer() << std::endl;
        std::cout << "RAM Capacity = " << iter->capacity() << std::endl;
        std::cout << "RAM Serial Number = " << iter->serialNumber() << std::endl;
        std::cout << "RAM Form Factor = " << iter->formFactor() << std::endl;
        std::cout << "RAM Part Number = " << iter->partNumber() << std::endl;
        std::cout << "RAM Memory Type = " << iter->memoryType() << std::endl;
        std::cout << "RAM Clock Speed = " << iter->clockSpeed() << std::endl;
        std::cout << std::endl;
        ramCount++;
    }
    delete ramInfo;

    GPUInfoDelegate *gpuInfo = new GPUInfoDelegate();
    std::vector<GPUInfo> gpuInfoVector = gpuInfo->gpuInfoVector();
    std::cout << "This computer has " << gpuInfo->numberOfGPUInfoItems() << " GPU(s) installed" << std::endl;
    int gpuCount = 1;
    for (std::vector<GPUInfo>::const_iterator iter = gpuInfoVector.begin(); iter != gpuInfoVector.end(); iter++) {
        std::cout << "Information for GPU #" << gpuCount << ": " << std::endl;
        std::cout << "GPU Name = " << iter->name() << std::endl;
        std::cout << "GPU Manufacturer = " << iter->manufacturer() << std::endl;
        std::cout << "GPU Adapter RAM = " << iter->adapterRAM() << std::endl;
        std::cout << "GPU Refresh Rate = " << iter->refreshRate() << std::endl;
        std::cout << "GPU Driver Version = " << iter->driverVersion() << std::endl;
        std::cout << "GPU Video Architecture = " << iter->videoArchitecture() << std::endl;
        std::cout << "GPU Video Mode Description = " << iter->videoModeDescription() << std::endl;
        std::cout << std::endl;
        gpuCount++;
    }
    std::cout << std::endl << "Press any button to continue...";
	std::cin.get();
    return 0;
}

 

And the output (running it on my local machine):

 

This computer has 1 CPU(s) installed
Information for CPU #1:
CPU Name = Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
CPU Manufacturer = GenuineIntel
Number of CPU Cores = 4
Current CPU Clock Speed = 4008MHz
CPU Architecture = x86_64
CPU L2 Cache Size = 1024KB
CPU L3 Cache Size = 8192KB
Current CPU Temperature = unknown

This computer has 1 motherboard(s) installed
Information for motherboard #1:
Motherboard Name = Z170A XPOWER GAMING TITANIUM EDITION(MS-7968)
Motherboard Manufacturer = MSI
Motherboard Chipset = Intel(R) 100 Series/C230 Series Chipset
Motherboard Serial Number = G316062268
Motherboard Version = 3.0

This computer has 4 RAM stick(s) installed
Information for RAM stick #1:
RAM Name = ChannelA-DIMM0
RAM Manufacturer = 1315
RAM Capacity = 8589MB (8589934592 Bytes)
RAM Serial Number = 16171913
RAM Form Factor = DIMM
RAM Part Number = BLE8G4D26AFEA.16FAD
RAM Memory Type = Unknown
RAM Clock Speed = 2667MHz

Information for RAM stick #2:
RAM Name = ChannelA-DIMM1
RAM Manufacturer = 1315
RAM Capacity = 8589MB (8589934592 Bytes)
RAM Serial Number = 16231222
RAM Form Factor = DIMM
RAM Part Number = BLE8G4D26AFEA.16FAD
RAM Memory Type = Unknown
RAM Clock Speed = 2667MHz

Information for RAM stick #3:
RAM Name = ChannelB-DIMM0
RAM Manufacturer = 1315
RAM Capacity = 8589MB (8589934592 Bytes)
RAM Serial Number = 16114821
RAM Form Factor = DIMM
RAM Part Number = BLE8G4D26AFEA.16FAD
RAM Memory Type = Unknown
RAM Clock Speed = 2667MHz

Information for RAM stick #4:
RAM Name = ChannelB-DIMM1
RAM Manufacturer = 1315
RAM Capacity = 8589MB (8589934592 Bytes)
RAM Serial Number = 16171913
RAM Form Factor = DIMM
RAM Part Number = BLE8G4D26AFEA.16FAD
RAM Memory Type = Unknown
RAM Clock Speed = 2667MHz

This computer has 1 GPU(s) installed
Information for GPU #1:
GPU Name = NVIDIA GeForce GTX 980 Ti
GPU Manufacturer = NVIDIA
GPU Adapter RAM = 4293MB (4293918720 Bytes)
GPU Refresh Rate = 144MHz
GPU Driver Version = 10.18.13.6881
GPU Video Architecture = Unknown
GPU Video Mode Description = 1920 x 1080 x 4294967296 colors


Press any button to continue...

The code (right now) is located at https://github.com/Pinguinsan/SystemInfo

It is all in one gigantic folder, but you should be able to open the SystemInfo.sln file up and run it on your local machine. From there, I'll work on getting a .sln file for building just a single library so you can build one of those, too. Give it a try and let me know what you think. The library is VERY hacky (relying on the Windows cmd.exe and wmic), but it will work for the short term (I think you mentioned just doing it temporarily?). Also, if it isn't obvious, this will absolutely only work on windows :)

Link to comment
Share on other sites

Link to post
Share on other sites

Excellent! I just tried the code on my laptop (which has a hybrid dGPU (AMD Radeon) and iGPU (Intel i7)), and it picked up and displayed both of them. Output from my laptop:

This computer has 1 CPU(s) installed
Information for CPU #1:
CPU Name = Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz
CPU Manufacturer = GenuineIntel
Number of CPU Cores = 2
Current CPU Clock Speed = 2601MHz
CPU Architecture = x86_64
CPU L2 Cache Size = 512KB
CPU L3 Cache Size = 4096KB
Current CPU Temperature = unknown

This computer has 1 motherboard(s) installed
Information for motherboard #1:
Motherboard Name = 052K07
Motherboard Manufacturer = Dell Inc.
Motherboard Chipset = Intel(R) 100 Series Chipset
Motherboard Serial Number = /97MRN72/CN1296363M03D8/
Motherboard Version = A00

This computer has 2 RAM stick(s) installed
Information for RAM stick #1:
RAM Name = DIMM A
RAM Manufacturer = SK Hynix
RAM Capacity = 8589MB (8589934592 Bytes)
RAM Serial Number = 12151215
RAM Form Factor = SODIMM
RAM Part Number = HMT41GS6BFR8A-PB
RAM Memory Type = DDR3
RAM Clock Speed = 1600MHz

Information for RAM stick #2:
RAM Name = DIMM B
RAM Manufacturer = SK Hynix
RAM Capacity = 8589MB (8589934592 Bytes)
RAM Serial Number = 12121212
RAM Form Factor = SODIMM
RAM Part Number = HMT41GS6BFR8A-PB
RAM Memory Type = DDR3
RAM Clock Speed = 1600MHz

This computer has 2 GPU(s) installed
Information for GPU #1:
GPU Name = AMD Radeon (TM) R5 M335
GPU Manufacturer = Advanced Micro Devices, Inc.
GPU Caption = AMD Radeon (TM) R5 M335
GPU Adapter RAM = 4293MB (4293918720 Bytes)
GPU Refresh Rate = Unknown
GPU Driver Version = 16.150.2211.0
GPU Video Architecture = Unknown
GPU Video Mode Description = Unknown
GPU Video Processor = AMD Radeon Graphics Processor (0x6660)

Information for GPU #2:
GPU Name = Intel(R) HD Graphics 520
GPU Manufacturer = Intel Corporation
GPU Caption = Intel(R) HD Graphics 520
GPU Adapter RAM = 1073MB (1073741824 Bytes)
GPU Refresh Rate = 59MHz
GPU Driver Version = 20.19.15.4444
GPU Video Architecture = Unknown
GPU Video Mode Description = 1920 x 1080 x 4294967296 colors
GPU Video Processor = Intel(R) HD Graphics Family


Press any button to continue...

 

Link to comment
Share on other sites

Link to post
Share on other sites

8 hours ago, Pinguinsan said:

Hey, no problem man. The library is done but it doesn't hit all of the things you initially wanted. A few things (CPU temp, GPU temp) are extremely involved and there isn't a good hardware-independent way of doing it. As well, getting the Motherboard chipset seemed almost impossible as well (at least using WMIC, which the entire library is built around). Otherwise, this was my "main.cpp", testing out the library (the "xxxxinfodelegate.h" classes are used to populate the information about all of the items):


#include <iostream>
#include <string>
#include <vector>

#include "stdafx.h"
#include "cpuinfodelegate.h"
#include "motherboardinfodelegate.h"
#include "raminfodelegate.h"
#include "gpuinfodelegate.h"


int main(int argc, char *argv[])
{
    //First make a delegate object that handles the cases where the computer has multiple CPUs
	CPUInfoDelegate *cpuInfo = new CPUInfoDelegate();

    //Then extract the separate CPUs into a vector (of CPUInfo objects)
	std::vector<CPUInfo> cpuInfoVector = cpuInfo->cpuInfoVector();

    //Print out the number of CPUs, directory from the delegate object
	std::cout << "This computer has " << cpuInfo->numberOfCPUInfoItems() << " CPU(s) installed" << std::endl;
    
    //Iterate through all of the CPUs and print out the information for all of them
	int CPUCount = 1;
	for (std::vector<CPUInfo>::iterator iter = cpuInfoVector.begin(); iter != cpuInfoVector.end(); iter++) {
		std::cout << "Information for CPU #" << CPUCount << ": " << std::endl;
		std::cout << "CPU Name = " << iter->name() << std::endl;
		std::cout << "CPU Manufacturer = " << iter->manufacturer() << std::endl;
		std::cout << "Number of CPU Cores = " << iter->numberOfCores() << std::endl;
		std::cout << "Current CPU Clock Speed = " << iter->currentClockSpeed() << std::endl;
		std::cout << "CPU Architecture = " << iter->architecture() << std::endl;
		std::cout << "CPU L2 Cache Size = " << iter->L2CacheSize() << std::endl;
		std::cout << "CPU L3 Cache Size = " << iter->L3CacheSize() << std::endl;
		std::cout << "Current CPU Temperature = " << iter->currentTemperature() << std::endl;
		std::cout << std::endl;
		CPUCount++;
	}
    delete cpuInfo;

	MotherboardInfoDelegate *moboInfo = new MotherboardInfoDelegate();
	std::vector<MotherboardInfo> moboInfoVector = moboInfo->motherboardInfoVector();
    std::cout << "This computer has " << moboInfo->numberOfMotherboardInfoItems() << " motherboard(s) installed" << std::endl;
	int motherboardCount = 1;
	for (std::vector<MotherboardInfo>::const_iterator iter = moboInfoVector.begin(); iter != moboInfoVector.end(); iter++) {
		std::cout << "Information for motherboard #" << motherboardCount << ": " << std::endl;
		std::cout << "Motherboard Name = " << iter->name() << std::endl;
		std::cout << "Motherboard Manufacturer = " << iter->manufacturer() << std::endl;
		std::cout << "Motherboard Chipset = " << iter->chipset() << std::endl;
		std::cout << "Motherboard Serial Number = " << iter->serialNumber() << std::endl;
		std::cout << "Motherboard Version = " << iter->version() << std::endl;
		std::cout << std::endl;
		motherboardCount++;
	}
    delete moboInfo;

    RAMInfoDelegate *ramInfo = new RAMInfoDelegate();
    std::vector<RAMInfo> ramInfoVector = ramInfo->ramInfoVector();
    std::cout << "This computer has " << ramInfo->numberOfRAMInfoItems() << " RAM stick(s) installed" << std::endl;
    int ramCount = 1;
    for (std::vector<RAMInfo>::const_iterator iter = ramInfoVector.begin(); iter != ramInfoVector.end(); iter++) {
        std::cout << "Information for RAM stick #" << ramCount << ": " << std::endl;
        std::cout << "RAM Name = " << iter->name() << std::endl;
        std::cout << "RAM Manufacturer = " << iter->manufacturer() << std::endl;
        std::cout << "RAM Capacity = " << iter->capacity() << std::endl;
        std::cout << "RAM Serial Number = " << iter->serialNumber() << std::endl;
        std::cout << "RAM Form Factor = " << iter->formFactor() << std::endl;
        std::cout << "RAM Part Number = " << iter->partNumber() << std::endl;
        std::cout << "RAM Memory Type = " << iter->memoryType() << std::endl;
        std::cout << "RAM Clock Speed = " << iter->clockSpeed() << std::endl;
        std::cout << std::endl;
        ramCount++;
    }
    delete ramInfo;

    GPUInfoDelegate *gpuInfo = new GPUInfoDelegate();
    std::vector<GPUInfo> gpuInfoVector = gpuInfo->gpuInfoVector();
    std::cout << "This computer has " << gpuInfo->numberOfGPUInfoItems() << " GPU(s) installed" << std::endl;
    int gpuCount = 1;
    for (std::vector<GPUInfo>::const_iterator iter = gpuInfoVector.begin(); iter != gpuInfoVector.end(); iter++) {
        std::cout << "Information for GPU #" << gpuCount << ": " << std::endl;
        std::cout << "GPU Name = " << iter->name() << std::endl;
        std::cout << "GPU Manufacturer = " << iter->manufacturer() << std::endl;
        std::cout << "GPU Adapter RAM = " << iter->adapterRAM() << std::endl;
        std::cout << "GPU Refresh Rate = " << iter->refreshRate() << std::endl;
        std::cout << "GPU Driver Version = " << iter->driverVersion() << std::endl;
        std::cout << "GPU Video Architecture = " << iter->videoArchitecture() << std::endl;
        std::cout << "GPU Video Mode Description = " << iter->videoModeDescription() << std::endl;
        std::cout << std::endl;
        gpuCount++;
    }
    std::cout << std::endl << "Press any button to continue...";
	std::cin.get();
    return 0;
}

 

And the output (running it on my local machine):

 


This computer has 1 CPU(s) installed
Information for CPU #1:
CPU Name = Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
CPU Manufacturer = GenuineIntel
Number of CPU Cores = 4
Current CPU Clock Speed = 4008MHz
CPU Architecture = x86_64
CPU L2 Cache Size = 1024KB
CPU L3 Cache Size = 8192KB
Current CPU Temperature = unknown

This computer has 1 motherboard(s) installed
Information for motherboard #1:
Motherboard Name = Z170A XPOWER GAMING TITANIUM EDITION(MS-7968)
Motherboard Manufacturer = MSI
Motherboard Chipset = Intel(R) 100 Series/C230 Series Chipset
Motherboard Serial Number = G316062268
Motherboard Version = 3.0

This computer has 4 RAM stick(s) installed
Information for RAM stick #1:
RAM Name = ChannelA-DIMM0
RAM Manufacturer = 1315
RAM Capacity = 8589MB (8589934592 Bytes)
RAM Serial Number = 16171913
RAM Form Factor = DIMM
RAM Part Number = BLE8G4D26AFEA.16FAD
RAM Memory Type = Unknown
RAM Clock Speed = 2667MHz

Information for RAM stick #2:
RAM Name = ChannelA-DIMM1
RAM Manufacturer = 1315
RAM Capacity = 8589MB (8589934592 Bytes)
RAM Serial Number = 16231222
RAM Form Factor = DIMM
RAM Part Number = BLE8G4D26AFEA.16FAD
RAM Memory Type = Unknown
RAM Clock Speed = 2667MHz

Information for RAM stick #3:
RAM Name = ChannelB-DIMM0
RAM Manufacturer = 1315
RAM Capacity = 8589MB (8589934592 Bytes)
RAM Serial Number = 16114821
RAM Form Factor = DIMM
RAM Part Number = BLE8G4D26AFEA.16FAD
RAM Memory Type = Unknown
RAM Clock Speed = 2667MHz

Information for RAM stick #4:
RAM Name = ChannelB-DIMM1
RAM Manufacturer = 1315
RAM Capacity = 8589MB (8589934592 Bytes)
RAM Serial Number = 16171913
RAM Form Factor = DIMM
RAM Part Number = BLE8G4D26AFEA.16FAD
RAM Memory Type = Unknown
RAM Clock Speed = 2667MHz

This computer has 1 GPU(s) installed
Information for GPU #1:
GPU Name = NVIDIA GeForce GTX 980 Ti
GPU Manufacturer = NVIDIA
GPU Adapter RAM = 4293MB (4293918720 Bytes)
GPU Refresh Rate = 144MHz
GPU Driver Version = 10.18.13.6881
GPU Video Architecture = Unknown
GPU Video Mode Description = 1920 x 1080 x 4294967296 colors


Press any button to continue...

The code (right now) is located at https://github.com/Pinguinsan/SystemInfo

It is all in one gigantic folder, but you should be able to open the SystemInfo.sln file up and run it on your local machine. From there, I'll work on getting a .sln file for building just a single library so you can build one of those, too. Give it a try and let me know what you think. The library is VERY hacky (relying on the Windows cmd.exe and wmic), but it will work for the short term (I think you mentioned just doing it temporarily?). Also, if it isn't obvious, this will absolutely only work on windows :)

It works! Thanks a billion!!! :) But one minor flaw... It works when configured as Debug, but not as 'Release'.

Nothing to see here ;)

Link to comment
Share on other sites

Link to post
Share on other sites

No problem! I have pushed a couple of small changes, notably that when you use the objects, you only need to include "systeminfo.h" instead of the "xxxxinfodelegate.h" headers. Oh, and you don't need to include the "stdafx.h" header anymore either. As well, I added a couple of bugfixes. Either way, you can see the changed I made in the up to date repository. On my local machine, it builds and runs okay after switching the target to release. Could you give it a shot?

For funsies, I also made a new VS project to compile the code as a static library, and it compiled to a *.lib okay. Let me know if you want any help with compiling a static/dynamic library, I'll do the best that I can to help (I don't use Visual Studio too much).

Link to comment
Share on other sites

Link to post
Share on other sites

On 31.7.2016 at 8:29 PM, Unimportant said:

The CPUID instruction does not return the CPU name as a string. It returns stepping, model, family and so on. If you want to print an actual name you have to build a database holding the names for each possible model and family so you can cross reference.

 

 

I'd like to correct myself here. After some reading up it seems CPUID can return a string with the processor name using subfunctions 0x80000002, 0x80000003, 0x80000004. Each subfunction returns 16 bytes of the string in eax, ebx, ecx and edx, for a total of 48 bytes.

Link to comment
Share on other sites

Link to post
Share on other sites

11 minutes ago, AlexTheRose said:

Strange that no one has asked this before, but… why don’t you just use libcpuid? Reinventing the wheel seems kinda pointless.

He wants information about the CPU, GPU, Motherboard, and RAM, not just the CPU.

Link to comment
Share on other sites

Link to post
Share on other sites

8 hours ago, AlexTheRose said:

Yeah, but aren’t there already programs that do this on every major platform?

 

If it’s for a learning experience or something then that’s different, but if that’s the case writing a library for him would be an egregious case of giving a man a fish… lol

Actually yes - learning how it all works is the whole point of this endeavour. And even if @Pinguinsan gives me a whole library of sorts, I won't publicly distribute it (also not without crediting him). I am analyzing the code, how it all comes together, and what methods have been used, etc., right now, to understand the concept of communicating with system hardware. :)

Nothing to see here ;)

Link to comment
Share on other sites

Link to post
Share on other sites

On ‎8‎/‎2‎/‎2016 at 4:09 PM, Anand_Geforce said:

It works! Thanks a billion!!! :) But one minor flaw... It works when configured as Debug, but not as 'Release'.

Can you put the code on GitHub :)?

 

I'm also kinda interested in this except I previously gave up cos I thought it was too hard.

 

You don't need C++ to be able to display a lot of information about a PC. You can use C# but some parts are more hard than the C++ equivalent.

Judge a product on its own merits AND the company that made it.

How to setup MSI Afterburner OSD | How to make your AMD Radeon GPU more efficient with Radeon Chill | (Probably) Why LMG Merch shipping to the EU is expensive

Oneplus 6 (Early 2023 to present) | HP Envy 15" x360 R7 5700U (Mid 2021 to present) | Steam Deck (Late 2022 to present)

 

Mid 2023 AlTech Desktop Refresh - AMD R7 5800X (Mid 2023), XFX Radeon RX 6700XT MBA (Mid 2021), MSI X370 Gaming Pro Carbon (Early 2018), 32GB DDR4-3200 (16GB x2) (Mid 2022

Noctua NH-D15 (Early 2021), Corsair MP510 1.92TB NVMe SSD (Mid 2020), beQuiet Pure Wings 2 140mm x2 & 120mm x1 (Mid 2023),

Link to comment
Share on other sites

Link to post
Share on other sites

On 2/8/2016 at 1:39 PM, Anand_Geforce said:

The code (right now) is located at https://github.com/Pinguinsan/SystemInfo

 

2 hours ago, AluminiumTech said:

Can you put the code on GitHub :)?

 

I'm also kinda interested in this except I previously gave up cos I thought it was too hard.

 

You don't need C++ to be able to display a lot of information about a PC. You can use C# but some parts are more hard than the C++ equivalent.

That's the code above - I haven't even touched it yet... I don't want to mess it up! :)

Nothing to see here ;)

Link to comment
Share on other sites

Link to post
Share on other sites

25 minutes ago, Anand_Geforce said:

 

That's the code above - I haven't even touched it yet... I don't want to mess it up! :)

Thanks :).

Judge a product on its own merits AND the company that made it.

How to setup MSI Afterburner OSD | How to make your AMD Radeon GPU more efficient with Radeon Chill | (Probably) Why LMG Merch shipping to the EU is expensive

Oneplus 6 (Early 2023 to present) | HP Envy 15" x360 R7 5700U (Mid 2021 to present) | Steam Deck (Late 2022 to present)

 

Mid 2023 AlTech Desktop Refresh - AMD R7 5800X (Mid 2023), XFX Radeon RX 6700XT MBA (Mid 2021), MSI X370 Gaming Pro Carbon (Early 2018), 32GB DDR4-3200 (16GB x2) (Mid 2022

Noctua NH-D15 (Early 2021), Corsair MP510 1.92TB NVMe SSD (Mid 2020), beQuiet Pure Wings 2 140mm x2 & 120mm x1 (Mid 2023),

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Anand_Geforce said:

 

That's the code above - I haven't even touched it yet... I don't want to mess it up! :)

Oops. Too late. It's already messed up. I cloned the GitHub repo and tried to run it. But it gave me loads of errors :(.

 

I'm using VS 2015 Update 3. All the C++ parts enabled.

 

I decided to work on a C# version of mine from scratch and I've got some errors. I can get most of the stuff you asked for but maybe not the PSU.

Judge a product on its own merits AND the company that made it.

How to setup MSI Afterburner OSD | How to make your AMD Radeon GPU more efficient with Radeon Chill | (Probably) Why LMG Merch shipping to the EU is expensive

Oneplus 6 (Early 2023 to present) | HP Envy 15" x360 R7 5700U (Mid 2021 to present) | Steam Deck (Late 2022 to present)

 

Mid 2023 AlTech Desktop Refresh - AMD R7 5800X (Mid 2023), XFX Radeon RX 6700XT MBA (Mid 2021), MSI X370 Gaming Pro Carbon (Early 2018), 32GB DDR4-3200 (16GB x2) (Mid 2022

Noctua NH-D15 (Early 2021), Corsair MP510 1.92TB NVMe SSD (Mid 2020), beQuiet Pure Wings 2 140mm x2 & 120mm x1 (Mid 2023),

Link to comment
Share on other sites

Link to post
Share on other sites

On 8/7/2016 at 11:31 AM, AluminiumTech said:

Oops. Too late. It's already messed up. I cloned the GitHub repo and tried to run it. But it gave me loads of errors :(.

 

I'm using VS 2015 Update 3. All the C++ parts enabled.

 

I decided to work on a C# version of mine from scratch and I've got some errors. I can get most of the stuff you asked for but maybe not the PSU.

Hey @AluminiumTech, can you post some of the errors you're getting? I want to fix it so everyone can use it.

EDIT: I think I know why it spit out a bunch of errors at you. I tried to add an icon to the project a couple days ago, and I just found out that Visual Studio added like 6 more include files that I didn't need. So I got rid of those. Even if you aren't going to use it, could you do me a favor and download/run the code? Thanks!

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×