i have the following problem. When the user closes the Windows store app, i want a text file with data to be saved.
What method should i write so that when closing the app a file gets saved ?
This article describes the application lifecycle of a Windows Store App.
If you look at the very first figure, you can see that there are only 3 events related to application lifecycle:
Activated - Raised when program first starts
Suspended - Raised when program is suspended (i.e. the user returns to the Start Screen or another app)
Resuming - Raised when the program is awakened from its suspended state.
The fourth transition - the one to the "Not Running" state - has no such notification event. The reason is: you don't really know when the app will fully close. Nor should you - Microsoft wants you to perform all of your state-saving logic in the transition from "Running" to "Suspended." In this way, they can free up resources when they deem necessary.
Even if the user forces the program to terminate (by right-clicking it and selecting "Close" from the task menu), you will enter the "Suspended" state for exactly 10 seconds before the program is terminated. So you can rest easy that your state-saving logic will always be executed.
you don't really know when the app will fully close. Nor should you...
I don't agree with this - Microsoft are copying this from Apple, and I don't know why, I never liked Apple's implementation either.
If your user makes changes to your App, then closes it using the keyboard or gesture, then restarts it say after 6 seconds, all changes are lost.
I don't see any way as a developer to get around this. Whoever decided that closed events (and exit buttons for that matter) are evil is an idiot.
Related
I want to log if a customer tries to force close the application. I'm aware of having no chance to catch a process kill. But it should be possible through the main form closing event to get informed about the 'CloseReason.TaskManagerClosing' reason.
But any tests I did under Windows 8.1 I always got a CloseReason.UserClosing reason. But in this case (compared to a normals CloseReason.UserClosing) I've about 0.2s to run user code afterwards my program is killed!
Is this a new behavior in Windows 8.1?
Yes, I see this. And yes, this is a Windows change, previous versions of Task Manager sent the window the WM_CLOSE notification directly. I now see it issue the exact same command that's issued when you close the window with the Close button (WM_SYSCOMMAND, SC_CLOSE). Or press Alt+F4 or use the system menu. So Winforms can no longer tell the difference between the Task Manager and the user closing the window and you do get CloseReason.UserClosing.
What happens next is expected, if you don't respond to the close command quickly enough then Task Manager summarily assassinates your program with TerminateProcess().
Do keep in mind that trying to save data when the user aborts your program through Task Manager is a bad practice. Your user will normally use this if your program is malfunctioning, you can't really trust the data anymore and you risk writing garbage. This is now compounded by your saving code being aborted, high odds for a partially written file or dbase data that isn't usable anymore.
There is no simple workaround for this, the odds that Windows is going to be patched to restore old behavior are very close to zero. It is very important that you save your data in a transactional way so you don't destroy valuable data if the saving code is aborted. Use File.Replace() for file data, use a dbase transaction for dbase writes.
An imperfect way to detect this condition is by using the Form.Deactivate and Activate events. If you saw the Deactivate event and the FormClosing event fires then reasonable odds that another program is terminating yours.
But the normal way you deal with this is the common one, if the user ends the program without saving data then you display a dialog that asks whether to save data. Task Manager ensures that this doesn't go further than that.
Another solution for determining when the Task Manager is closing the program is by checking if the main form, or any of its controls, has focus. When you close via the Task Manager, the application is not focused, whereas if you close via the close button or Alt+F4, the application does have focus. I used a simple if check:
private void MyForm_Closing(object sender, FormClosingEventArgs e)
{
if (this.ContainsFocus)
{
// Put user close code here
}
}
I want to get event when windows store app is closing or page is closing same way as we get "Closing" event in Desktop application.
Can anybody suggest me?
Try this:- https://msdn.microsoft.com/en-us/library/windows/apps/hh986968.aspx
refer:- How to save data on Windows Store App Close?
If you look at the very first figure, you can see that there are only 3 events related to application lifecycle:
Activated - Raised when program first starts
Suspended - Raised when program is suspended (i.e. the user returns to the Start Screen or another app)
Resuming - Raised when the program is awakened from its suspended state.
The fourth transition - the one to the "Not Running" state - has no such notification event. The reason is: you don't really know when the app will fully close. Nor should you - Microsoft wants you to perform all of your state-saving logic in the transition from "Running" to "Suspended." In this way, they can free up resources when they deem necessary.
Even if the user forces the program to terminate (by right-clicking it and selecting "Close" from the task menu), you will enter the "Suspended" state for exactly 10 seconds before the program is terminated. So you can rest easy that your state-saving logic will always be executed.
I'm working with background tasks.
If I press the home button once the app will call DidEnterBackground and I can run anything here - Ok
If I press the home button twice and swipe the application out of the screen, finalizing it, WillTerminate will be called and after that, the app DIED, I can't do anything more.
On the Android I can do it and keep the app running, without show it on the android's app switcher.
There's a way to do it?
And how I re-open the app every time I kill the app (Every time WillTerminate is called).
You cannot avoid the kill by the user. Apple philosophy is that the user is the "commander-in-chief" and he can decide to kill your app when he wants (and the kill must be real, no hidden processes).
All background tasks of the app will terminate with it and you cannot reverse the user decision (i.e. restarting automatically).
I don't see simple solution for your problem. The only thing that I can think is to put a big alert message to the user, when a specific task begins, saying:
"don't kill this app from the switcher while this operation is running ..."
or, save the state of the background process and restart it at the next run of the app.
Some explanation: for a project I'm working on I have to write a program that is running in the background, detects changes to files, and uploads the modified files to a web service to make it available to others. Quite simple synchronization if it were not for the case when a user modifies a big file and decides to shutdown its computer right after the edit.
I could cancel the upload and wait for the next reboot to do the upload, but I can imagine the user downloading the file from the web to another computer the next morning and don't understanding why his changes from last night aren't there.
So my idea was to detect when the users logs off or reboots Windows, and if I'm in the middle of an upload, just asking the user "We're still synchronizing file Foo.txt that you just changed. Are you sure you want to reboot ? You're changes won't be available to others until you restart your computer !". If the users says no, I'd need to cancel the reboot/loging off
Is this possible?
There is a static class called SystemEvents that exposes this behaviour:
http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.aspx
However, it cannot differentiate between certain actions and doesn't pause the OS process time-out guard. I used it once, but the default time-out as configured in the registry is a little short so will likely need increasing.
To cut a long story short, it all felt a little hackish.
To add to #Adam's answer, if you need to tell the difference between logoff and shutdown/reboot, you can handle the WM_QUERYENDSESSION message.
"Shutdown Changes for Windows Vista" is a useful article for understanding the shutdown timeout.
Trying to block a shutdown is a lossy proposition these days, it's no longer possible to do so in Vista and up. A prompt isn't readable nor reachable. Using a service is highly indicated here, lets you survive a user log-off. And a reboot, your service will start running again automatically, letting you complete the job.
I've got an application (that is targetting .Net Framework 2.0) that is running on startup of the System, and I'm trying to get a NotifyIcon to display.
When my program starts up when a user either Runs it normally or is started as a child process after the system has already logged on everything is fine.
If my application starts up as the system is performing an AutoLogon using POSReady2009 (basically XP with Single User set). Then the NotifyIcon never becomes active.
If you subsequently check (in a timer) the .Visible of the Icon at any point later it always reports that it is visible = true.
If you disable the SSDPSrv and restart the Computer, the Icon displays correctly.
I have a sneaking suspicion this is related to .Net 3.5sp1 installed over the top of a .Net 2 system.
Is there some process that I should be following to ensure that my NotifyIcon is always available to the user.
I have setup RegisterWindowMessage("TaskbarCreated") but I don't get this message called, except when you forcilbly Kill Explorer.exe and restart it. Even so, a NotifyIcon interally registers for these notifications anyway, so it shouldn't be required.
I'm happy to stall the startup of my program, but once the program starts up, I expect that the icon shows correctly.
If there is a KB article that I cannot find detailing this I'd be happy with that too.
Hmm... that's odd.
This may not work, and it's possibly not the best way of doing it - but first of all try putting NotifyIcon1.Visible = True in the Load event.
If that isn't working why not try adding this into a timer...
NotifyIcon1.Visible = False
NotifyIcon1.Visible = True
This should then hide and show the icon everytime the timer ticks, at least then you can see if it's working. Maybe only run the timer 10 times and then it ends, that way the script should hide and show the icon 10 times by which time the system should be ready.
Let me know if this works - if not I'll have a scratchy beard moment and have another think!
Well it's kinda dumb but have endedup needing to modify the process of startup to deal with this issue.
Made the program it's own shortcut that get's placed into the Startup folder by our installer.
The program that triggers this no longer starts it automatically. Instead we inform the other program once we have started up (Dropping a trigger file).
The other program then monitors if the user closes us OR we just crash and automatically re-opens the program. [There is a proper process to follow if you wish to fully close down the system]
Inside the startup of the program we check to see if the SSDP service is available and Not set to Disabled.. if so, wait until this service has started. We then check that SQLServer is running.
We then prepare the NotifyIcon and set it's .visible= true and all is good.
Still have kept the RegisterWindowMessage in the event the user somehow kills windows explorer.