15.11.2013, Vladimír Klaus, navštíveno 6529x
Nedávno mě jeden známý požádal o naprogramování malé aplikace, pomocí které by mohl provádět některé „vypínací akce“ s počítačem. V tomto článku si ukážeme funkce a postupy, které jsem použil. Výsledná aplikace AUDREY Restart PC je ke stažení na této stránce a je samozřejmě zcela zdarma.
Vypnutí, restart, odhlášení
Samotný princip není složitý – vlastně se jen volá systémová funkce s parametrem, který to zařídí. Například vypnutí počítače.
ExitWindowsEx(EWX_SHUTDOWN, 0);
Jenomže se může stát, že nám to bude nějaká aplikace blokovat, Windows se nás budou ptát, zda ji chceme ukončit, aplikace neodpovídá apod. Pokud toto nechceme řešit, příkaz se vylepší o konstantu, která vypnutí (nebo jiný příkaz) vynutí.
ExitWindowsEx(EWX_SHUTDOWN + EWX_FORCE, 0);
Tyto konstanty jsou definovány ve Winapi.Windows.pas. Tam najdete i ty další potřebné, které zajistí třeba odhlášení nebo restart.
ExitWindowsEx(EWX_LOGOFF + EWX_FORCE, 0);
ExitWindowsEx(EWX_REBOOT + EWX_FORCE, 0);
Situace se trochu komplikuje ve chvíli, kdy zjistíte, že vám toto z nějakého důvodu nefunguje. Možná je to tím, že nemáte práva nebo že váš systém (BIOS, grafická karta) danou akci nepodporuje. Pak budete muset doplnit do programu nějaké to testování…
Já už řadu let používám tuto složitější funkci, které předávám jen jeden parametr. Vynucení se přidává automaticky. Funguje spolehlivě i na 64bit Windows a byla použita při přípravě ukázkové aplikace.
procedure UkoncitWindows(aAkce: Shortint);
var
hToken, hProcess: THandle;
tp, prev_tp: TTokenPrivileges;
Len : DWORD;
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then begin
hProcess := OpenProcess(PROCESS_ALL_ACCESS, True, GetCurrentProcessID);
try
if not OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,hToken) then Exit;
finally
CloseHandle(hProcess);
end;
try
if not LookupPrivilegeValue('', 'SeShutdownPrivilege',tp.Privileges[0].Luid) then Exit;
tp.PrivilegeCount := 1;
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
if not AdjustTokenPrivileges(hToken, False, tp, SizeOf(prev_tp),prev_tp, Len) then Exit;
finally
CloseHandle(hToken);
end;
end;
ExitWindowsEx(EWX_FORCE or aAkce, 0);
end;
Uspání a hibernace
Na tyto akce se musí úplně jinak. Nejprve si nadefinujeme odkaz na externí systémovou funkci SetSuspendState.
function SetSuspendState(hibernate, forcecritical, disablewakeevent: boolean): boolean;
stdcall; external 'powrprof.dll' name 'SetSuspendState';
A pak ji použijeme. První volání počítač uspí, druhé ho hibernuje. Vše důležité řeší vlastně jen ten první parametr.
SetSuspendState(false, false, false);
SetSuspendState(true, false, false);
Pokud vás teď napadá, jaký je rozdíl mezi uspáním a hibernací, tak se to má takto:
Režim spánku spočívá v tom, že se počítač zdánlivě vypne, ale on pouze velice sníží spotřebu. Všechna rozpracovaná práce je uložena do paměti. Pokud počítač probudíte (třeba myší nebo klávesnicí), uvede se během několika vteřin do stavu, v jakém byl těsně před uspáním. Vše tedy běží a vy můžete okamžitě pokračovat v práci.
Režim hibernace je podobný režimu spánku, ale s tím rozdílem, že se veškerá rozpracovaná práce (stav paměti) uloží na disk a počítač se skutečně vypne. Pokud ho pak tlačítkem pro zapínání nastartujete, probíhá opravdový start počítače, ale na konci se uvede do stavu, v jakém jste ho hibernovali. Všechny spuštěné aplikace poběží (obnoví se jejich stav z disku) a vy i v tomto případě můžete pokračovat v práci.
Závěr
Pokud vás celá problematika více zajímá, doporučuji níže uvedené stránky. Bohužel je na webu i řada jiných podobných informací, které mohou být zkreslené nebo dokonce nepravdivé (i když třeba jen proto, že to fungovalo před 10 lety na starších Windows, ale dnes už ne). Pokud budete programovat aplikaci využívající takovéto speciální funkce, dbejte na kvalitu informací. Uživatelé to ocení.
http://www.tek-tips.com/faqs.cfm?fid=6881
http://msdn.microsoft.com/en-us/library/windows/desktop/aa376868(v=vs.85).aspx
http://windows.microsoft.com/cs-CZ/Windows7/Sleep-and-hibernation-frequently-asked-questions
Pochopitelně budu rád za připomínky nebo další náměty. Buď k tomuto článku nebo ukázkové aplikaci, kterou budu (občas) zlepšovat.