A megoldáshoz fontos tudnunk, hogy milyen operációs rendszer alatt fut a programunk, mivel Win9x sorozat alatt más a módja, mint WinNT alatt.
Win 95, 98, Me
Ez esetben a SetSuspendState függvény hívása lesz a kulcs. A függvény a Delphi unit-jaiban nem deklarált, így használatához ezt pótolnunk kell:
function SetSuspendState (Hibernate: boolean; ForceCritical: boolean; DisableWakeEvent: boolean): boolean; stdcall; external ‘Powrprof.dll’;
Ha a függvény Hibernate nevű paramétere igaz, akkor hibernálás funkció kerül végrehajtásra, különben a készenléti állapot.
A ForceCritical paraméter igaz értéke esetén egy PBT_APMSUSPEND üzenet kerül elküldésre minden alkalmazásnak és driver-nek, míg hamis érték esetén PBT_APMQUERYSUSPEND üzenet. Az első esetben feltétel nélkül megtörténik a kért funkció, míg a második esetben valamely alkalmazás, vagy driver megakadályozhatja a hibernálást, készenléti állapotba kerülést.
A DisableWakeEvent paraméter igaz értéke esetén letiltjuk a feléledés eseményét, míg hamis érték esetén létrejön ez az esemény újrainduláskor.
Win NT, 2000, XP, .NET
Windows NT vonalon a SetSystemPowerState függvény használatos, mellékelt példánkban is ezt valósítottuk meg.
E függvény használata valamivel bonyolultabb, mivel szüksége van alkalmazásunknak a SE_SHUTDOWN_NAME jog megszerzésére is.
A SetSystemPowerState függvény első paramétere ha igaz, akkor készenléti állapotba kerül a gép, míg hamis érték esetén hibernálva lesz. A második paraméter igaz értéke esetén egy PBT_APMSUSPEND üzenet kerül elküldésre minden alkalmazásnak és driver-nek, míg hamis érték esetén PBT_APMQUERYSUSPEND üzenet. Az első esetben feltétel nélkül megtörténik a kért funkció, míg a második esetben valamely alkalmazás, vagy driver megakadályozhatja a hibernálást, készenléti állapotba kerülést.
A függvény hívása előtt megfelelő jogokat kell szereznünk alkalmazásunknak, melyhez az AdjustTokenPrivileges függvény használata segít hozzá bennünket.
private void button1_Click(object sender, System.EventArgs e)
{
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);
Win32.SetSystemPowerState(true, true);
}