How to keep my WPF C# app running when user cancel the shutdown

156 views Asked by At

I have a C# WPF app which will run as a background process. The purpose of the app is to calculate the break taken by the user. We use lock and consecutive unlock as break. If the break exceeds certain minutes through an UI I will get the reason for the break. The requirement is , it has to keep on running in the background. But it fails in the below scenario:

User clicks shut down but due to some unsaved changes in other apps , say notepad etc., the shutdown is stopped and user cancel the shutdown. Now my app is no longer running.

Below steps I tried but no luck:

1)On SystemEvents_SessionEnding I tried to run a .bat file which will start my app after 5 minutes delay.

  1. Tried the same above logic in a powershell script.

Both are failures. Please help me here.

My Code:

private void Application_Startup(object sender, StartupEventArgs e)
{

    SystemEvents.SessionEnding += SystemEvents_SessionEnding;
    Application.Current.Exit += Application_Exit;
    //and some mutex codes are here
}

private void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
{
    try
    {
        if (e.Reason == SessionEndReasons.Logoff || e.Reason == SessionEndReasons.SystemShutdown)
        {
            if(SharedResource.Instance.IsSystemLocked ==false)
            {
                App_InsertLockDetais(false, null, null);  //Here I do some sqllite local database insert
            }                    
        }

        if(e.Reason == SessionEndReasons.SystemShutdown)
        {
            ReInitiateApp();
        }
    }
    catch (Exception ex)
    {
        ErrorHandler.HandleException(ex, "SystemEvents_SessionEnding");
    }
}

private void ReInitiateApp()
{
    try
    {
        string appPath = AppDomain.CurrentDomain.BaseDirectory;
        string batFilePath = Path.Combine(appPath, "phoenix.bat");

        var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = batFilePath,
                RedirectStandardOutput = true,
                UseShellExecute = false,
                CreateNoWindow = true
            }
        };
        process.Start();
    }
    catch (Exception ex)
    {
        ErrorHandler.HandleException(ex, "ReInitiateApp");
    }
}

private void Application_Exit(object sender, ExitEventArgs e)
{
    SystemEvents.SessionSwitch -= SystemEvents_SessionSwitch;
    SystemEvents.SessionEnding -= SystemEvents_SessionEnding;
    _mutexuser?.ReleaseMutex();
}

My phoenix.bat file

@echo off
timeout /t 600 /nobreak
start "" "C:\ProgramData\MyExeFolder\MyExe.exe"
3

There are 3 answers

3
JonasH On

You should probably split your application in two parts

The part that does all the actual work should run as a service. This makes it run independently of the user session, and immune to things like "cancel shutdown". The service can also be configured to restart the service on failure, or the entire computer if needed.

You can then have a separate UI application to interface and control the service. This application only needs to run when the user actually wants to do something, and can be freely closed without affecting the background work. The user just needs to restart it if it is closed for any reason, just like all other applications.

Use your favorite type of inter process communication protocol to make these two components talk to each other.

This pattern is common for server oriented software, like databases. The actual database runs as a service, with an administration tool that is run as a regular application.

Trying to keep an UI application running after the user or OS has explicitly told it to close can easily become user hostile.

2
Atnap RK On

Instead of creating a background process in a WPF project. Create a service and a GUI to start and stop the process where both project are independent of each other. You can create a windows setup project to install both your service and WFP app for easy installation. I have provided the sample Project Structure with some elaboration.

Service App Project Structure

1
CodeJunkie On

I am going to get hate for this, but your use context sounds awfully suspicious. You have no admin rights, the app runs in the background and it cannot be shutdown by the user. That seems pretty hostile towards the user and could easily be used for malicious purposes (keyloggers etc...)