2009-10-12 12 views
10

Używam funkcji GlobalMemoryStatusEx do pobierania informacji o pamięci, ale ta funkcja nie działa poprawnie. Zwraca 0 dla wszystkich właściwości. Nie sądzę, że ta funkcja działa w moim środowisku Windows 7.Jak mogę uzyskać całkowitą pamięć fizyczną w języku C#?

[StructLayout(LayoutKind.Sequential)] 
    internal struct MEMORYSTATUSEX 
    { 
     internal uint dwLength; 
     internal uint dwMemoryLoad; 
     internal ulong ullTotalPhys; 
     internal ulong ullAvailPhys; 
     internal ulong ullTotalPageFile; 
     internal ulong ullAvailPageFile; 
     internal ulong ullTotalVirtual; 
     internal ulong ullAvailVirtual; 
     internal ulong ullAvailExtendedVirtual; 
    } 
    [return: MarshalAs(UnmanagedType.Bool)] 
    [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    internal static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer); 

    private void btnGlobalMemoryStatusEX_Click(object sender, EventArgs e) 
    { 
     MEMORYSTATUSEX statEX = new MEMORYSTATUSEX(); 
     GlobalMemoryStatusEx(ref statEX); 

     double d = (double)statEX.ullTotalPhys; 
    } 

Czy ktoś może mi powiedzieć, gdzie popełniłem błąd przy użyciu niewłaściwego kodu?

+0

Czy próbowałeś WMI? Jest wolniejszy, ale musi działać na każdym systemie operacyjnym. – Restuta

Odpowiedz

9

znajdę mój błąd z: http://www.pinvoke.net/default.aspx/kernel32/GlobalMemoryStatusEx.html

Zmieniłem

internal static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer); 

Aby

static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer); 

i zmienił

GlobalMemoryStatusEx(ref statEX); 

Aby

GlobalMemoryStatusEx(statEX); 

działać poprawnie. Zbiorniki

+0

Skąd wziąłeś tę pracę Uruchomiłem ten kod w VS uruchomiłem jako Admin na koncie Admin., kiedy zadzwonię do GlobalMemoryStatusEX () uzyskać wyjątek mówiąc:.. System.AccessViolationException hresult = 0x80004003 Message = próba odczytu lub zapisu pamięci chronionej jest to często wskazanie, że inne pamięci jest uszkodzony – Alvaromon

1

można użyć tej szablony:

long memory = Process.GetCurrentProcess().PeakVirtualMemorySize64; 

a inny właściwości o nazwach szczytowa * 64

+0

Wierzę, że OP pyta o pamięć fizyczną, więc proces nie jest aż tak użyteczny. –

5

Jak o:

My.Computer.Info.TotalPhysicalMemory 
My.Computer.Info.AvailablePhysicalMemory 
+0

czołgi, ale piszę w C# .Net. –

+0

@ Amir: Dodaj odniesienie do pliku Microsoft.VisualBasic.dll. – dalle

+0

@Amir, przepraszam, zawsze zapominam, że My-Namespace nie istnieje "natywnie" w C#. :( – Bobby

4

Jeśli C# można:

referencyjne Microsoft.VisualBasic montaż. Następnie zaimportuj przestrzeń nazw Microsoft.VisualBasic.Devices.
I wreszcie użyj ComputerInfo, aby uzyskać całkowitą pamięć fizyczną.

int bytesPerMebibyte = (1 << 20); // http://physics.nist.gov/cuu/Units/binary.html 
ComputerInfo myCompInfo = new ComputerInfo(); 
string physicalMemory = "Physical Memory: " 
    + (myCompInfo.TotalPhysicalMemory/bytesPerMebibyte) + " MB"; 
0

Zapomniałeś ustawić statEX.dwLength przed dzwonieniem pod numer GlobalMemoryStatusEx.

MEMORYSTATUSEX statEX = new MEMORYSTATUSEX(); 
statEX.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX)); 
GlobalMemoryStatusEx(ref statEX); 
+0

ustawić tego, ale to nie działa, ani –

+1

OK, powinniśmy ustawić to, ale głównym problemem jest słowo kluczowe "ref". ould usunąć go z delaretion i wykorzystania funkcji. –

+0

@dalle: fyi, ponieważ funkcja MEMORYSTATUSEX jest niezarządzana, możesz użyć sizeof (MEMORYSTATUSEX) bezpośrednio, bez wywoływania pomocnika interop (Marshal). –

Powiązane problemy