The short answer is there's absolutely nothing you can do in 100% of cases about a forcible process termination at the time of termination. Think about it. This is not unique to desktop apps. Browser apps have this problem. Server apps have it. The power could go out. The room could explode. There's literally no way to guarantee something happens before the app goes caput.
But even if you can't guarantee your cleanup executes before exit, the situation isn't hopeless. Essentially, you need to keep your application's state saved somewhere persistent - this can be local or online depending on your application. Every time you start something critical, you log that it's starting. When it finishes successfully, you log that it succeeded (or you delete the record of there being an open task).
Now let's say there's a crash. Two possibilities -
(1) if you're an online application, and were saving this state online, then your server could be pinging your app periodically until the task is done. If it doesn't get a successful ping back from your app, it can assume that the app died, and cleanup whatever's necessary.
(2) If you're totally offline, then you likely can only do the clean up when your application restarts. At that point you check the record of the last state, see if it was open/incomplete, and if so do your cleanup.
Edit in response to comment -
Based on what you're doing as far as changing the system with Windows APIs and wanting to ensure it's restored properly, it sounds like an online solution won't work.
I think your idea to launch a separate process to be your monitor might be your best bet. You need it to be a single portable EXE but still should be able to run the same process via Process.Start
, but put it in a monitor "mode" via command line arguments. You can get the process path through Assembly.GetExecutingAssembly
and then launch a second instance to put it in that mode.
That still won't help you from a system crash though. If you want the highest level of robustness you may want to install your app in the Startup folder so that it can check for and handle this failure mode on restart. In that case you'll need to be constantly logging progress to disk somewhere so that your application knows how to properly roll back on startup if things failed.