In my windows phone7(Silverlight) Application I have to display a message box asking, the user to confirm(Yes/No) before exit from the application [on device back button click].
The problem is I have to use a custom messagebox(using a popup) to get user confirmation, and I have no way to get exit from the application.(No method found which will exit the application like dispose() or close()).
if I didn't have to use a custom messagebox, the on the Device back key press event "OnBackKeyPress" I would have use the following logic and done my work
MessageBoxResult res = MessageBox.Show("Do you want to Exit?", "Exit", MessageBoxButton.OKCancel);
if (res == MessageBoxResult.OK)
{
if (NavigationService.CanGoBack)
{
while (NavigationService.RemoveBackEntry() != null)
{
NavigationService.RemoveBackEntry();
}
}
}
else
{
e.Cancel = true;
}
The problem is I need to use the custom messagebox and done this work. Same problem arise if need to implement a button to exit the application with out using the device back button.
I found in several posts suggesting to throw an exception and make this done. Following are some of them
http://mobile.dzone.com/articles/windows-phone-mango-sample-3
http://imaginativeuniversal.com/blog/post/2010/08/22/How-to-Quit-a-WP7-Silverlight-Application.aspx
I don't think that this is a good practice and also not sure if the windows market place will certify this way. Would like to hear the thoughts of once who have experienced this issue, and any suggestion to Achieve this(Terminate the application). Thanks inadvance....!!!!
If you want to submit to the Marketplace you've got a couple of problems because of the following certification requirements:
5.2.4.2 Pressing the Back button from the first screen of an application must close the application.
5.2.2 A Windows Phone application is closed and terminated by the OS when the user navigates away from the application. When an application is started after being closed, its launch time must meet the requirements in Section 5.2.1 – Launch Time
5.2.3 A Windows Phone application is deactivated when the user presses the Start button or if the device timeout causes the lock screen to engage. A Windows Phone application is also deactivated with it invokes a Launcher or Chooser API.
This is a couple instances where you simply can't display a message box.
And technically using an exception to termniate the app is a violation:
5.1.2 The application must handle exceptions raised by the .NET Framework and not close unexpectedly. During the certification process, the application is monitored for unexpected closure. An application that closes unexpectedly fails certification. The application must continue to run and remain responsive to user input after the exception is handled.
As a developer, part of your job is communicating to users about requirements that are unrealistic or unreasonable.
Sorry, no way to do this. Before mango update you could Clear the back stack, then programmatically trigger the Back button. but as of SDK 7.1 (wp7.5) we can no longer do this.
My recommendation is to create a custom Exception type ApplicationXExitException and throw that to exit the app. The reason for the custom type is so that when you pull your exception logs from the marketplace, you'll know the ones that were indeed unintended exceptions crashing the app, vs your exception to intentionally exit the app.
You can hook an event raising after your custom messagebox closes. Event arguments will keep information about user's choice. Depending on that you will decide whether to exit app or not.
Related
Looking for some feature that can make my app start up even fast, I found the prelaunch feature in the Microsoft documentation that would help open the app faster. But even if I register the app to enable prelaunch, the OnLaunched event keeps getting false in e.PrelaunchActivated.
(I only could test this feature using the VS option 'Debug UWP Prelaunch' in debug mode).
Do I need a Microsoft certificate to use it?
How long does the OS take to understand that my app is eligible to prelaunch?
Does this influence the fact that I'm getting false at the event?
I made a test and the prelaunch works correctly. I'll post my code here and explain how the prelaunch works. Hope it will help you solve your question.
Here is the sample code that I used:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
bool canEnablePrelaunch = Windows.Foundation.Metadata.ApiInformation.IsMethodPresent("Windows.ApplicationModel.Core.CoreApplication", "EnablePrelaunch");
// ********
// some other code here
// *********
//check if it is prelaunched
if (e.PrelaunchActivated == false)
{
// On Windows 10 version 1607 or later, this code signals that this app wants to participate in prelaunch
if (canEnablePrelaunch)
{
TryEnablePrelaunch();
}
// ******
// normal code
// ******
}
else
{
//prelaunched
// do some logic that don't require UI thread.
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), "PreLaunched");
}
// Ensure the current window is active
Window.Current.Activate();
}
}
As you could see, I add an else sentence to do the work when the app is prelaunched.
When testing via the Debug Universal Windows App Prelaunch mode in Visual Studio, the whole process should be like:
Choose the Debug Universal Windows App Prelaunch mode, then the app will be prelaunched.
The OnLaunched event will be fired and you will go into the else sentence because it is prelaunched.
You could do your work in the OnLaunched event for prelaunched
Then the app will go to suspend status.
Now, the user launches the app from Start Menu.
The OnLaunched event will be fired again and this time it will show e.PrelaunchActivated == false because it is launched by the user, it is not prelaunched. I suspect this is the behavior that you are getting.
So this is the whole process about how the prelaunch works. This is also mentioned here: App launch.
In my case, Windows does not use Prelaunch when app is deployed by Visual Studio, but after installing it from the Store it works as expected. User must run an app at least one time and next time you will see it in the Task Manager. Will it work or not, depends on the amount of available memory, but I found it working even on a device with 4Gb of RAM.
Keep in mind, this is a Console App running .NET with C#. Also, I might later convert this into a service, but for now, I need to handle the shutdown while my Console App is running.
My system sometimes gets shutdown automagically by Windows Updates or by Kace Updates. This is irritating when my program is in the middle of doing long tests in the middle of the night and I'm not there to see it happen. I would like to be able to detect the system shutting down and delay it long enough for my tests to finish gracefully and allow me to gracefully exit my program keeping all my test data intact.
I've looked at various threads and can't seem to find a working solution. I've tried both of these:
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
Application.ApplicationExit += OnApplicationExit;
But neither of these events seem to get fired. I basically want to send an e-mail notification to myself when the shutdown is detected and pause the shutdown. Or at least log a message somehow...
I can simulate this behavior using (of all things) 'notepad.exe'. I just open notepad.exe, type some junk, and then attempt to ShutDown my computer. The computer tries to shutdown, and then shows a message that says it cannot shut down because 'notepad' is blocking it.
I would like MY program to block the shutdown (or at least delay it) the same way as 'notepad.exe' does it.
Any information, events, or other ideas that you may have would be very useful. Thanks in advance for your assistance.
This can help you:
https://www.meziantou.net/prevent-windows-shutdown-or-session-ending-in-dotnet.htm
When the user logs off or when he stops his machine, Windows quits all open applications. Some applications want to execute code before ending in order not to lose the current state (a document being written for example).
For this Windows sends a message to all applications:
WM_QUERYENDSESSION when closing the session
WM_ENDSESSION when shutting down the machine
Windows provides 3 methods:
ShutdownBlockReasonCreate
Indicates that the system cannot be shut down and sets a reason string to be displayed to the user if system shutdown is initiated ("I want to live" in the screenshot)
ShutdownBlockReasonDestroy
Indicates that the system can be shut down
SetProcessShutdownParameters
This function sets a shutdown order for a process relative to the other processes in the system
The final method determines the order in which Windows sends the WM_ENDSESSION and WM_QUERYENDSESSION messages to the applications. This is used in the case where an application A depends on an application B. The application A wishes to be informed before the application B that the machine is stopping to potentially block this stop. Thus application B remains alive as application A blocks the shutdown.
The priority is defined with an integer between 0 and 0x4FF. 0x4FF is the highest priority (called first), 0 is the lowest priority (last called). By default, applications have priority 280.
In the link there is also a code for WinForm that can be adapted.
Something like:
private const int WM_QUERYENDSESSION=0x0011;
private bool isShuttingDown=false;
protected override void WndProc(ref Message m)
{
if(m.Msg==WM_QUERYENDSESSION)
{
isShuttingDown=true;
}
base.WndProc(ref m);
}
As part of some work I need to get done for Windows 10, I have written a code in C# that essentially detects every minute whether a PC is in screen saver mode or not, and it writes to a table in MySQL the relevant status ("PC in use" if the screen saver is off, "available PC" if the screen saver is on).
I did this using (full link if required - https://www.codeproject.com/Articles/17067/Controlling-The-Screen-Saver-With-C):
// Returns TRUE if the screen saver is actually running
public static bool GetScreenSaverRunning( )
{
bool isRunning = false;
SystemParametersInfo( SPI_GETSCREENSAVERRUNNING, 0,
ref isRunning, 0 );
return isRunning;
}
The code works flawlessly in console application mode (I made a loop to test it out over a minute with a check up on screen save status every 10 seconds), this means in MySQL the status was set correctly every time, depending on the screen save status at the moment of the check up.
The problem occurs when I use this code for a windows service. The service is installed correctly, the log on tab is set on Local System (I also tried with the logged in user instead, same results) and I allow the service to interact with the desktop, just in case, but the difference here is that no matter if the PC enters screen save or not, it always returns false on GetScreenSaverRunning(), thus setting the status of the PC in MySQL as "PC in use", even if the screen saver is on at the moment of check up.
I get the sense that the problem isn't in the code itself, since it works without any issues as a console application, but perhaps something behind the scenes. I tried to search here and on many other websites, haven't found anything related to such a problem.
Does anyone have any idea at all what might be the issue? Any help and/or suggestions will be greatly appreciated!
Thank you in advance.
(I could post the code if required, but it is pretty much straight forward and the main part of it, controlling the screen save detection, is taken from the website mentioned above, afterwards it's a simple if (GetScreenSaverRunning() == true) )
Ever since Vista, Services are barred from a Interactive Session. Even if they run under the same rights, they do not get a interactive Session. I would guess that is getting in the way here.
While you can overwrite this behavior in the Service settings, this is not adviseable for new code. Consider making this a Background Task started by the Task Sheduler instead.
Because the windows service runs in different session then the windows logon. You can't interact with the desktop related services unless you run the windows service in win logon session. There used to be an option in Windows service manager where you can set the properties to "Interact with desktop session" but I don't think that ever worked.
There's a work around to run the windows service using the win logo session.
See this helper class that can get the current logged on user session and interact with the desktop services. https://github.com/murrayju/CreateProcessAsUser/blob/master/ProcessExtensions/ProcessExtensions.cs
My apologies if this question has been asked and already answered, I have spent the best part of three days experimenting with WndProc() in WinPE (for Windows 10).
How do I "Catch" Messages through WndProc() (or a Handler Routine) in WinPE (Windows 10)?
I have a custom application(written in C# .Net 4.5.2) that is launched by WinPEShl.exe, on boot of WinPE. This is currently an Application that provides access to other applications to enable Windows deployment or Image Capture.
While this Application may not always be the current Windows Form, there a one or two routines that need to be completed before Windows PE has shutdown. I would like this to happen on either the WM_QUERYENDSESSION/WM_ENDSESSION or WTS_SESSION_CHANGE notifications through the overriden WndProc() function.
Currently this is my WndProc() function:
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message m)
{
// Listen for operating system messages.
if (m.Msg == WM_QUERYENDSESSION)
{
Program.WriteLogFile(4, 1, "WM_QUERYENDSISSION: received. Return Bool=True");
}
if (m.Msg == WTS.WM_WTSSESSION_CHANGE)
{
int wValue = m.WParam.ToInt32();
if (wValue == WTS.WTS_SESSION_LOGOFF)
{
//Write my darn Log file!
Program.WriteLogFile(4, 1, "WM_WTS_SESSION_LOGOFF: received. Return Bool=True");
}
if (wValue == WTS.WTS_CONSOLE_DISCONNECT)
{
Program.WriteLogFile(4, 1, "WM_WTS_SESSION_DISCONNECT: received. Return Bool=True");
}
}
base.WndProc(ref m);
}
Program.WriteLogFile() is a Log File writer (as it says!) that will be used to report that the system is shutting down.
From this Link I am aware that as WinPE is a Stream lined version of Windows, with only a small number of API's being available for usage. I have looked through both of the MinCore.lib sets for both Windows API Sets mentioned - resulting in nill success for finding any function in relation to the WndProc() holder function. I have evensearched OneCore.lib aswell.
I did however find the WTSRegiSessionNotifications() functions. Again even though they register fine in WinPE, my Shell App doesn't receive the messages if another application shuts down the system (such as Windows Setup on completion of the first phase).
Testing in Windows provides both results in the associated application log file.
Should I be using a hidden console app, to capture the CTRL_LOGOFF_EVENT/CTRL-SHUTDOWN_EVENT, or should i be using a service (and have all log writing routed through it)?
Log files from Windows 10 (working as should be) and WinPE available on request.
Thanks for any and all help in this matter.
Kind regards
Richie
I'm not sure why you're not using the regular winforms form lifetime events. I'm guessing you're somewhat more used to C-oriented ways of doing things?
If you've built a winpeshl.ini that starts your program, and it's the only program listed (beyond winpeinit.exe), then when it shuts down, PE shuts down. This is true even if you spawn other applications from your main program (via System.Diagnostics.Process).
So, don't list a lot of programs in winpeshl.ini. Let your one-and-only main program start the rest.
FWIW, I've got a similar app...does image capture, deploy and periodic maintenance. We put our winPE in it's own partition and do a lot of active BCD management to make it boot when we want. I've closed off all the "normal" shutdown routes. Yes, I suppose a persistent user can circumvent...but if they're determined, so be it...but we haven't had an issue with that.
In Windows Vista and up, services can no longer access the GUI. However, after writing a simple mechanism to pass messages from my service to a helper GUI application, I found the following overload for System.Windows.Forms.MessageBox.Show, where the "MessageBoxOptions" parameter caught my eye:
public static DialogResult Show(
string text,
string caption,
MessageBoxButtons buttons,
MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton,
MessageBoxOptions options
)
Looking at the enum more closely, one of the valid options is MessageBoxOptions.ServiceNotification, which states on MSDN that:
The message box is displayed on the active desktop. The caller is a
service notifying the user of an event. The function displays a
message box on the current active desktop, even if there is no user
logged on to the computer.
Does this mean that by passing the MessageBox.Show() method this option, my service can actually handle displaying a simple message from the service without having to use a helper application in Vista, Windows 7, and up?
MESSAGEBOXOPTIONS ENUM DEMYSTIFIED - Applicable for XP
Starting with Windows Vista and above, user interfaces generated by Windows services can’t be seen. And even worst, your service could be stuck waiting for some user input that the user cannot give as she does not see anything
From here
To display MessageBox in windows service, you need to send WTSSendMessage message. It will show up DialogBox in Session 0 special desktop.
Yes, what you're proposing will work, but do you really want to do that? Remember that by default MessageBox.Show() is a blocking operation. Generally it's a really bad practice to have services waiting on UI operations.
The answer to your question is: "yes, but please don't."
Your Service can display a MessageBox using Show method only if you have started "Interactive Service Detection" service. To start this Service type "services.msc" in the Run Window.