只能說這真是一個/組莫名奇妙的api呀....
CE 可以用
CeRunAppAtEvent(_T("\\\\.\\Notifications\\NamedEvents\\MYWAKEUPEVENT"),
NOTIFICATION_EVENT_WAKEUP
要求 kernel (GWES) 把 OS內部 的 EVENT_WAKEUP 轉成 Signal MYWAKEUPEVENT。
但是...這個 funciton 被 call 幾次, wakeup 時,那個 event 就會被 signal 幾次。
也就是說,即使你的 ap 已經結束,但是event 已經 create 起來,OS也註冊了,所以即使你的 Ap 已經結束了,OS 還是會依照註冊的內容執行..
所以,要 記得 un-register...就是把那個 event 改對應到 NOTIFICATION_EVENT_NONE 就可以:
CeRunAppAtEvent(_T("\\\\.\\Notifications\\NamedEvents\\MYWAKEUPEVENT"),
NOTIFICATION_EVENT_NONE)
附上測試的 code :
// SYSWAKEUPEVENT.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include <notify.h>
HWND MainWnd;
int rcvcnt=0;
DWORD WINAPI WaiterThread(PVOID pArg)
{
HANDLE WakeUpEvent;
WakeUpEvent = CreateEvent(NULL,FALSE,FALSE,_T("MYWAKEUPEVENT"));
if(WakeUpEvent == NULL){
RETAILMSG(1,(TEXT("CreateEvent Failed\r\n")));
ExitThread(0);
}
if(!CeRunAppAtEvent(_T("\\\\.\\Notifications\\NamedEvents\\MYWAKEUPEVENT"),
NOTIFICATION_EVENT_NONE)){
RETAILMSG(1,(TEXT("CeRunAppAtEvent NONE Failed\r\n")));
ExitThread(0);
}
if(!CeRunAppAtEvent(_T("\\\\.\\Notifications\\NamedEvents\\MYWAKEUPEVENT"),
NOTIFICATION_EVENT_WAKEUP)){
RETAILMSG(1,(TEXT("CeRunAppAtEvent Failed\r\n")));
ExitThread(0);
}
while(1){
DWORD EventGot;
EventGot = WaitForSingleObject(WakeUpEvent,INFINITE);
if(EventGot==WAIT_OBJECT_0){
rcvcnt++;
RETAILMSG(1,(TEXT("received! %d\r\n"),rcvcnt));
InvalidateRect(MainWnd,NULL,TRUE);
}else{
RETAILMSG(1,(TEXT("receive not object 0 : %d\r\n"),EventGot));
}
}
}
HANDLE hWaiterThread;
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
RECT rect;
HDC hdc;
switch(wMsg){
case WM_PAINT:
{
TCHAR outtext[50];
GetClientRect(hWnd,&rect);
hdc = BeginPaint(hWnd, &ps);
swprintf(outtext,TEXT("Received WAKEUP EVENT: %d"),rcvcnt);
DrawText(hdc, outtext,-1,&rect,DT_CENTER | DT_CENTER | DT_SINGLELINE);
EndPaint(hWnd,&ps);
}
return 0;
case WM_DESTROY:
if(hWaiterThread)
CloseHandle(hWaiterThread);
PostQuitMessage(0);
}
return DefWindowProc(hWnd, wMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
WNDCLASS wc;
MSG msg;
// register the main windows class
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT("SYSWAKEUPEVENT");
if(RegisterClass(&wc) == NULL){
RETAILMSG(1,(TEXT("RegisterClass Failed\r\n")));
return -1;
}
MainWnd = CreateWindowEx(WS_EX_NODRAG,TEXT("SYSWAKEUPEVENT"),TEXT("SYSWAKEUPEVENT"),
WS_VISIBLE | WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
if(!IsWindow(MainWnd)){
RETAILMSG(1,(TEXT("CreateWindowsEx Failed\r\n")));
return -2;
}
ShowWindow(MainWnd,nCmdShow);
UpdateWindow(MainWnd);
hWaiterThread = CreateThread(NULL,0,WaiterThread,NULL,0,NULL);
if(hWaiterThread == NULL){
RETAILMSG(1,(TEXT("CreateThread Failed\r\n")));
}
while(GetMessage (&msg,NULL,0,0) ) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
return 0;
}
reference
這一個 (http://social.msdn.microsoft.com/Forums/en-US/vssmartdevicesvbcs/thread/11c91a9f-9626-4db5-afaa-233ad514e6a3) 討論串。