C# - Állomány kiterjesztéshez tartozó alkalmazások és ikonok meghatározása

forráskód letöltése
A Windows rendszerben számtalan állomány-kiterjesztés létezik, melyek többségéhez egy alkalmazás, és egy ikon is rendelhető. Ennek köszönhető, hogy ha egy állománynév megjelenik az Intézőben, akkor mellette találunk egy képet is. Cikkünkben elkészítünk egy alkalmazást, mely kigyűjti a rendszer olyan kiterjesztéseit, melyhez egy kép is kapcsolódik, és megjeleníti a kapcsolódó alkalmazás nevét és a képet egy ListBox kontrolban.
Az alkalmazás a Windows Rendszerleíró adatbázisában keresi meg a szükséges adatokat. Ebben a HKEY_CLASSES_ROOT főkulcs alatt megtalálható az összes ismert állomány kiterjesztés és a hozzájuk tartozó adatok. Nincs más teendőnk tehát, mint egy olyan alkalmazást készíteni, mely végignézi ezt a listát és kigyűjti a megnevezéseket, majd megjeleníti az állományokhoz tartozó ikonokat.
Az alkalmazásban a ListBox kontrol egy eleme a kigyűjtött típusok ikonját, valamint a kapcsolódó alkalmazás nevét tartalmazza. Hogy ezt képes legyen elvégezni, két eseményére kezelőmetódust kell deklarálni. A MeasureItem esemény kezelőjében megadjuk, hogy milyen magas legyen egy-egy elem a listában. A DrawItem esemény kezelőjében adjuk meg a kirajzolás kódját.
listBox1.DrawItem += new DrawItemEventHandler(listBox1_DrawItem);
listBox1.MeasureItem += new MeasureItemEventHandler(listBox1_MeasureItem);
A nyomógomb megnyomásakor lefuttatjuk a CollectRegData metódust, melyben kigyűjtjük a registry megfelelő adatait, és előállítjuk a megjelenítéshez szükséges információkat. Az információ két adatból áll: az első adat annak az állománynak az elérési útvonala, melyben az adott alkalmazáshoz kapcsolódó ikon megtalálható, a másik adat az ikon állományon belüli sorszáma, mivel egy állomány több ikont is tartalmazhat.
A két adatot az ExtractIcon API metódusban használjuk fel.
[DllImport("shell32.dll")]
private static extern IntPtr ExtractIcon(IntPtr hInst,string lpszExeFileName,int nIconIndex);
A metódus első paramétere az alkalmazás process-ének azonosítója, a második paraméter tartalmazza az ikont tartalmazó állomány elérési útvonalát, míg a harmadik paraméter a sorszámot rejti.
A CollectRegData metódusban kigyűjtjük a kiterjesztéseket, melyek egy „.” karakterrel kezdődnek, majd lekérdezzük a kiterjesztés nevű kulcs értékét, mely egy újabb kulcsra mutat a főkulcson belül.
Az .exe kiterjesztés esetén ez a kulcsnév az EXEFILE lesz. A kulcsnévnek minden esetben van egy DefaultIcon nevű alkulcsa, mely az ikont rejtő állomány elérési útvonalát és egy számot tartalmaz, mindezt egy karakterláncban.
A metódusunkban szét kell választanunk a két adatot, és ezeket egy karakterlánc tömbben elhelyezve adjuk át egy ArrayList listának, melyből majd lekérdezzük őket a rajzolómetódusban.
A rajzolómetódusban az adott indexű elemhez kapcsolódó adatpárt lekérdezzük, és meghívjuk a fenti API metódust.
string[] datas = datas = (string[])regdata[e.Index];
IntPtr ptr = ExtractIcon(Process.GetCurrentProcess().Handle,datas[0],Convert.ToInt32(datas[1]));
A függvény egy mutatót ad vissza az ikonra, melynek felhasználásával már létrehozhatunk egy Icon objektumot.
Bitmap bmp = Bitmap.FromHicon(ptr);
Icon icon = Icon.FromHandle(bmp.GetHicon());
Meg kell határoznunk a megjelenítés pozícióit, majd a Graphics osztály DrawIcon metódusával kirajzoljuk az ikont.
int x = e.Bounds.X + 5;
int y = e.Bounds.Y + (e.Bounds.Height/2-icon.Height/2);
e.Graphics.DrawIcon(icon,x,y);
Újabb pozícionálás után a szöveget is kiírjuk.
...
e.Graphics.DrawString(listBox1.Items[e.Index].ToString(),Font,new SolidBrush(Color.Black),x,y);
A listában végül 432 darab elnevezés és kép jelenik meg.