Prevent C# App from Process Kill

Prevent C# app from process kill

You can't - as long as the user has the right to call TerminateProcess on your program, you can't prevent End Process from killing you immediately in task manager. Raymond Chen posted on this some time ago: The arms race between programs and users

How to avoid force kill to stop a console application?

Based on the many contributions added to this post and also detecting-console-application-exit-in-c i build the following helper, to gracefully stop a console application on taskkill signal but also to stop with any other close controls signals:

public class StopController : Form, IMessageFilter
{
//logger
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
static private CancellationTokenSource cancellationTokenSource;

public StopController(CancellationTokenSource cancellationTokenSource)
{
StopController.cancellationTokenSource = cancellationTokenSource;
System.Windows.Forms.Application.AddMessageFilter(this);
SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);
}

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false;
}
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == 16)
{
log.Warn("Receiveing WF_Close event. Cancel was fired.");
cancellationTokenSource.Cancel();
}

return true;
}

public static void Activate(CancellationTokenSource cancellationTokenSource)
{
Task.Run(() => Application.Run(new StopController(cancellationTokenSource)));
}
#region unmanaged

//must be static.
private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
{
// Put your own handler here
switch (ctrlType)
{
case CtrlTypes.CTRL_C_EVENT:

log.Warn("CTRL+C received!. Cancel was fired.");
cancellationTokenSource.Cancel();
break;

case CtrlTypes.CTRL_BREAK_EVENT:

log.Warn("CTRL+BREAK received!. Cancel was fired.");
cancellationTokenSource.Cancel();
break;

case CtrlTypes.CTRL_CLOSE_EVENT:

log.Warn("Program being closed!. Cancel was fired.");
cancellationTokenSource.Cancel();
break;

case CtrlTypes.CTRL_LOGOFF_EVENT:
case CtrlTypes.CTRL_SHUTDOWN_EVENT:
log.Warn("User is logging off!. Cancel was fired.");
cancellationTokenSource.Cancel();
break;

default:
log.Warn($"unknow type {ctrlType}");
break;
}
return true;

}
// Declare the SetConsoleCtrlHandler function
// as external and receiving a delegate.

[DllImport("Kernel32")]
public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);

// A delegate type to be used as the handler routine
// for SetConsoleCtrlHandler.
public delegate bool HandlerRoutine(CtrlTypes CtrlType);

// An enumerated type for the control messages
// sent to the handler routine.
public enum CtrlTypes
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}

#endregion
}

Usage:

  StopController.Activate(cancellationTokenSource);

There is no need to change to windows application.

How to prevent users from killing C# Application

It is not seen as good practice to stop your application from being closed.

See an example of why here

Even if you hide the close button and intercept the alt + f4 keypresses, and handle the exit code of the main form, the user can still force the application to close via task manager.

How do we prevent closing the application from the Task Manager?

Anti-Virus software that is signed and have special contact with Microsoft are allowed to be part of ELAM/Protected processes.

You can try to do the same by writing a kernel driver and deny everyone the right to open a handle with terminate rights on your process. This is however a bit ugly and should be avoided if possible.

The sane solution is to write your "important" application as a Windows service, this will prevent normal users from stopping it.

It will not stop administrator users but that is OK because untrusted users should not be administrators.

Prevent Force Killing of Application Process

Stating your 'absolute' need to keep this process running, I really suggest to separate the critical part of your process from your winforms application and to move this part away from the user machine to a company server.

On this server write a service which keeps your vital work alive and running all the time you like.

These kind of 'absolute' requirements could be enforced only on server machines with redundancy disks, ups units and, (especially), informed sysadmins.



Related Topics



Leave a reply



Submit