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);
}