Je to už hodně dávno, někdy na samém začátku našeho seriálu, kdy jsme si povídali o programovém vypnutí či restartu počítače. No a dneska si povíme ještě o další možnosti, jak počítač vypnout.
Možná si ještě vzpomenete na původní funkce v jednom z prvních dílů seriálu. Pomocí nich naše aplikace dokázala restartovat či zcela vypnout počítač. Po stisknutí tlačítka se pak požadovaná funkce ihned provedla. Případně jste si mohli vytvořit jednoduchý program na vypnutí počítače po uplynutí určité doby, stačilo opatřit aplikaci jednoduchým
Timerem. Tak či tak, naše aplikace musela v rozhodujícím okamžiku vypnutí počítače běžet, protože právě naše aplikace vydala příkaz, aby se systém ukončil.
Co když ale chceme, aby náš program sice vydal pokyn k vypnutí systému, ale aby nemusel v onu "kritickou" chvíli běžet? Jednoduše řečeno, naše aplikace rozkáže systému, aby se vypnul například za 5 minut a pak můžeme naší aplikaci klidně ukončit. Systém už se o zbytek postará. Přihlášeným uživatelům se zobrazí výstražné varování o tom, že bude systém vypnut a jaký uživatel k tomu vydal pokyn. Zároveň bude v tomto dialogovém okně i zobrazen odpočet času, zbývajícího do restartu. Navíc je ještě v tomto malém okně i místo pro zprávu pro uživatele, kde můžete blíže vysvětlit, proč k restartu či vypnutí dochází.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function TimedShutDown(Computer: string; Msg: string; Time: Word; Force: Boolean; Reboot: Boolean): Boolean;
var
rl: Cardinal;
hToken: Cardinal;
tkp: TOKEN_PRIVILEGES;
begin
if not OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then ShowMessage(`Cannot open process token.`)
else
begin
if LookupPrivilegeValue(nil, `SeShutdownPrivilege`, tkp.Privileges[0].Luid) then
begin
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
tkp.PrivilegeCount := 1;
AdjustTokenPrivileges(hToken, False, tkp, 0, nil, rl);
if GetLastError <> ERROR_SUCCESS then ShowMessage(`Error adjusting process privileges.`);
end
else
ShowMessage(`Cannot find privilege value.`);
end;
Result := InitiateSystemShutdown(PChar(Computer), PChar(Msg), Time, Force, Reboot)
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if not TimedShutDown(`\\pocitac`, `Pozor, pocítac bude restartován!`, 30, true, true) then ShowMessage(`Chyba, funkci se nepodarilo spustit...`);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
AbortSystemShutdown(`\\pocitac`);
end;
end.
Asi už vás napadlo z předchozího odstavce, že tato funkce bude pracovat pouze pod systémy NT/2000/XP. Starší řada 9x zobrazí při pokusu o aktivování funkce varovné hlášení a neprovede samozřejmě nic.
Všimněte si na konci zdrojového kódu ještě jedné funkce - AbortSystemShutdown. Ta slouží, jak říká její název, ke zrušení příkazu na vypnutí počítače. Stihnete-li tedy včas než vyprší daný časový interval tuto funkci aktivovat například stiskem příslušného tlačítka jako v našem příkladu, odpočítávání bude zrušeno a systém se nevypne.
Nesmíme zapomenout na popis parametrů naší funkce TimedShutDown. Prvním parametrem je název počítače, který chceme vypnout. Dále máme textovou proměnnou, kde můžeme napsat onu konkrétnější zprávu pro uživatele. Číslo, které následuje, udává v sekundách dobu, za jakou k restartu či vypnutí dojde. Předposlední logická proměnná určuje, zda chceme provést "násilné" vypnutí, tedy bez ohledu na to, v jakém stavu jsou ostatní spuštěné aplikace a zda nám chtějí vypnutí "dovolit". Poslední parametr určuje, zda dojde jen k restartu nebo k úplnému vypnutí.