The current structure of my classes goes a little bit like this: PC.Processor.Architecture[0] = The Architecture of the first processor (assuming a multi-processor system).
How I ideally want it is more like this: PC.Processor[0].Architecture, because it's a bit more self explanatory this way.
Is there a fairly efficient way of doing this with what I have? Bear in mind there are like, over 9000 properties in each of the classes Processor, Motherboard, Memory etc and WMI calls are not CPU-cheap to run.
Here are the important snippets for my classes
class PC
{
public Processor Processor;
public Motherboard Motherboard;
// Constructor
public PC()
{
Processor = new Processor();
Motherboard = new Motherboard();
}
// Method to get all info sequentially
public void GetAllInfo()
{
Processor.GetInfo();
Motherboard.GetInfo();
}
}
class Processor
{
public string[] Architecture;
public string[] Availability;
public UInt16[] Cores;
public void GetInfo()
{
// Get WMI Information from custom process
// Returns as an array of ManagementObjects for each matched device (which is a bit like an array of dictionaries)
ManagementObject[] WMIData = DataRetriever.GetWMIData("Win32_Processor");
try
{
for (int i = 1; i < WMIData.Length; i++)
{
this.Architecture[i] = (string)WMIData[i]["Architecture"];
this.Availability[i] = (string)WMIData[i]["Availability"];
this.Cores[i] = (UInt16)WMIData[i]["NumberOfCores"];
}
}
catch (NullReferenceException e)
{
// To be implemented
}
}
}
FURTHERMORE
There may be more than one WMI search query per class. For example, HardDrive needs to make use of both Win32_PhysicalMedia and ATAPI_SmartData (or whatever the class actually is.)
Thanks to everyone who's responded. I've come up with a reasonably elegant solution that suits my needs.
PC Class Example:
public class PC
{
public List<Processor> Processor;
// Constructor
public PC()
{
this.Processor = new List<Processor>();
}
// Method to get all info sequentially
public void GetAllInfo()
{
// These temporary stores fetch WMI data as ManagementObjects
// Most cases will only need one WMI class.
ManagementObject[] WMIDataTemp1;
ManagementObject[] WMIDataTemp2;
WMIDataTemp1 = DataRetriever.GetWMIData("Win32_Processor");
foreach (ManagementObject Object in WMIDataTemp1)
{
this.Processor.Add(new Processor(Object));
}
}
public void RefreshAll()
{
// Delete the lists and start again
// Another option would be to foreach through the list elements and initialise each object again.
this.Processor.Clear();
GetAllInfo();
}
public void RefreshVolatileData()
{
// Extra function that will do some cool stuff later.
}
}
Processor Class Example:
public class Processor
{
// Define properties
public string Architecture = "N/A";
public string Availability = "N/A";
public UInt32 CacheL2 = 0;
public UInt32 CacheL3 = 0;
// Overloaded constructor method
// The one with no arguments does nothing to initialise the class
// The one with the ManagementObject argument will call GetInfo to arrange the held data into the properties above
public Processor() { }
public Processor(ManagementObject wmiProcessor)
{
this.GetInfo(wmiProcessor);
}
// The main information handler for the classes.
// This splits out the data in the ManagementObject into the class's own properties
public void GetInfo(ManagementObject wmiProcessor)
{
// If anything fails, the try loop will just end without making a fuss
// Because of the default values, N/A will be displayed everywhere if something fails here.
try
{
this.Architecture = (string)wmiProcessor["Architecture"];
this.Availability = (string)wmiProcessor["Availability"];
this.CacheL2 = (UInt32)wmiProcessor["L2CacheSize"];
this.CacheL3 = (UInt32)wmiProcessor["L3CacheSize"];
}
catch (Exception e)
{
}
}
}
Usage example:
public PC Computer = new PC();
Computer.GetAllInfo();
textbox1.Text = Computer.Processor[0].Architecture
In the event a device needs to query more than one WMI class, each additional class can be listed as an extra parameter in the device constructor and GetInfo() method.