11

If we're just talking about Windows, I can use the Microsoft.Win32.SystemEvents.SessionEnding

Is there something cross-platform that I can use? I want something that works with Windows and Linux. I shall be using .NET 6.0

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
igg
  • 2,172
  • 3
  • 10
  • 33
  • I don't think there is any equivalent of that Windows specific class. Probably this has it roots in that there is no single session interface in *nix (each loginmanager and window manager could have it's own set of signals). The closest thing I could find was [PosixSignal](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.posixsignal?view=net-6.09) which would allow you to at least detect when the system attempts to shut down your program - regardless of reason. – fredrik Apr 03 '22 at 14:32
  • @fredrik The PosixSignal seems interesting, but it's just an enum. How can I listen to it? I assume there's some kind of event I can subscribe to? – igg Apr 04 '22 at 18:38
  • Look at the other classes in the namespace. PosixSignalRegistration for exemple. – fredrik Apr 04 '22 at 19:01

1 Answers1

5

To my knowledge, there is no straightforward and reliable way to determine this in a Linux environment, let alone a cross-platform solution. You will need to implement a linux-specific way to detect this.

As @fredrik mentioned in the comments, using PosixSignal would let you know that your application is being asked to terminate, but not why. You can nevertheless examine the situation upon receiving a SIGTERM to determine if the system is indeed shutting down. For example, running systemctl is-system-running would return "stopping" if that is the case.

If we assume a modern Linux desktop environment, a more robust alternative could be to subscribe to the D-bus signal PrepareForShutdown. From the systemd documentation:

The PrepareForShutdown() and PrepareForSleep() signals are emitted when a system suspend or shutdown has been requested and is about to be executed, as well as after the the suspend/shutdown was completed (or failed)...

The library Tmds.Dbus provides an async API to listen to that signal in your .net app. You will still need to deal with the fact that you'll receive this AND the SIGTERM in sequence.

istepaniuk
  • 4,016
  • 2
  • 32
  • 60
  • 1
    Thanks, your answer is quite extensive and has given me a good idea what to look into. I'll keep the question open while the bounty lasts and if no one has anything better, I will award it to you. – igg Apr 04 '22 at 18:39