Ala*_*ult 5 delphi timer windows-7
关于可等待的计时器,我有些不明白。我在网上搜索并阅读了 MSDN 上的规范以及我在 stackoverflow 上可以找到的任何内容(例如link),但是我的计时器在 PC 挂起后几乎立即触发。
为了解决这个问题,我在 Windows 7 中使用 XE5(64 位)编写了一个小型测试应用程序,并尝试复制此处找到的项目:http : //www.codeproject.com/Articles/49798/Wake-the-PC-从待机或休眠
我以为问题是我推导时间的方式,但我似乎找不到问题所在。
测试应用程序看起来像这样(非常简单):

我声明线程类型如下
type
TWakeupThread = class(TThread)
private
FTime: LARGE_INTEGER;
protected
procedure Execute; override;
public
constructor Create(Time: LARGE_INTEGER);
end;
Run Code Online (Sandbox Code Playgroud)
...
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;
Run Code Online (Sandbox Code Playgroud)
现在,当单击“设置计时器”按钮时,我会以这种方式计算文件时间并创建线程。
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;
Run Code Online (Sandbox Code Playgroud)
这不起作用。无论选择多长时间,系统进入挂起模式后,计时器似乎都会在不到 2 分钟的时间内触发。任何关于我做错了什么的指针将不胜感激。
编辑
找到了这个有趣的命令行工具,让我们检查可等待的计时器。从命令中,您可以通过键入以下内容“查看”可等待计时器的状态:
powercfg -waketimers
Run Code Online (Sandbox Code Playgroud)
我可以用它来确认我的计时器设置正确。我还可以使用它来确认我的计时器在 PC 过早唤醒时仍在运行。
使用相同的工具,您可以获得能够从休眠状态唤醒的设备列表(在我的情况下是鼠标、键盘、网络):
powercfg -devicequery wake_armed
Run Code Online (Sandbox Code Playgroud)
在所有测试的系统上,命令“powercfg -lastwake”返回以下内容,我不知道如何破译:
Wake History Count - 1
Wake History [0]
Wake Source Count - 0
Run Code Online (Sandbox Code Playgroud)
我在 Windows 中启用了睡眠和休眠,几秒钟后都会唤醒。没有键盘/鼠标活动,我们也没有设备向这些 PC 发送 WOL(网络唤醒)请求。
我想知道在调用 SetSuspendState 时是否需要做一些特别的事情;这是我的代码:
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;
Run Code Online (Sandbox Code Playgroud)
该问题与delphi 或代码没有任何关系。该问题是由 Windows 7 的一项功能造成的,该功能在启用 WOL 时不仅仅启用魔术数据包。强制 Windows 仅侦听魔术数据包解决了该问题。
MS链接: http: //support.microsoft.com/kb/941145
感谢所有试图提供帮助的人,特别是 David Heffernan,他提到了可能是其他东西唤醒了电脑。
| 归档时间: |
|
| 查看次数: |
1529 次 |
| 最近记录: |