1.18.2010

糟糕的: CeRunAppAtEvent

只能說這真是一個/組莫名奇妙的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) 討論串。

1 則留言:

Xiao Bin 提到...

这个api的设计的目的就是如此吧。
要在某个事件发生时启动APP.