Ho bisogno di registrare le informazioni sulla quantità di RAM che l'utente ha. Il mio primo approccio è stato quello di utilizzare GlobalMemoryStatusEx, ma questo mi dà solo la quantità di memoria disponibile per Windows, non quanto è installato. Ho trovato questa funzione GetPhysicallyInstalledSystemMemory ma è solo Vista e successive. Ho bisogno che funzioni su XP. C'è un modo abbastanza semplice di interrogare le informazioni SMBIOS che GetPhysicallyInstalledSystemMemory stava usando o c'è un valore di registro da qualche parte che posso trovare questo fuori.Come posso sapere quanta memoria è installata fisicamente in Windows?
risposta
EDIT: mi piacerebbe utilizzare risposta steelbytes', ma se non è possibile utilizzare WMI Per qualche ragione, si può fare questo :
Non credo che le versioni di Windows precedenti a Vista tengano traccia di queste informazioni: dovresti eseguire alcune enumerazioni BIOS o scheda madre specifiche del sistema per trovare il vero valore prima di Vista. La soluzione migliore è chiamare la nuova API, GetPhysicallyInstalledSystemMemory
, e eseguire il failover su GlobalMemoryStatusEx
per i sistemi XP.
Uno dei valori restituiti da GlobalMemoryStatusEx è ullTotalPhys, che sembra essere quello che stai cercando.
Le cose come ram utilizzate per la memoria video non sono in là, ma dubito che ci sia un modo per arrivarci.
penso WMI può dare queste informazioni ...
http://briandesmond.com/blog/getting-total-installed-memory-with-wmi/
Oooh - vorrei aver pensato a questo. +1. –
non sono sicuro che sia xp friendly o no ... ho pensato di pubblicarlo come idea :-) – SteelBytes
Lo è. Dovrebbe funzionare per le macchine XP. –
Si dovrebbe dare un'occhiata alla classe Win32_ComputerSystem (WMI) e alla proprietà TotalPhysicalMemory. Ci sono modi per accedere a queste informazioni tramite .Net tramite lo spazio dei nomi System.Management per il codice gestito (io uso C#, quindi non ho provato a utilizzare Visual Studio per lo sviluppo C++). È anche possibile creare uno script per eseguire direttamente WMI e fare in modo che il programma C++ chiami lo script.
AGGIORNAMENTO: è inoltre possibile esaminare la classe Win32_PhysicalMemory (consultare la proprietà Capacità). Ciò allevierà letture imprecise a causa del BIOS utilizzando alcuni della RAM ecc
UPDATE 2:
Ho provato questo in C# (3.5) e Windows XP (SP 2) e funziona. Sono sicuro che puoi fare qualcosa di simile con le stesse classi WMI in C++ (almeno attraverso Visual Studio). Funziona senza problemi, quindi non è un problema Vista o maggiore. Non sono sicuro se questo è esattamente quello che stai cercando, ma questo codice restituirà la capacità di memoria fisica totale del sistema (non quanto è gratuito). Spero che questo sia ciò che intendevi. Comunque qui è un codice di esempio che individua ogni bastone di RAM e visualizza alcune informazioni su ciascuno di essi (compresa la capacità) e poi il totale in fondo:
using System;
using System.Collections.Generic;
using System.Management;
using System.Text;
namespace WmiTest
{
public class RamCounter
{
private List<RamStick> _ramSticks;
private int _totalRam;
private StringBuilder _stringRepresentation;
public RamCounter()
{
_ramSticks = new List<RamStick>();
_totalRam = 0;
_stringRepresentation = new StringBuilder();
}
public void GetRamSticks()
{
_ramSticks.Clear();
_totalRam = 0;
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMemory");
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject mo in queryCollection)
{
_ramSticks.Add(
new RamStick(Convert.ToUInt64(mo.GetPropertyValue("Capacity")),
mo.GetPropertyValue("DeviceLocator").ToString(),
mo.GetPropertyValue("Description").ToString(),
Convert.ToUInt32(mo.GetPropertyValue("FormFactor")),
Convert.ToUInt32(mo.GetPropertyValue("Speed"))));
}
}
public override string ToString()
{
_stringRepresentation.Capacity = 0;
foreach (RamStick rs in _ramSticks)
{
_stringRepresentation.Append(rs.ToString());
_totalRam += rs.CapacityInMB;
}
_stringRepresentation.Append("Total RAM(MB): " + _totalRam);
return _stringRepresentation.ToString();
}
}
public class RamStick
{
private UInt64 _capacity;
private UInt32 _formFactor;
public RamStick(UInt64 capacity, string location, string description, UInt32 formFactor, UInt32 speed)
{
_capacity = capacity;
Location = location;
Description = description;
_formFactor = formFactor;
Speed = speed;
}
public int CapacityInMB
{
get { return Convert.ToInt32(_capacity/(1024 * 1024)); }
}
public string Location
{
get;
private set;
}
public string Description
{
get;
private set;
}
public string GetFormFactor()
{
string formFactor = string.Empty;
switch (_formFactor)
{
case 1:
formFactor = "Other";
break;
case 2:
formFactor = "SIP";
break;
case 3:
formFactor = "DIP";
break;
case 4:
formFactor = "ZIP";
break;
case 5:
formFactor = "SOJ";
break;
case 6:
formFactor = "Proprietary";
break;
case 7:
formFactor = "SIMM";
break;
case 8:
formFactor = "DIMM";
break;
case 9:
formFactor = "TSOP";
break;
case 10:
formFactor = "PGA";
break;
case 11:
formFactor = "RIMM";
break;
case 12:
formFactor = "SODIMM";
break;
case 13:
formFactor = "SRIMM";
break;
case 14:
formFactor = "SMD";
break;
case 15:
formFactor = "SSMP";
break;
case 16:
formFactor = "QFP";
break;
case 17:
formFactor = "TQFP";
break;
case 18:
formFactor = "SOIC";
break;
case 19:
formFactor = "LCC";
break;
case 20:
formFactor = "PLCC";
break;
case 21:
formFactor = "BGA";
break;
case 22:
formFactor = "FPBGA";
break;
case 23:
formFactor = "LGA";
break;
default:
formFactor = "Unknown";
break;
}
return formFactor;
}
public UInt32 Speed
{
get;
private set;
}
public override string ToString()
{
return string.Format("Description:{1}{0}"
+ "Location:{2}{0}"
+ "Form Factor:{3}{0}"
+ "Speed:{4}{0}"
+ "Capacity(MB):{5}{0}{0}",
Environment.NewLine,
Description,
Location,
GetFormFactor(),
Speed,
CapacityInMB);
}
}
}
Per utilizzare il codice:
private void btnRam_Click(object sender, EventArgs e)
{
RamCounter rc = new RamCounter();
rc.GetRamSticks();
MessageBox.Show(rc.ToString());
}
Esempio di output dalla mia macchina:
Description: Physical Memory
Location: J6H1
Format Factor: DIMM
Speed: 667
Capacity(MB): 1024
Description: Physical Memory
Location: J6H2
Format Factor: DIMM
Speed: 667
Capacity(MB): 1024
Description: Physical Memory
Location: J6J1
Format Factor: DIMM
Speed: 667
Capacity(MB): 1024
Total RAM(MB): 3072
Ha gli stessi problemi della chiamata 'GlobalMemoryStatusEx'. –
Molte proprietà dichiarano se non sono supportate in una particolare versione di Windows (o prima di una particolare versione).Nessuna di queste proprietà che ho menzionato dichiara che sono solo Vista o superiore. Questo non vuol dire che siano supportati in XP però (non ho provato me stesso). –
Sospetto che le chiamate all'interno di Win32_ComputerSystem si riducano semplicemente alle chiamate GlobalMemoryStatusEx. Ma l'enumerazione Win32_PhysicalMemory dovrebbe funzionare su tutti i sistemi. +1 per l'aggiornamento. –
Perché questa risposta è in aumento? Riposiziona la domanda in parole diverse. –