C# - Memória információ lekérdező komponens

forráskód letöltése
Sok esetben nem árt, ha tisztában vagyunk vele, hogy mennyi az összes, és mennyi a szabad memória terület az adott gépen. Most készítünk egy olyan komponenst, mely már fejlesztési időben tájékoztat a memóriával kapcsolatos paraméterekről.
A példaprogramból azt is megtudhatjuk, hogy miként használhatunk fel egy külső Win API függvényt, melynek paraméterként egy struktúrát kell átadni.
Első lépésként a komponenst kell elkészítenünk, mely a MemStat alkönyvtárban kapott helyet. Vegyük most sorra, hogy milyen lépésekkel lehet létrehozni egy ilyen komponenst.
Válasszuk a File – New – Project menüpontot, majd a Visual C# Projects csoport Windows Conrol Library elemét. A létrejött új project-ben válaszuk a Project – New Component menüpontot.
Ezzel kaptunk egy új, üres komponenst.
A memória információk lekérdezéséhez a GlobalMemoryStatus Win API függvényt használnánk, ezért ezt külsőként deklarálnunk kell. Egy DllImport attribútumban megadhatjuk, hogy melyik rendszer DLL tartalmazza a használni kívánt függvényt, majd ezt követően deklarálhatjuk azt külsőként (extern).
  [DllImport("kernel32")]
  private static extern void GlobalMemoryStatus(ref MEMORYSTATUS buf);
Mivel e függvény azonban egy struktúrát vár paraméterként, így ezt is létre kell hoznunk, hogy használhassuk.
  [StructLayout(LayoutKind.Sequential)]   
  public struct MEMORYSTATUS
  {
    public  uint dwLength;
    public  uint dwMemoryLoad;
    public  uint dwTotalPhys;
    public  uint dwAvailPhys;
    public  uint dwTotalPageFile;
    public  uint dwAvailPageFile;
    public  uint dwTotalVirtual;
    public  uint dwAvailVirtual;
  }
Ezt követően deklarálunk egy globális változót e struktúrából.
    private MEMORYSTATUS ms = new MEMORYSTATUS();        
Ennek a változónak a komponens konstruktorában adunk először értéket, méghozzá úgy, hogy meghívjuk a Refresh saját függvényünket.
    public MemStatComponent()
    {
      InitializeComponent();
      Refresh();
    }
Ez a Refresh függvény publikus, így ha a komponenst felhasználjuk a programunkban, akkor a Refresh meghívása után biztosak lehetünk benne, hogy az aktuális adatokat érhetjük el a komponens property-jeiből.
    public void Refresh()
    {
      GlobalMemoryStatus(ref ms);
    }
Most már csak létre kell hozni ezeket a property-ket, melyeken keresztül elérhetőek a kívánt adatok. A komponens property-jeinek létrehozását úgy végezzük el, hogy a MEMORYSTATUS struktúra minden fontos eleméhez tartozzon egy-egy. Ezeket a property-ket a Memory kategóriába soroljuk, így a Properties ablakban ezek együtt, egy helyen lesznek láthatók.
    [
    Category("Memory"),
    Description("Total Physical Memory")
    ]
    public uint TotalPhys
    {
Mivel a property-hez csak egy get metódust hozunk létre, így ezzel annak értéke csak olvasható lesz. Nyilvánvaló, hogy nem is lenne értelme ez esetben írható property-ket létrehoznunk. Ezért a Properties ablakban megjelenő property-k értéke ugyan látható lesz, de azokat nem tudjuk módosítani.
      get
      {
        return ms.dwTotalPhys;
      }
    }
A MEMORYSTATUS struktúra többi eleméhez hasonló módszerrel hozzuk létre a property-ket.
A komponens elkészülte után fordítsuk le a DLL-t, majd vegyük fel a ToolBox-ra azt a következőképpen: válasszuk ki azt a palettát, amelyre szeretnénk helyezni, vagy készítsünk egy újat (ToolBox – jobb gomb – Add tab). Ezek után kattintsuk a ToolBox-on jobb gombbal és válasszuk a Customize ToolBox menüpontot. A megjelenő ablakban a .NET Framework Components lapon a Browse gomb lenyomása után keressük elő a MemStat.dll-t. A listában ekkor megjelenik a MemStatComponent. Az előtte lévő CheckBox-ot jelöljük meg, majd OK gomb.
Ezek után már használhatjuk a komponenst. A teszt alkalmazás a TestApp alkönyvtárban található. A komponens feltétele után a property-ken keresztül rögtön láthatóvá válnak az aktuális értékek. Ha a program futása során szeretnénk kiolvasni valamely értéket, akkor előtte ne felejtsük el meghívni a Refresh függvényt, hogy mindig az aktuális értéket kapjuk vissza.
    private void timer1_Tick(object sender, System.EventArgs e)
    {
      memStatComponent1.Refresh();
      label1.Text = memStatComponent1.AvailPhys.ToString();
    }