2010-03-25 2 views
6

J'ai besoin d'enregistrer des informations sur la quantité de RAM de l'utilisateur. Ma première approche était d'utiliser GlobalMemoryStatusEx mais cela ne me donne que la quantité de mémoire disponible pour Windows, et non pas combien est installé. J'ai trouvé cette fonction GetPhysicallyInstalledSystemMemory mais c'est seulement Vista et plus tard. J'ai besoin de ça pour travailler sur XP. Existe-t-il un moyen assez simple d'interroger les informations SMBIOS que GetPhysicallyInstalledSystemMemory utilisait ou y a-t-il une valeur de registre quelque part que je puisse trouver?Comment puis-je connaître la quantité de mémoire installée physiquement dans Windows?

Répondre

2

EDIT: J'utilise la réponse de steelbytes, mais si vous ne pouvez pas utiliser WMI Pour une raison quelconque, vous pouvez le faire :

Je ne crois pas que les versions de Windows antérieures à Vista suivent cette information - vous devriez faire une énumération spécifique du BIOS ou de la carte mère du système pour trouver la vraie valeur avant Vista. Le mieux est d'appeler la nouvelle API, GetPhysicallyInstalledSystemMemory, et de basculer vers GlobalMemoryStatusEx pour les systèmes XP.

1

L'une des valeurs renvoyées par GlobalMemoryStatusEx est ullTotalPhys, ce qui semble être ce que vous recherchez.

Des choses comme le bélier utilisé pour la mémoire vidéo ne sont pas là, mais je doute qu'il y ait un moyen d'y arriver du tout.

+0

Pourquoi cette réponse est-elle mise à la hausse? Cela ne fait que répéter la question dans des mots différents. –

4

Vous devriez jeter un coup d'œil à la classe Win32_ComputerSystem (WMI) et à la propriété TotalPhysicalMemory. Il existe des moyens d'accéder à ces informations via .Net via l'espace de noms System.Management pour le code managé (j'utilise C#, donc je n'ai pas essayé d'utiliser Visual Studio pour le développement C++ moi-même). Vous pouvez également créer un script pour exécuter WMI directement et demander à votre programme C++ d'appeler le script. MISE À JOUR: Vous pouvez également consulter la classe Win32_PhysicalMemory (consultez la propriété Capacity). Cela permettra d'atténuer les lectures inexactes en raison du BIOS en utilisant une partie de la RAM, etc.

MISE À JOUR 2:

J'ai essayé cela en C# (3.5) et Windows XP (SP 2) et cela fonctionne. Je suis sûr que vous pouvez faire quelque chose de similaire avec les mêmes classes WMI en C++ (au moins via Visual Studio). Cela ne pose aucun problème, donc ce n'est pas un Vista ou un problème plus important. Je ne suis pas sûr que ce soit exactement ce que vous recherchez, mais ce code retournera la capacité de mémoire physique totale du système (pas combien est libre). J'espère que c'est ce que vous vouliez dire. est en tout cas ici quelques exemples de code qui permet de localiser chaque bâton de RAM et affiche quelques informations sur chacun d'eux (y compris la capacité), puis le total au bas:

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); 
     } 
    } 
} 

Pour utiliser le code:

private void btnRam_Click(object sender, EventArgs e) 
{ 
    RamCounter rc = new RamCounter(); 
    rc.GetRamSticks(); 
    MessageBox.Show(rc.ToString()); 
} 

Exemple de sortie de ma machine:

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 
+0

Cela pose les mêmes problèmes que l'appel 'GlobalMemoryStatusEx'. –

+0

La plupart des propriétés indiquent si elles ne sont pas prises en charge dans une version particulière de Windows (ou avant une version particulière).Aucune de ces propriétés que j'ai mentionné ne mentionne qu'elles sont seulement Vista ou plus. Cela ne veut pas dire qu'ils sont pris en charge par XP (je ne me suis pas essayé). –

+0

Je soupçonne que les appels dans Win32_ComputerSystem se résument simplement aux appels GlobalMemoryStatusEx. Mais l'énumération Win32_PhysicalMemory devrait fonctionner sur tous les systèmes. +1 pour la mise à jour –

Questions connexes