Search code examples
c#winapi

How is RegisterAppStateChangeNotification supposed to work?


Microsoft documentation says:

https://learn.microsoft.com/en-us/windows/win32/api/appnotify/nf-appnotify-registerappstatechangenotification

Enables an app to register a callback function through which it can be notified that its library is going into or coming out of a suspended state. The app can use this information to perform any necessary operations, such as preserving state, that should be performed at that point.

I thought this meant that I could use this to get a callback if my app were to be suspended, but I do not seem to be getting one. I'm wondering, am I misunderstanding the purpose of this call, or is something wrong with my implementation? I do not see any examples of this in use anywhere on Google.

Here is my code. I have another app that suspends all threads associated with the app to put it in a suspended state.

My end goal is to be able to know if my app was previously suspended and resumed by another app.

public partial class Form1 : Form
{
    [DllImport("api-ms-win-core-psm-appnotify-l1-1-0.dll")]
    static extern bool RegisterAppStateChangeNotification(
            PAPPSTATE_CHANGE_ROUTINE Routine
        , IntPtr Context
        , out IntPtr Registration
        );
    
    IntPtr context;

    public delegate void PAPPSTATE_CHANGE_ROUTINE(bool Quiesced, IntPtr Context);
    public static readonly PAPPSTATE_CHANGE_ROUTINE stateChangedCallback = OnStateChanged;

    public Form1()
    {
        InitializeComponent();
        RegisterStateChange();
        txtProcessId.Text = Process.GetCurrentProcess().Id.ToString(); //have this to make it easy to suspend the thread
    }
    
    public void RegisterStateChange()
    {
        RegisterAppStateChangeNotification(stateChangedCallback, IntPtr.Zero, out context);
    }
    public static void OnStateChanged(bool Quiesced, IntPtr Context)
    {
        MessageBox.Show("here!!!");
    }
}

Solution

  • This function is for the Universal Windows Platform (UWP). UWP apps have a process lifecycle managed by the operating system, meaning the OS suspends and resumes the apps automatically, and this function allows you to be notified about what the operating system is doing. If you are developing a traditional Win32 application, this function is not relevant, because the operating system doesn't automatically suspend or resume Win32 apps. Both kinds of apps (Win32 & UWP) can be manually suspended in Task Manager, and that would bypass this function even in the UWP case, because that is an action taken by the user and not by the operating system.

    As for why the API is freely available to use in Win32 apps, it's because it can be used in a DLL that could be loaded by either a Win32 app or a UWP app - the DLL doesn't necessarily have to know or be built for one or the other, it can just call this function and rest assured it will have its callbacks if needed.