How can I handle console closing in a Windows CE? - windows

I have a Win32 C++ console application running in Window CE 6.0 that contains a number of continuously running threads. Occasionally there is a need to stop the application, and I would like that to happen in a controlled manner. One method of doing this would be to simply monitor the console window, and if it closes then stop the process. Unfortunately SetConsoleCtrlHandler does not appear to be part of the Win32 api for Windows CE 6.0. Does anyone know how I can detect that the console is closing in a Win32 C++ program running in CE?
Thanks,

You can watch for Ctrl-C by calling DeviceIoControl with IOCTL_CONSOLE_SETCONTROLCHANDLER. Use _fileno(stdout) for the hDevice parameter.
I don't think there's any way to get notified for any other "close" mechanism.

I got this working on Windows Embedded Compact 7. The Ctrl+C and the "window closed" events are both catched.
Create a Win32 event.
Pass that event to DeviceIoControl() using the IOCTL_CONSOLE_SETCONTROLCEVENT, and given the console handle (e.g., _fileno(stdout)). That event will be signaled when Ctrl+C is typed, or the console window is closed.
Create a thread that waits on the Win32 event becoming signaled, and when it becomes so, calls your Ctrl+C handler or performs your cleanup, and probably exits the program.
Notice that IOCTL_CONSOLE_SETCONTROLCHANDLER has been deprecated and DeviceIoControl() fails when it is given that IOCTL code.

Related

How to trigger windows error recovery for sure?

I have a Windows application where I have registered a callback using the RegisterApplicationRecoveryCallback() function.
I want to trigger my callback and test if it is actually being hit or not.
I have tried to generate an infinite loop in main() but the Windows Recovery dialog doesn't come up.
I know causing a segmentation fault or other related error would trigger it, but I can't trigger a segmentation fault as all of such things are handled by a seperate process which catches all crashes.
I tried an infinite loop using for(;;), but the application just freezes and WER is not triggering. I was expecting to trigger the Windows Recovery dialog.
As #RaymondChen said, it's hard to define unresponsive for console applications but for GUI applications. I can build the recovery scenario for infinite loop using Registering for Application Recovery sample.

Does command line windows restart gracefully exit running app

Platform: Windows 2008 server
Ran into a problem where my one-file exe generated with pyinstaller would not clear its associated temporary folder. Read up about this http://pythonhosted.org/PyInstaller/ and found out if the exe doesn't close gracefully it would not delete its associated temporary folder. After this I spoke to the IT guys who setup the exe and was told that the app is started on system start-up and every night a system reboot occurs.
I tried finding out if the system restart on windows would gracefully exit running applications, but couldn't find anything regarding this.
Does anyone know if windows gracefully exits running apps with a scheduled system restart?
Thanks in advance
Yes, it does, but implementation slightly differs between XP\Vista. You can also change shutdown timer and auto-close behaviour: How to Specify WaitToKillAppTimeout to Speed Up Shut Down Time in Windows.
In Windows XP:
In Windows XP, each running application is sent the WM_QUERYENDSESSION
message at shutdown. Applications can return TRUE to indicate that
they can be closed, or FALSE to indicate that they should not be
closed (e.g., because doing so would cause the user to lose data or
destroy a CD being burned). If an application returns FALSE, in most
cases, shutdown will be cancelled (and the application that cancelled
shutdown is sent WM_ENDSESSION with wParam == FALSE).
Applications can also delay responding to WM_QUERYENDSESSION in order
to display UI asking what the user would like to do. For example, when
Notepad has unsaved data and displays a "Would you like to save your
data?" dialog during shutdown, this is what it is doing. By default,
applications can delay responding to WM_QUERYENDSESSION for up to 5
seconds. After 5 seconds, Windows XP will display a dialog that
indicates that the application is not responding and allows the user
to terminate it. Until the user responds to this dialog, applications
can block WM_QUERYENDSESSION (and, consequently, shutdown)
indefinitely.
In Windows Vista
Ability for users to forcefully shut down
In Windows XP, the UI for
blocking applications allows users to either cancel shutdown or
terminate the blocking application. If subsequent applications also
block shutdown, the system displays identical UI for each blocking
application. This is frustrating for many users, who, when shutting
down, "just want" their computers to turn off. Windows Vista will
solve this by allowing users to terminate the blocking application and
make shutdown "forceful." In a forceful shutdown, Windows will send
applications WM_QUERYENDSESSION with the ENDSESSION_CRITICAL flag. If
an application responds FALSE, Windows will continue shutdown instead
of canceling it, and will send the application WM_ENDSESSION. If an
application times out responding to WM_QUERYENDSESSION or
WM_ENDSESSION, Windows will terminate it.
Silent shutdown cancellations will no longer be allowed
In Windows XP,
applications are allowed to veto WM_QUERYENDSESSION without displaying
any UI indicating why they need to cancel shutdown. These "silent
shutdown failures" are highly frustrating to users, who often take a
minute or two to realize that shutdown has failed because no UI was
displayed. Windows Vista will eliminate this possibility by displaying
UI even if an application vetoes WM_QUERYENDSESSION.
Certain types of applications will no longer be allowed to block
shutdown. At shutdown, Windows Vista will check whether each running
application is not responding (an application is defined as not
responding if it has not responded to any of its window messages in
the last 5 seconds), and, if so, automatically terminate it.
Windows Vista will also not allow console applications or applications
that have no visible top-level windows to block shutdown. In most
cases, such applications are less important to users at shutdown than
applications that do have visible top-level windows. If an application
without a visible top-level window blocks shutdown by vetoing
WM_QUERYENDSESSION, or takes over 5 seconds to respond to
WM_QUERYENDSESSION or WM_ENDSESSION, Windows will automatically
terminate it.
However, if an application with no visible top-level windows uses the
new API to proactively indicate that it needs to block shutdown,
Windows Vista will not automatically terminate it, and will instead
treat it like an application that does have a visible top-level
window.

How can I automatically catch and restart a crashed process on Windows?

This might be silly. When my process crashes, a WerFault.exe has been launched and I can regain control only after I close this window or kill its task.
I'm looking for a simple way of not letting crashed program show this window or any idea for me to catch this crash.
SEH is not useful, by the way. I'm not sure why. The crash also remains when I use SEH.
Thanks!
Now I'm just figuring out how to avoid this WerFault.exe windows and sometimes csrss.exe window and regain control.
Use the Application Recovery and Restart API to have Windows Error Reporting (WER) restart and recover your app when it crashes. Use RegisterApplicationRestart() to register your intent to be restarted. Use RegisterApplicationRecoveryCallback() to register your intent to save and recover state data.
I have not tried this but this api : WerAddExcludedApplication should disable error raporting: http://msdn.microsoft.com/en-us/library/bb513617%28v=VS.85%29.aspx
As for restarting your app, you could create another background process that will start your main process and monitor how it behaves. If it crashes then restart it.
[edit]
unfortunately this api might not work, as suggested in comments to it - to remove this dialog your will have to FindWindow() and SendMessage(... WM_CLOSE...).

Windows Explorer does not receive WM_DESTROY. How can I detect when the user closes their explorer window?

I'm writing a program which needs to detect when windows are closed. Currently I am using SetWindowsHookEx to register a hook which can monitor window messages.
I am monitoring for WM_DESTROY events to find out when windows have been destroyed. This works fine for most windows with Windows Explorer being a notable exception. Windows Explorer does not appear to receive a WM_DESTROY event when it terminates (but receives most other interesting events).
Is there a reason why Windows Explorer does not receive WM_DESTROY?
More importantly, is there a alternate method I can use to detect when Windows Explorer terminates other than listening for WM_DESTROY?
Thanks!
I am using Windows 7 (not sure how relevant this information is)
Use a WH_CBT hook instead of a message hook, and have it handle HCBT_DESTROYWND notifications.

Request suspend on Vista but allow other applications to cancel

My application uses the Win32 SetSuspendState() API to trigger system suspend or hibernation when it has finished doing a lengthy task.
The API accepts a parameter "ForceCritical" which determines whether or not the system suspends immediately or whether it broadcasts PBT_APMQUERYSUSPEND first to allow other apps the chance to cancel the suspend. My app uses this to play nicely with other apps like Media Player, so it doesn't suspend if you're listening to music or something.
For some reason, starting with Vista, MS have changed things so this parameter is ignored so SetSuspendState immediately causes a suspend and other applications have no opportunity to stop it.
Does anyone know how I can get the desired "polite" behaviour back again on Vista?
MSDN says
To prevent the system from transitioning to a low-power state in Windows Vista, an application must call SetThreadExecutionState to inform the system that it is in use
I would guess that WMP does this, but older apps don't. You could probably emulate this by sending the WM_POWERBROADCAST:PBT_APMQUERYSUSPEND message to all top level windows and check their return values (Send the message with a timeout so a hung app does not hang your app)

Resources