Prevent/Log Time Change To PocketPC?

  • Thread starter Thread starter Scott Johnson
  • Start date Start date
S

Scott Johnson

Hi

I am developing an app in VB.NET for the PocketPC and the customer wants to
log every time the system clock is changed. (So delivery drivers can't roll
back the clock to cheat the system.)

Is there a way to either 1) prevent the system date/time from being changed
or 2) raise an event to the fact that the date/time was changed so that it
can be logged?

Thanks a lot!
--Scott
 
Maybe you can use P/Invoke to call CeRunAppAtEvent and listen to the
NOTIFICATION_EVENT_TIME_CHANGE event to do your logging

Hope that helps
 
Sorry for the cross post, but I noticed this thread after posting my
question in another newsgroup. I figured it's on topic here, so I'm posting
it here too.

When I call WaitForNotificationEvent(NOTIFICATION_EVENT_TIME_CHANGE) or
WaitForNotificationEvent(NOTIFICATION_EVENT_TZ_CHANGE) in the code below,
Then open control panel and change the system time or time zone, the named
event never signals. I wait forever at the WaitForSingleObject() line. Is
there something else I need to do differently with CeRunAppAtEvent? Does the
control panel applet somehow change the time or timezone without this
notification?

I noticed that the CE.NET 4.2 docs on CeRunAppAtEvent at
http://msdn.microsoft.com/library/d...y/en-us/wceui40/html/cerefcerunappatevent.asp
say that pwszAppName can refer to a named event, and that named events are
supported in CE.NET 4.0 and later, but I'm wondering if the functionality of
having CeRunAppAtEvent signal a named event is new in CE.NET 4.2, or if it's
also supported in 4.1. I don't see this functionality described in the
CeRunAppAtEvent docs for 4.1. Does anyone have any experience with using
CeRunAppAtEvent this way? I tried having it run an executable too, but no
better luck.

[DllImport("coredll.dll", EntryPoint="CeRunAppAtEvent", SetLastError=true)]
private static extern int CeRunAppAtEvent(string pwszAppName,
NOTIFICATION_EVENT lWhichEvent);

public enum NOTIFICATION_EVENT : int
{
NOTIFICATION_EVENT_NONE = 0,
NOTIFICATION_EVENT_TIME_CHANGE = 1,
NOTIFICATION_EVENT_SYNC_END = 2,
NOTIFICATION_EVENT_ON_AC_POWER = 3,
NOTIFICATION_EVENT_OFF_AC_POWER = 4,
NOTIFICATION_EVENT_NET_CONNECT = 5,
NOTIFICATION_EVENT_NET_DISCONNECT = 6,
NOTIFICATION_EVENT_DEVICE_CHANGE = 7,
NOTIFICATION_EVENT_IR_DISCOVERED = 8,
NOTIFICATION_EVENT_RS232_DETECTED = 9,
NOTIFICATION_EVENT_RESTORE_END = 10,
NOTIFICATION_EVENT_WAKEUP = 11,
NOTIFICATION_EVENT_TZ_CHANGE = 12,
NOTIFICATION_EVENT_MACHINE_NAME_CHANGE = 13
}

private void WaitForNotificationEvent(NOTIFICATION_EVENT notificationEvent)
string szEventName = "\\\\.\\Notifications\\NamedEvents\\" +
notificationEvent.ToString() + "\0";
hEvent = CreateEvent(IntPtr.Zero, 1, 0, szEventName);
if(0 != hEvent)
{
if(0 != CeRunAppAtEvent(szEventName, NotificationEvent))
{
WaitForSingleObject( hEvent, 0xFFFFFFFF );
Console.Writeline(notificationEvent.ToString());
ResetEvent(hEvent);
}
CloseHandle(hEvent);
hEvent = 0;
}
}

Thanks,
Dave
 
Your code confuses me. You use CeRunAppAtEvent to run a specified app when
an event occurs.

In this instance let's say you write a C++ app called TimeChanged.exe. In
that app, you would either log the time change or set the clock back (though
you'd have to get the right time somehow).

If you want another app to know that the event has occurred (and use
something like WaitForSingleObject), in TimeChanged.exe you simply do a
CreateEvent on an event with a unique name, let's call it
"MyTimeChangedEvent", set it and then exit. Any other app can then create
and wait on that named event.

--
Chris Tacke, eMVP
Co-Founder and Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net


Dave Hall said:
Sorry for the cross post, but I noticed this thread after posting my
question in another newsgroup. I figured it's on topic here, so I'm posting
it here too.

When I call WaitForNotificationEvent(NOTIFICATION_EVENT_TIME_CHANGE) or
WaitForNotificationEvent(NOTIFICATION_EVENT_TZ_CHANGE) in the code below,
Then open control panel and change the system time or time zone, the named
event never signals. I wait forever at the WaitForSingleObject() line. Is
there something else I need to do differently with CeRunAppAtEvent? Does the
control panel applet somehow change the time or timezone without this
notification?

I noticed that the CE.NET 4.2 docs on CeRunAppAtEvent at
http://msdn.microsoft.com/library/d...y/en-us/wceui40/html/cerefcerunappatevent.asp
say that pwszAppName can refer to a named event, and that named events are
supported in CE.NET 4.0 and later, but I'm wondering if the functionality of
having CeRunAppAtEvent signal a named event is new in CE.NET 4.2, or if it's
also supported in 4.1. I don't see this functionality described in the
CeRunAppAtEvent docs for 4.1. Does anyone have any experience with using
CeRunAppAtEvent this way? I tried having it run an executable too, but no
better luck.

[DllImport("coredll.dll", EntryPoint="CeRunAppAtEvent", SetLastError=true)]
private static extern int CeRunAppAtEvent(string pwszAppName,
NOTIFICATION_EVENT lWhichEvent);

public enum NOTIFICATION_EVENT : int
{
NOTIFICATION_EVENT_NONE = 0,
NOTIFICATION_EVENT_TIME_CHANGE = 1,
NOTIFICATION_EVENT_SYNC_END = 2,
NOTIFICATION_EVENT_ON_AC_POWER = 3,
NOTIFICATION_EVENT_OFF_AC_POWER = 4,
NOTIFICATION_EVENT_NET_CONNECT = 5,
NOTIFICATION_EVENT_NET_DISCONNECT = 6,
NOTIFICATION_EVENT_DEVICE_CHANGE = 7,
NOTIFICATION_EVENT_IR_DISCOVERED = 8,
NOTIFICATION_EVENT_RS232_DETECTED = 9,
NOTIFICATION_EVENT_RESTORE_END = 10,
NOTIFICATION_EVENT_WAKEUP = 11,
NOTIFICATION_EVENT_TZ_CHANGE = 12,
NOTIFICATION_EVENT_MACHINE_NAME_CHANGE = 13
}

private void WaitForNotificationEvent(NOTIFICATION_EVENT notificationEvent)
string szEventName = "\\\\.\\Notifications\\NamedEvents\\" +
notificationEvent.ToString() + "\0";
hEvent = CreateEvent(IntPtr.Zero, 1, 0, szEventName);
if(0 != hEvent)
{
if(0 != CeRunAppAtEvent(szEventName, NotificationEvent))
{
WaitForSingleObject( hEvent, 0xFFFFFFFF );
Console.Writeline(notificationEvent.ToString());
ResetEvent(hEvent);
}
CloseHandle(hEvent);
hEvent = 0;
}
}

Thanks,
Dave

Jose Luis Balsera said:
Maybe you can use P/Invoke to call CeRunAppAtEvent and listen to the
NOTIFICATION_EVENT_TIME_CHANGE event to do your logging

Hope that helps

"Scott Johnson" <sjohnson_at_softaltern_dot_comDIESPAM> escribió en el
mensaje news:[email protected]...
 
Your description of CeRunAppAtEvent corresponds to most of the documentation
I've seen, but the docs at
http://msdn.microsoft.com/library/d...y/en-us/wceui40/html/cerefcerunappatevent.asp
specifically say in regard to the pwszAppName parameter, that "You can also
use this string to support a named event instead of launching an
application." That's what I'm trying to do. I actually tried it the way you
described it by using "\Windows\Cmd.exe" as pwszAppName, thinking that it
would invoke a command prompt when I changed the system time. That didn't
work either. What I realy want is to tell CE to signal the named event, and
then I just sit and wait for it. Obviously, I do this in a background
thread. That's not shown in my sample code below. I was just trying to
reduce my problem to the bare minimum so I could post it.

Thanks for any ideas you might have.
Dave


Chris Tacke said:
Your code confuses me. You use CeRunAppAtEvent to run a specified app when
an event occurs.

In this instance let's say you write a C++ app called TimeChanged.exe. In
that app, you would either log the time change or set the clock back (though
you'd have to get the right time somehow).

If you want another app to know that the event has occurred (and use
something like WaitForSingleObject), in TimeChanged.exe you simply do a
CreateEvent on an event with a unique name, let's call it
"MyTimeChangedEvent", set it and then exit. Any other app can then create
and wait on that named event.

--
Chris Tacke, eMVP
Co-Founder and Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net


Dave Hall said:
Sorry for the cross post, but I noticed this thread after posting my
question in another newsgroup. I figured it's on topic here, so I'm posting
it here too.

When I call WaitForNotificationEvent(NOTIFICATION_EVENT_TIME_CHANGE) or
WaitForNotificationEvent(NOTIFICATION_EVENT_TZ_CHANGE) in the code below,
Then open control panel and change the system time or time zone, the named
event never signals. I wait forever at the WaitForSingleObject() line. Is
there something else I need to do differently with CeRunAppAtEvent? Does the
control panel applet somehow change the time or timezone without this
notification?

I noticed that the CE.NET 4.2 docs on CeRunAppAtEvent at
http://msdn.microsoft.com/library/d...y/en-us/wceui40/html/cerefcerunappatevent.asp
say that pwszAppName can refer to a named event, and that named events are
supported in CE.NET 4.0 and later, but I'm wondering if the
functionality
of
having CeRunAppAtEvent signal a named event is new in CE.NET 4.2, or if it's
also supported in 4.1. I don't see this functionality described in the
CeRunAppAtEvent docs for 4.1. Does anyone have any experience with using
CeRunAppAtEvent this way? I tried having it run an executable too, but no
better luck.

[DllImport("coredll.dll", EntryPoint="CeRunAppAtEvent", SetLastError=true)]
private static extern int CeRunAppAtEvent(string pwszAppName,
NOTIFICATION_EVENT lWhichEvent);

public enum NOTIFICATION_EVENT : int
{
NOTIFICATION_EVENT_NONE = 0,
NOTIFICATION_EVENT_TIME_CHANGE = 1,
NOTIFICATION_EVENT_SYNC_END = 2,
NOTIFICATION_EVENT_ON_AC_POWER = 3,
NOTIFICATION_EVENT_OFF_AC_POWER = 4,
NOTIFICATION_EVENT_NET_CONNECT = 5,
NOTIFICATION_EVENT_NET_DISCONNECT = 6,
NOTIFICATION_EVENT_DEVICE_CHANGE = 7,
NOTIFICATION_EVENT_IR_DISCOVERED = 8,
NOTIFICATION_EVENT_RS232_DETECTED = 9,
NOTIFICATION_EVENT_RESTORE_END = 10,
NOTIFICATION_EVENT_WAKEUP = 11,
NOTIFICATION_EVENT_TZ_CHANGE = 12,
NOTIFICATION_EVENT_MACHINE_NAME_CHANGE = 13
}

private void WaitForNotificationEvent(NOTIFICATION_EVENT notificationEvent)
string szEventName = "\\\\.\\Notifications\\NamedEvents\\" +
notificationEvent.ToString() + "\0";
hEvent = CreateEvent(IntPtr.Zero, 1, 0, szEventName);
if(0 != hEvent)
{
if(0 != CeRunAppAtEvent(szEventName, NotificationEvent))
{
WaitForSingleObject( hEvent, 0xFFFFFFFF );
Console.Writeline(notificationEvent.ToString());
ResetEvent(hEvent);
}
CloseHandle(hEvent);
hEvent = 0;
}
}

Thanks,
Dave

Jose Luis Balsera said:
Maybe you can use P/Invoke to call CeRunAppAtEvent and listen to the
NOTIFICATION_EVENT_TIME_CHANGE event to do your logging

Hope that helps

"Scott Johnson" <sjohnson_at_softaltern_dot_comDIESPAM> escribió en el
mensaje news:[email protected]...
 
Well I'll be damned, an interesting note. I just tried on a vanilla CE 4.2
device and it did in fact work. Here's the code I used (I understand it's
not managed, but it should be easy to port):

volatile BOOL threadRunning;

DWORD WINAPI EventWaitThreadProc(LPVOID lpParameter)
{
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, _T("MyTimeChangedEvent"));
WaitForSingleObject(hEvent, INFINITE);

DEBUGMSG(TRUE, (_T("\r\n** TIME CHANGE DETECTED **\r\n")));
threadRunning = FALSE;
ExitThread(0);
return 0;
}

int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
DEBUGMSG(TRUE, (_T("\r\nStart test\r\n")));

CeRunAppAtEvent(_T("\\\\.\\Notifications\\NamedEvents\\MyTimeChangedEvent"),
NOTIFICATION_EVENT_TIME_CHANGE);
CreateThread(NULL, 0, EventWaitThreadProc, NULL, 0, NULL);
threadRunning = TRUE;
while(threadRunning)
{
Sleep(1000);
DEBUGMSG(TRUE, (_T(".")));
}
DEBUGMSG(TRUE, (_T("\r\nEnd test\r\n")));

return 0;
}

--
Chris Tacke, eMVP
Co-Founder and Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net


Dave Hall said:
Your description of CeRunAppAtEvent corresponds to most of the documentation
I've seen, but the docs at
http://msdn.microsoft.com/library/d...y/en-us/wceui40/html/cerefcerunappatevent.asp
specifically say in regard to the pwszAppName parameter, that "You can also
use this string to support a named event instead of launching an
application." That's what I'm trying to do. I actually tried it the way you
described it by using "\Windows\Cmd.exe" as pwszAppName, thinking that it
would invoke a command prompt when I changed the system time. That didn't
work either. What I realy want is to tell CE to signal the named event, and
then I just sit and wait for it. Obviously, I do this in a background
thread. That's not shown in my sample code below. I was just trying to
reduce my problem to the bare minimum so I could post it.

Thanks for any ideas you might have.
Dave


Chris Tacke said:
Your code confuses me. You use CeRunAppAtEvent to run a specified app when
an event occurs.

In this instance let's say you write a C++ app called TimeChanged.exe. In
that app, you would either log the time change or set the clock back (though
you'd have to get the right time somehow).

If you want another app to know that the event has occurred (and use
something like WaitForSingleObject), in TimeChanged.exe you simply do a
CreateEvent on an event with a unique name, let's call it
"MyTimeChangedEvent", set it and then exit. Any other app can then create
and wait on that named event.

--
Chris Tacke, eMVP
Co-Founder and Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net


Does
the
http://msdn.microsoft.com/library/d...y/en-us/wceui40/html/cerefcerunappatevent.asp
say that pwszAppName can refer to a named event, and that named events are
supported in CE.NET 4.0 and later, but I'm wondering if the
functionality
of
having CeRunAppAtEvent signal a named event is new in CE.NET 4.2, or
if
it's
also supported in 4.1. I don't see this functionality described in the
CeRunAppAtEvent docs for 4.1. Does anyone have any experience with using
CeRunAppAtEvent this way? I tried having it run an executable too, but no
better luck.

[DllImport("coredll.dll", EntryPoint="CeRunAppAtEvent", SetLastError=true)]
private static extern int CeRunAppAtEvent(string pwszAppName,
NOTIFICATION_EVENT lWhichEvent);

public enum NOTIFICATION_EVENT : int
{
NOTIFICATION_EVENT_NONE = 0,
NOTIFICATION_EVENT_TIME_CHANGE = 1,
NOTIFICATION_EVENT_SYNC_END = 2,
NOTIFICATION_EVENT_ON_AC_POWER = 3,
NOTIFICATION_EVENT_OFF_AC_POWER = 4,
NOTIFICATION_EVENT_NET_CONNECT = 5,
NOTIFICATION_EVENT_NET_DISCONNECT = 6,
NOTIFICATION_EVENT_DEVICE_CHANGE = 7,
NOTIFICATION_EVENT_IR_DISCOVERED = 8,
NOTIFICATION_EVENT_RS232_DETECTED = 9,
NOTIFICATION_EVENT_RESTORE_END = 10,
NOTIFICATION_EVENT_WAKEUP = 11,
NOTIFICATION_EVENT_TZ_CHANGE = 12,
NOTIFICATION_EVENT_MACHINE_NAME_CHANGE = 13
}

private void WaitForNotificationEvent(NOTIFICATION_EVENT notificationEvent)
string szEventName = "\\\\.\\Notifications\\NamedEvents\\" +
notificationEvent.ToString() + "\0";
hEvent = CreateEvent(IntPtr.Zero, 1, 0, szEventName);
if(0 != hEvent)
{
if(0 != CeRunAppAtEvent(szEventName, NotificationEvent))
{
WaitForSingleObject( hEvent, 0xFFFFFFFF );
Console.Writeline(notificationEvent.ToString());
ResetEvent(hEvent);
}
CloseHandle(hEvent);
hEvent = 0;
}
}

Thanks,
Dave

message Maybe you can use P/Invoke to call CeRunAppAtEvent and listen to the
NOTIFICATION_EVENT_TIME_CHANGE event to do your logging

Hope that helps

"Scott Johnson" <sjohnson_at_softaltern_dot_comDIESPAM> escribió en el
mensaje
 
I guess we both learned something this time. The thing I was doing wrong was
passing the same string to CreateEvent() and CeRunAppAtEvent(). It seems
that CeRunAppAtEvent() requires the "\\\\.\\Notifications\\NamedEvents\\"
prefix before the event name, while CreateEvent() takes only the event name
without specifying a path (if that's the correct term). Once I made that
single change, the original code that I posted worked like a charm on my CE
4.1 device. Just out of curiosity, how did you know that the path is
required for one function, but not the other? I don't think I'd have ever
guessed that one.

Thanks for the help.
Dave
 
It just seemed intuitive based on the note in the help page. It reads:

....
"\\\\.\\Notifications\\NamedEvents\\Event Name"
Event Name represents the application-defined name of the event to signal.
When you use this format for pwszAppName,

....

So I knew that only Event Name was my defined name and assumed the rest was
a constant.
 
Guess I need to hone my intuition. In the mean time, thanks again for
sharing yours.
Dave
 
A question about the notifications.

I've managed to get this code into C# and working, I'm checking for
serial detection, what I want to do now is be notified when the
connection is no longer there.
My aim is to know when I connect to a PC and when I disconnect.

Any help would be great

Thanks
 
You can look for a change of state in one of the handshake signals. I don't
recall which is used by the default serial driver, but that's how it's
detecting a connection for launching of ActiveSync.

Paul T.
 
Paul,

Not sure what handshake signals are, I'm no expert, just trying to put a
little app together.

Any more info so I can do a put more research.


Thanks
 
If you don't know what handshake signals are, you're probably over your
head. What you want to do is check the states of things like RTS, CTS, DTR,
DSR. Which one will work, if any, I don't know.

Paul T.
 
Back
Top