Is there an easy way to get notified when user presses Power Off button on it's Windows Mobile device? Using C# of course.
Thanks!
When the power button is pressed, the power manager will send out a notification of a state change. You can request that the PM send you a notification by calling RequestPowerNotifications You have to send in a handle to a point-to-point messgae queue (managed version here) that will get the notification.
For thos who don't want to write all of the glue to make this work, all of this is already pre-done for you in the SDF's PowerManagement class.
Also be forewarned that just becasue you request the notification does not mean that your app will get the notification before the state change occurs. For example on pwer down it's pretty common that an app won't see the notification, and almost certain that even if you do see it you won't have time to execute anything before suspend actually occurs. Typically your handler will run when the device resumes (followed by any handler for the resume state).
The power manager doesn't wait for you, it simply broadcasts a message. You cannot use this to run code before a shutdown.
I just place CreateMsgQueue() into the XIP RPM binaries, without need for source code or OEM help. you need to use a hex editor and a few tools from XDA forums.
<DllImport("coredll.dll", SetLastError:=True)> _
Public Shared Function CreateMsgQueue(ByVal lpszName As String, ByVal lpOptions As MsgQueueOptions) As IntPtr
End Function
also you should just create a simple driver for blocking the power down event, your driver is allowed to hold up the power down process in the PowerDown device Event. that way you get a guaranteed event that you can set the flag and stop your background running process, and store any variables, and then restore them on ther PowerUp event, which is also a standard evc++ event for winCE device driver. Pretty simple really. there is 100s of demo source code on the internet for this, I've seen it on 100s of sites.
Unfortunately, on the Windows CE 6 device i am using, CreateMsgQueue does not exist in CoreDll. Any other suggestions?
The only thing i can think of is continually checking Environment.TickCount against the device's real time clock. If time has moved forward but not the tick count, then presumably the device was sleeping.
Dont like this solution because it will get tricked if the time jumps due to a failure in the device's real time clock
Related
I decided to run a test on the XCode iOS simulator to see if an observer to a location in the Firebase database would continue to fire even when the app is in the background. Turns out it does, but I am wondering if this is indefinite until the app terminates or if it will actually stop after some time. It's been a very long time and the observers still fires whenever I manually update the value in the database that the observer is looking at. Also note that I don't have any background modes enabled in my app's capabilities, so it seems that the observer can persist in background mode despite no explicit background modes of any kind.
On the one hand I am very glad that the observer stays on in background as this is helpful to me, but I am a bit anxious to know why this is allowed to happen as iPhone is generally quite conservative by default when it comes to doing stuff in the background.
While the listener may stay active in your single test case, you should not rely on Firebase Database listeners for background data delivery.
The listener stays active as long as the connection stays open. It is up to the operating system to determine when it closes the connection. There is a good chance that the iOS emulator has different behavior in this case than a physical device would have.
I'm working on a kiosk style application where I need to control the shutdown/restart of the PC when the power button is pressed. Thanks to this post, I'm about 90% of the way there.
In control panel set the acpi power button press action to shutdown.
Listen for the WndProc message WM_QUERYENDSESSION
When received issue the completely undocumented:
[DllImport("user32.dll", SetLastError = true)]
static extern int CancelShutdown();
Return from the WndProc and bring up my own message box asking the user to Shutdown / Restart or Cancel, and respond to their action.
Everything works well if I do a start / shutdown from the task bar (I can issue theses as fast as I want). Everything also works well the first time I press the power button. On subsequent power button presses though I see a minute or so delay before I receive the WM_QUERYENDSESSION message.
Is there a setting or registry entry about how often windows will issue an ACPI event? I know it's not the hardware because under linux the same machine will fire the ACPI event as fast as I can press the button.
Thanks.
Calling in some favors at work, I was able to take this question directly to Microsoft support. On my third support engineer, I was essentially told this is not possible at an application level. It was his belief that calling the undocumented CancelShutdown() "confuses" the power manager or acpi driver which leads to the WM_QUERYENDSESSION message delay. Since the CancelShutdown() is undocumented, MS is not willing investigate further.
So, how do you hook power button presses? You need to write a device driver, specifically an ACPI Filter Driver. We are investigating this now.
I don't think it is possible unless you speak with your hardware manufacturer or hardwire the start-button so that it doesn't send a signal to the hardware which handles this.
You can only delay it but even that would not give you 100% guarantee I guess.
Windows 8.1 will (maybe) bring a Kiosk Mode. Maybe that is what you are looking for ;-)
I want to create something like a client in c#.
But I do not know that how I can learn computer status like sleep mode, off, logged in or logged out.
Also, I need to get the warning if the user haven't used the computer for 10 minutes.
You can find information about currently logged user and how to hook the Locked/Unlocked events in this thread.
There are some other different approaches you might try:
You can use the System.Diagnostics and get the process list via Processes.GetProcesses(). Just keep an eye on the Idle process -- if it runs for more than 50% CPU longer than 10 mins the user seems to be idling too.
You can use Performance Counters to monitor the activity taking place on the computer and make certain decisions.
You can also use the WMI service with similar purposes.
Partial answer:
User activity/inactivity can be monitored using hooks. Start a timer with a 10-minute interval. Whenever you detect a keyboard/mouse message, restart it. If the timer event happens, than you detected 10 minutes of inactivity.
I'm working on writing an application that straddles the line between C# and C/++ on Windows Mobile 6.1/6.5. We currently have a kiosk application running on our devices, and would like to add the ability to switch back and forth to a second kiosk application.
Our goal is to establish a global hot key that switches process windows (similar to the way that alt+tab works) whenever it is pressed. We already have both applications and I've written some code that switches the processes, but am having a rough time getting the global hot key portion of the project working.
From all of the reading that I've done, my understanding is that the best way to monitor global key presses is to link into the system message pump with the SetWindowsHookEx function in coredll.dll. Unfortunately, I've also read that this function isn't technically supported on the platform.
I also found some tutorials that suggested using a message map with the ON_WM_KEYUP/ON_WM_KEYDOWN macros in the MFC framework, but couldn't find any documentation specific to Windows Mobile. When I tried to use the documentation here, my device kept crashing.
Is there an accepted best practice for setting some kind of global key hook on the platform? If not, is there something that's at least technically supported?
Thanks in advance.
ReplyQuote
Why not use a RegisterHotKey call and use that to swap applications? IIRC the hardware buttons typically map to key codes starting at 0xC1 (193).
We actually ended up polling the GetAsyncKeyState function in coredll.dll on a separate thread. The thread monitors a specific key, and throws an event whenever it is pressed.
Because the event is executed on the key polling thread, you have to be sure to use a delegate to invoke its handler on the GUI thread when the event is thrown.
I would go for a keyboard hook, but only if RegisterHotKey didn't work for your particular scenario.
From all of the reading that I've done, my understanding is that the best way to monitor global key presses is to link into the system message pump with the SetWindowsHookEx function in coredll.dll. Unfortunately, I've also read that this function isn't technically supported on the platform.
Not technically supported, is correct in theory, but I've not seen a WM 6.5.* device that hasn't supported it in reality. Keyboard hooking is such an important feature of vertical market custom rugged WM device apps that it I think it just cannot be removed, for backwards compatibilty.
The enterprise side of the WM space is too important.
I am using the Windows Update API to update a bunch of VM's. With Windows Update comes the inevitable reboots. Can anyone think of a way that I could tell from a remote server if the windows box has indeed finished its reboot? All ideas or thoughts would appreciated.
EDIT:
Because the VM's are in Lab Manager and using a fenced configuration, WMI will not work, and although I thought about using the VM to send a signal when it was back up. There would have been no way to reliably know who to notify as the app waiting for the machine could be on any number of machines so it just didn't seem reasonable. However time is not essential (and even though I know this will bite me sometime when a Service Pack comes down) I have had good success with the PING and then wait 5 minutes so far, so I am going to use that for now. If I run into exceptions I will then try to implement the VM notfiying the world when it comes back up. Thanks to all.
Just wait for it to respond to a ping.
In light of your comments:
1 - Use this script
2 - If you get any errors with that script, follow these instructions.
Check for this event in the event log:
Event Type: Information
Event Source: EventLog
Event Category: None
Event ID: 6005
Date: 7/27/2007
Time: 12:56:24 PM
User: N/A
Computer: IWSDEV
Description:
The Event log service was started.
A more general version of this question is How do I know if a system has powered on?
The reality is that you can't know when it is done booting. The boot process is pretty asynchronous and so whatever criteria you use to determine that it is done "booting" could happen before something else completes.
What I would recommend is determine what you actually want to know. What specifically is it you are waiting for? Find a way to determine whether this has taken place and forget worrying about "booting".
If you just need to know that the machine is back up but maybe hasn't completed all of the post-boot loading, put something in the startup sequence or a service that signals your code. When this signal takes place, take whatever action you need to.
You could install a startup program or service on the machine to send an email or some type of network based posting everytime it restarts.
Windows is done rebooting only slightly before it'll need rebooting again :-)
If you're specifically looking to query the status of VMs then you should check out these links which deal with the API for Virtual Server 2005:
The IVMVirtualMachine Interface...
http://msdn.microsoft.com/en-us/library/aa368465(VS.85).aspx
... has a property called State...
IVMVirtualMachine::State Property
http://msdn.microsoft.com/en-us/library/aa368637(VS.85).aspx
... which will return a value from the VMVMState Enumeration...
http://msdn.microsoft.com/en-us/library/aa368922(VS.85).aspx
At a more general level, you should probably define how much of Windows you want up and running. Do you consider network stack ready to be "rebooted" or do you need IIS/SQL or some other application level service up?
I'd probably write an app that checks the "heart-beat" of your servers - that app could well be the same one that's invoking the Windows Update stuff. You'd then get yourself a nice "console" showing you the status of your servers. The heart-beat app could ping a server, hit a static html page, hit the remote event log, use WMI or whatever you define as enough to consider your server rebooted.