C# - Tetszőleges alkalmazások futásának letiltása

forráskód letöltése
A .NET osztálykönyvtár System.Diagnostics névterében található Process osztály statikus metódusai nagyon hasznosak akkor, amikor a számítógépen futó process-ekről szeretnénk információkat gyűjteni. Abban az esetben, ha valamilyen alkalmazástípus – például egy tetszőleges névvel rendelkező .NET-es alkalmazás – futását szeretnénk megakadályozni, nem nyújt elegendő segítséget, hiszen a futó process-eket név vagy azonosító alapján vagyunk csak képesek azonosítani. Cikkünkben annak járunk utána, hogy miként tudjuk ezen funkciót megvalósítani alternatív eszközök felhasználásával.
A mellékelt példa azon funkcióját, mely bizonyos megadott alkalmazástípusok futtatásának lehetőségét akadályozza meg, vagy a futó alkalmazástípus példányainak megszüntetéséről gondoskodik, csak abban az esetben tudjuk kipróbálni, ha a számítógépünkön telepítve van az adott, a programban felsorolt típusú alkalmazás valamelyike. Ezek: Internet Explorer, Windows Commander, Microsoft Outlook, Microsoft Word.
Az alkalmazásunk indulása után annak ablaka nem jelenik meg, csupán egy kis ikon jelzi a Tálcán alkalmazásunk futásának tényét. Az ikonra a jobb egérgombbal kattintva elérhetünk egy menüt, melyben az „Ablak megnyitása” menüpont kiválasztásával tehetjük láthatóvá a program konfigurációs ablakát.
A Form CheckedListBox kontroljában felsoroltuk azokat az alkalmazástípusokat, melyek futása a kiválasztás után leállítható, vagy a későbbi indítás megakadályozható.
A listában be kell jelölnünk azt a típust, melynek példányai nem futhatnak a számítógépen, és a fejléc bezárásért felelős gombjával elrejthetjük az ablakot. Az ikon menüjében az „Alkalmazás leállítása” menüpontra kattintva törölhetjük alkalmazásunkat a futó process-ek listájából.
A megoldás lényege, hogy minden GUI-val rendelkező alkalmazástípus ablaka rendelkezik egy fő osztálynévvel, mely alapján azonosíthatunk alkalmazásokat. Ezeknek már csak el kell küldenünk egy SendMessage üzenetet, és bezárhatjuk őket.
A projekt Win32osztályában helyeztük el azoknak az API függvényeknek az implementációját, melyek szükségesek a művelet elvégzéséhez.
Az üzenetküldés konstansai a következők:
public const int WM_SYSCOMMAND = 0x0112;
public const int SC_CLOSE = 0xF060;
A FindWindowEx metódussal határozhatjuk meg a futó alkalmazás ablakazonosítóját, mely a megadott osztállyal rendelkezik.
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr next, string sClassName, IntPtr sWindowTitle);
A bezárásra utasító üzenetet a SendMessage függvénnyel juttatjuk célba.
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);
A példaalkalmazásban felsorolt, és a futást megakadályozó funkcióban elérhető alkalmazások ablakosztályainak nevei a következők:
  • IEFrame: Internet Explorer
  • wndclass_desked_gsk: Visual Studio.NET IDE
  • TWINDOWSCMD: Windows Commander
  • rctrl_renwnd32: Microsoft Outlook
  • OpusApp: Microsoft Word
A programban elindítunk egy System.Timers.Timer típusú időzítőt, mely fél másodpercenként ellenőrzi a lista kijelöléseit, és a kijelölt nevű elemeket „lelövi”, vagy az indítandó alkalmazások futását akadályozza meg.
A periodikusan végzendő művelet kódja a következő. Elsőként megvizsgáljuk, hogy mely elemek vannak kijelölve:
for(int j=0;j<checkedListBox1.Items.Count;j++)
{
  if (checkedListBox1.CheckedItems[i].ToString() == checkedListBox1.Items[j].ToString())
  {
    cname = classes[j];  
  }
  ...
A kijelölések függvényében sorban kijelöljük az osztály nevét, melyet a ciklusban átadunk a FindWindowEx függvénynek.
  do
  {
    p2 = Win32.FindWindowEx(p1,p2,cname,IntPtr.Zero);
Ha fut ilyen alkalmazás a számítógépen, akkor elküldjük neki a bezárásra felszólító üzenetet.
    if (!p2.Equals(IntPtr.Zero))
    {
      Win32.SendMessage(p2, Win32.WM_SYSCOMMAND, Win32.SC_CLOSE,IntPtr.Zero);
    }
  } 
  while (!p2.Equals(IntPtr.Zero));
}
A művelet eredményeképpen ezek az alkalmazások nem futhatnak a rendszerben, amíg a programunkat le ne állítjuk.