Understanding expected timers
There is something I don't understand about suitable timers. I've searched the web and read the specs on MSDN plus everything I could find on stackoverflow (like the link ), but my timers fire almost immediately after the PC stops.
To focus on the problem, I wrote a small test application using XE5 (64-bit) on Windows 7 and tried to duplicate the project found here: http://www.codeproject.com/Articles/49798/Wake-the-PC-from -standby-or-hibernation
I thought the problem was how I get the time, but I can't seem to find the problem.
The test application looks like this (very simple):
I declare the stream type as follows
type
TWakeupThread = class(TThread)
private
FTime: LARGE_INTEGER;
protected
procedure Execute; override;
public
constructor Create(Time: LARGE_INTEGER);
end;
...
constructor TWakeupThread.Create(Time: LARGE_INTEGER);
begin
inherited Create(False);
FreeOnTerminate:=True;
FTime:=Time;
end;
procedure TWakeupThread.Execute;
var
hTimer: THandle;
begin
// Create a waitable timer.
hTimer:=CreateWaitableTimer(nil, True, 'WakeupThread');
if (hTimer <> 0) then
begin
//CancelWaitableTimer(hTimer);
if (SetWaitableTimer(hTimer, FTime.QuadPart, 0, nil, nil, True)) then
begin
WaitForSingleObject(hTimer, INFINITE);
end;
CloseHandle(hTimer);
end;
end;
Now that the Set Timer button is clicked, I calculate the file time this way and create a stream.
procedure TForm1.btnSetTimerClick(Sender: TObject);
var
iUTCTime : LARGE_INTEGER;
SysTime : _SystemTime;
FTime : _FileTime;
hHandle : THandle;
dt : TDateTime;
begin
ReplaceDate(dt,uiDate.DateTime);
ReplaceTime(dt,uiTime.DateTime);
DateTimeToSystemTime(dt, SysTime);
SystemTimeToFileTime(SysTime, FTime);
LocalFileTimeToFileTime(FTime, FTime);
iUTCTime.LowPart := FTime.dwLowDateTime;
iUTCTime.HighPart := FTime.dwHighDateTime;
TWakeupThread.Create(iUTCTime);
end;
This does not work. The timer seems to fire less than 2 minutes after the system goes into suspend mode regardless of the amount of time selected. Any guidance as to what I am doing wrong would be appreciated.
EDIT
Found this interesting command line tool that allows us to check expected timers. From the command, you can "see" the status of your pending timers by typing:
powercfg -waketimers
I can use this to confirm that my timers are set correctly. I can also use this to confirm that my timers are still running when the PC wakes up prematurely.
Using the same tool, you can get a list of devices that can wake up from sleep (mouse, keyboard, network in my case):
powercfg -devicequery wake_armed
On all systems tested, the "powercfg -lastwake" command returns the following, which I don't know how to decrypt:
Wake History Count - 1
Wake History [0]
Wake Source Count - 0
I have both sleep and hibernate enabled on Windows and both will wake up after a few seconds. There is no keyboard and mouse activity, and we have no devices sending WOL (wake-on-lan) requests to these PCs.
I am wondering if I need something special when calling SetSuspendState; here's my code:
function SetSuspendState(Hibernate, ForceCritical, DisableWakeEvent: Boolean): Boolean;
//Hibernate = False : system suspends
//Hibernate = True : system hibernates
begin
if not Assigned(_SetSuspendState) then
@_SetSuspendState := LinkAPI('POWRPROF.dll', 'SetSuspendState');
if Assigned(_SetSuspendState) then
Result := _SetSuspendState(Hibernate, ForceCritical, DisableWakeEvent)
else
Result := False;
end;
function LinkAPI(const module, functionname: string): Pointer;
var
hLib: HMODULE;
begin
hLib := GetModuleHandle(PChar(module));
if hLib =0 then
hLib := LoadLibrary(PChar(module));
if hLib <> 0 then
Result := getProcAddress(hLib, PChar(functionname))
else
Result := nil;
end;
procedure TForm1.btnSuspendClick(Sender: TObject);
begin
SetSuspendState(True, False, False);
end;
source to share
The problem was not delphi or code related in any way. The problem was created with a Windows 7 feature that allows more than magic packs when WOL is enabled. Forcing Windows to only listen for magic packets solved the problem.
MS Link: http://support.microsoft.com/kb/941145
Thanks to everyone who tried to help, and especially David Heffernan, who hinted at the possibility that something else is awakening the computer.
source to share