C# - Kijelentkezés, újraindítás, leállítás: programból!

forráskód letöltése
Készítsünk egy komponenst, mely képes arra, hogy programból elvégezze a kijelentkezés, a számítógép újraindítása, leállítása műveletet. Ettől kezdve bármely alkalmazásunkat felruházhatjuk ezzel a képességgel: csak fel kell tennünk ezt a komponenst a Form-ra, kiválasztani a property-knél, hogy milyen műveletet szeretnénk elvégezni és már nincs is gondunk másra!
A megvalósításhoz az ExitWindowsEx Windows függvényt kell használnunk. Ezzel elvégezhetjük a fent említett funkciókat. Meghívása előtt némi további előkészítő műveletekre: további függvényhívásokra lesz szükség.
A Windows függvényeket és a működésükhöz szükséges konstansokat, struktúrákat a Win32 osztályba helyeztük el. A létrehozott Exit komponens négy új property-vel rendelkezik:
  • Flags - az elvégzendő művelet
  • Force - a művelet kikényszerítése, olyan esetben is ha egy alkalmazás nem válaszol
  • MajorReason - a művelet elvégzésnek okozója (csak XP esetén)
  • MinorReason - a művelet elvégzésnek oka (csak XP esetén).
A komponens egyetlen függvénnyel rendelkezik, mely az Execute nevet kapta. Ha már beállítottuk a kívánt funkciót a property-ken keresztül, akkor azt az Execute hívásával hajthatjuk végre.
Nézzük miként működik ez a függvény.
Ahhoz, hogy jogunk legyen újraindítani, leállítani egy gépen, NT/2000/XP alatt ahhoz szükséges a SE_SHUTDOWN_NAME privilégium megszerzése az alkalmazásunk számára. Ezt az AdjustTokenPrivileges függvény hívásával megtehetjük, viszont a függvény paramétereihez szükségünk van néhány értékre, melyek megszerzéséhez ismét további függvényeket kell meghívnunk ennek használata előtt.
    public void Execute()
    {
      Win32.LuidAttr tp;
      IntPtr h = IntPtr.Zero;
      Win32.OpenProcessToken(Win32.GetCurrentProcess(), Win32.TOKEN_ADJUST_PRIVILEGES | Win32.TOKEN_QUERY, ref h);
      tp.Count = 1;
      tp.Luid = 0;
      tp.Attr = Win32.SE_PRIVILEGE_ENABLED;
      Win32.LookupPrivilegeValue(null, Win32.SE_SHUTDOWN_NAME, ref tp.Luid);
      Win32.AdjustTokenPrivileges(h, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
Az ExitWindowsEx hívásához a komponens property-jeiben megadott értékekből előállítjuk a szükséges számokat, melyek a függvény két paraméterét képezik.
      uint p1 = Convert.ToUInt32(flag) + Convert.ToUInt32(force);
      uint p2 = Convert.ToUInt32(majorReason) + Convert.ToUInt32(minorReason);
      Win32.ExitWindowsEx(p1, p2);
    }