Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions Hardware.Info/Components/Memory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,36 @@ public enum FormFactor
LGA = 23
}

public enum MemoryType
{
/// <summary>
/// Represents an unknown or unspecified form factor.
/// </summary>
UNKNOWN,

DRAM,
EDRAM,
VRAM,
SRAM,
RAM,
SDRAM,
SGRAM,
RDRAM,
FBD2,
DDR,
DDR2,
DDR3,
DDR4,
DDR5,
HBM,
HBM2,
LPDDR,
LPDDR2,
LPDDR3,
LPDDR4,
LPDDR5,
}

/// <summary>
/// WMI class: Win32_PhysicalMemory
/// </summary>
Expand Down Expand Up @@ -179,6 +209,16 @@ public class Memory
/// Speed of the physical memory in nanoseconds.
/// </summary>
public UInt32 Speed { get; set; }

/// <summary>
/// Type of memory
/// </summary>
public MemoryType Type { get; set; }

/// <summary>
/// Data width of the physical memory—in bits
/// </summary>
public ushort DataWidth { get; set; }

/// <summary>
/// Write all property values to a string
Expand All @@ -188,6 +228,8 @@ public override string ToString()
{
return
"BankLabel: " + BankLabel + Environment.NewLine +
"Type: " + Type + Environment.NewLine +
"Width: " + DataWidth + Environment.NewLine +
"Capacity: " + Capacity + Environment.NewLine +
"FormFactor: " + FormFactor + Environment.NewLine +
"Manufacturer: " + Manufacturer + Environment.NewLine +
Expand Down
127 changes: 86 additions & 41 deletions Hardware.Info/Linux/HardwareInfoRetrieval.cs
Original file line number Diff line number Diff line change
Expand Up @@ -679,65 +679,110 @@ public List<Memory> GetMemoryList()
{
List<Memory> memoryList = new List<Memory>();

string processOutput = ReadProcessOutput("lshw", "-short -C memory");
string processOutput = ReadProcessOutput("lshw", "-C memory");

string[] lines = processOutput.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
var cacheInfoIndex = processOutput.IndexOf("*-cache", StringComparison.Ordinal);
if (cacheInfoIndex != -1)
{
processOutput = processOutput.Remove(cacheInfoIndex);
}

string[] formFactorNames = Enum.GetNames(typeof(FormFactor));
string[] sections = processOutput.Split(new[] { "*-bank:" }, StringSplitOptions.RemoveEmptyEntries);

foreach (string line in lines)
foreach (string section in sections)
{
string[] split = line.Split(new[] { "memory" }, StringSplitOptions.RemoveEmptyEntries);

if (split.Length > 1)
if (section.Contains("size:") && (section.Contains("DIMM") || section.Contains("DDR")))
{
string relevant = split[1].Trim();

if (relevant.Contains("DDR") || relevant.Contains("DIMM") || relevant.Contains("System"))
Memory ram = new Memory();

string[] lines = section.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

foreach (string line in lines)
{
Memory ram = new Memory();

string[] parts = relevant.Split(' ');

foreach (string part in parts)
string trimmedLine = line.Trim();

if (trimmedLine.StartsWith("size:"))
{
Regex sizeRegex = new Regex("^([0-9]+)(K|M|G|T)iB");

if (formFactorNames.Any(name => name == part))
string sizePart = trimmedLine.Substring(5).Trim();
Regex sizeRegex = new Regex(@"^([0-9]+)(K|M|G|T)iB");
Match match = sizeRegex.Match(sizePart);

if (match.Success && match.Groups.Count > 2)
{
if (Enum.TryParse(part, out FormFactor formFactor))
ram.FormFactor = formFactor;
if (ulong.TryParse(match.Groups[1].Value, out ulong number))
{
string exponent = match.Groups[2].Value;
ram.Capacity = exponent switch
{
"T" => number * 1024uL * 1024uL * 1024uL * 1024uL,
"G" => number * 1024uL * 1024uL * 1024uL,
"M" => number * 1024uL * 1024uL,
"K" => number * 1024uL,
_ => number,
};
}
}
else if (new Regex("^[0-9]+$").IsMatch(part))
}
else if (trimmedLine.StartsWith("clock:"))
{
string clockPart = trimmedLine.Substring(6).Trim();
Regex clockRegex = new Regex(@"([0-9]+)MHz");
Match match = clockRegex.Match(clockPart);

if (match.Success)
{
if (uint.TryParse(part, out uint speed))
if (uint.TryParse(match.Groups[1].Value, out uint speed))
{
ram.Speed = speed;
}
}
else if (sizeRegex.IsMatch(part))
}
else if (trimmedLine.StartsWith("description:"))
{
string description = trimmedLine.Substring(12).Trim();
var descriptionParts = description.Split(' ');

foreach (var descriptionPart in descriptionParts)
{
Match match = sizeRegex.Match(part);

if (match.Groups.Count > 2)
if (ram.Type != MemoryType.UNKNOWN && ram.FormFactor != FormFactor.UNKNOWN) break;
if (Enum.TryParse(descriptionPart, out MemoryType memoryType))
{
if (ulong.TryParse(match.Groups[1].Value, out ulong number))
{
string exponent = match.Groups[2].Value;

ram.Capacity = exponent switch
{
"T" => number * 1024uL * 1024uL * 1024uL * 1024uL,
"G" => number * 1024uL * 1024uL * 1024uL,
"M" => number * 1024uL * 1024uL,
"K" => number * 1024uL,
_ => number,
};
}
ram.Type = memoryType;
}
else if (Enum.TryParse(descriptionPart, out FormFactor formFactor))
{
ram.FormFactor = formFactor;
}
}
}

memoryList.Add(ram);
else if (trimmedLine.StartsWith("width:"))
{
string widthPart = trimmedLine.Substring(6).Trim();
Regex widthRegex = new Regex(@"([0-9]+)");
Match match = widthRegex.Match(widthPart);

if (match.Success)
{
if (uint.TryParse(match.Groups[1].Value, out var width))
ram.DataWidth = (ushort) width;
}
}
else if (trimmedLine.StartsWith("product:"))
{
ram.PartNumber = trimmedLine.Substring(8).Trim();
}
else if (trimmedLine.StartsWith("vendor:"))
{
ram.Manufacturer = trimmedLine.Substring(7).Trim();
}
else if (trimmedLine.StartsWith("serial:"))
{
ram.SerialNumber = trimmedLine.Substring(7).Trim();
}
}

memoryList.Add(ram);
}
}

Expand Down
2 changes: 2 additions & 0 deletions Hardware.Info/Mac/HardwareInfoRetrieval.cs
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,8 @@ public List<Memory> GetMemoryList()
{
if (Enum.TryParse(split[1], out FormFactor formFactor))
memory.FormFactor = formFactor;
if (Enum.TryParse(split[1], out MemoryType memoryType))
memory.Type = memoryType;
}
}

Expand Down
34 changes: 31 additions & 3 deletions Hardware.Info/Windows/HardwareInfoRetrieval.cs
Original file line number Diff line number Diff line change
Expand Up @@ -518,8 +518,8 @@ public List<Memory> GetMemoryList()
{
List<Memory> memoryList = new List<Memory>();

string queryString = _os.Version.Major >= 10 ? "SELECT BankLabel, Capacity, FormFactor, Manufacturer, MaxVoltage, MinVoltage, PartNumber, SerialNumber, Speed FROM Win32_PhysicalMemory"
: "SELECT BankLabel, Capacity, FormFactor, Manufacturer, PartNumber, SerialNumber, Speed FROM Win32_PhysicalMemory";
string queryString = _os.Version.Major >= 10 ? "SELECT BankLabel, Capacity, FormFactor, Manufacturer, MaxVoltage, MinVoltage, PartNumber, SerialNumber, Speed, DataWidth, SMBIOSMemoryType FROM Win32_PhysicalMemory"
: "SELECT BankLabel, Capacity, FormFactor, Manufacturer, PartNumber, SerialNumber, Speed, DataWidth FROM Win32_PhysicalMemory";
using ManagementObjectSearcher mos = new ManagementObjectSearcher(_managementScope, queryString, _enumerationOptions);

foreach (ManagementBaseObject mo in mos.Get())
Expand All @@ -532,13 +532,41 @@ public List<Memory> GetMemoryList()
Manufacturer = GetPropertyString(mo["Manufacturer"]),
PartNumber = GetPropertyString(mo["PartNumber"]),
SerialNumber = GetPropertyString(mo["SerialNumber"]),
Speed = GetPropertyValue<uint>(mo["Speed"])
Speed = GetPropertyValue<uint>(mo["Speed"]),
DataWidth = GetPropertyValue<ushort>(mo["DataWidth"])
};

if (_os.Version.Major >= 10)
{
memory.MaxVoltage = GetPropertyValue<uint>(mo["MaxVoltage"]);
memory.MinVoltage = GetPropertyValue<uint>(mo["MinVoltage"]);

memory.Type = GetPropertyValue<uint>(mo["SMBIOSMemoryType"]) switch
{
0x03 => MemoryType.DRAM,
0x04 => MemoryType.EDRAM,
0x05 => MemoryType.VRAM,
0x06 => MemoryType.SRAM,
0x07 => MemoryType.RAM,
0x0F => MemoryType.SDRAM,
0x10 => MemoryType.SGRAM,
0x11 => MemoryType.RDRAM,
0x12 => MemoryType.DDR,
0x13 => MemoryType.DDR2,
0x14 => MemoryType.DDR2, // DDR2 FB-DIMM
0x18 => MemoryType.DDR3,
0x19 => MemoryType.FBD2,
0x1A => MemoryType.DDR4,
0x1B => MemoryType.LPDDR,
0x1C => MemoryType.LPDDR2,
0x1D => MemoryType.LPDDR3,
0x1E => MemoryType.LPDDR4,
0x20 => MemoryType.HBM,
0x21 => MemoryType.HBM2,
0x22 => MemoryType.DDR5,
0x23 => MemoryType.LPDDR5,
_ => MemoryType.UNKNOWN
};
}

memoryList.Add(memory);
Expand Down