Electron App events not firing #60

Closed
opened 2026-01-29 16:29:26 +00:00 by claunia · 5 comments
Owner

Originally created by @BrianAllred on GitHub (Nov 9, 2017).

Originally assigned to: @GregorBiswanger on GitHub.

I've tried subscribing to BeforeQuit, Quitting, WillQuit, and WindowAllClosed. Regardless of the event, my code never fires when I close the Electron window.

            Electron.App.BeforeQuit += SaveOptions;
            Electron.App.Quitting += SaveOptions;
            Electron.App.WillQuit += SaveOptions;
            Electron.App.WindowAllClosed += SaveOptions;

Using version 0.0.7 on Windows 10.

Originally created by @BrianAllred on GitHub (Nov 9, 2017). Originally assigned to: @GregorBiswanger on GitHub. I've tried subscribing to BeforeQuit, Quitting, WillQuit, and WindowAllClosed. Regardless of the event, my code never fires when I close the Electron window. ``` Electron.App.BeforeQuit += SaveOptions; Electron.App.Quitting += SaveOptions; Electron.App.WillQuit += SaveOptions; Electron.App.WindowAllClosed += SaveOptions; ``` Using version 0.0.7 on Windows 10.
claunia added the bugIn progress labels 2026-01-29 16:29:26 +00:00
Author
Owner

@BrianAllred commented on GitHub (Nov 9, 2017):

More details:

I actually had some errors in my C# which causes the backend ASP.NET process to crash without the frontend closing. So after I fixed that, I did some more digging.

It seems to be random whether it fires or not. Environment doesn't seem to be a factor; I tried from Visual Studio and attaching the debugger, not attaching the debugger, and doing a full build and running the exe. While debugging, sometimes I'll hit my break point, but then Visual Studio goes into "Application break" mode. This makes it seem like Electron is not actually finishing the callback before it kills the process.

I'm definitely open to being more involved. If you want recordings, code samples, a shared desktop session, I will accommodate. I really like this framework and want it to be successful.

@BrianAllred commented on GitHub (Nov 9, 2017): More details: I actually had some errors in my C# which causes the backend ASP.NET process to crash without the frontend closing. So after I fixed that, I did some more digging. It seems to be random whether it fires or not. Environment doesn't seem to be a factor; I tried from Visual Studio and attaching the debugger, not attaching the debugger, and doing a full build and running the exe. While debugging, sometimes I'll hit my break point, but then Visual Studio goes into "Application break" mode. This makes it seem like Electron is not actually finishing the callback before it kills the process. I'm definitely open to being more involved. If you want recordings, code samples, a shared desktop session, I will accommodate. I really like this framework and want it to be successful.
Author
Owner

@BrianAllred commented on GitHub (Nov 10, 2017):

I think I fixed it.

Some context: I'm designing essentially a single-page application, so I'm using my HomeController as my bread-and-butter (probably not the best practice, but...). Because of this, I'm doing my event setup in the Index() method of the controller. I'm subscribing to the IpcMain messages there and I put the subscription to the BeforeQuit there.

What I discovered was that putting any blocking call in the Index() method would keep the BeforeQuit event from firing. I changed my blocking calls to run using Threadpool.QueueUserWorkItem. Once my Index() method was nothing but event subscriptions and thread creation, all events started firing correctly.

As far as how this affects my code, it's not a big deal. It just wasn't immediately apparent what the issue was.

@BrianAllred commented on GitHub (Nov 10, 2017): I think I fixed it. Some context: I'm designing essentially a single-page application, so I'm using my HomeController as my bread-and-butter (probably not the best practice, but...). Because of this, I'm doing my event setup in the Index() method of the controller. I'm subscribing to the IpcMain messages there and I put the subscription to the BeforeQuit there. What I discovered was that putting any blocking call in the Index() method would keep the BeforeQuit event from firing. I changed my blocking calls to run using Threadpool.QueueUserWorkItem. Once my Index() method was nothing but event subscriptions and thread creation, all events started firing correctly. As far as how this affects my code, it's not a big deal. It just wasn't immediately apparent what the issue was.
Author
Owner

@GregorBiswanger commented on GitHub (Nov 10, 2017):

I coded the night long for you and fix it and implement one more feature: Prevent Quiting ;)
I synced my work on master. The next Electron.NET API Version 0.0.8 have the fix. I will write a short documentation here tomorrow. I´m tired now.

Enjoy!

@GregorBiswanger commented on GitHub (Nov 10, 2017): I coded the night long for you and fix it and implement one more feature: **Prevent Quiting** ;) I synced my work on master. The next Electron.NET API Version 0.0.8 have the fix. I will write a short documentation here tomorrow. I´m tired now. **Enjoy!**
Author
Owner

@BrianAllred commented on GitHub (Nov 10, 2017):

Thanks!! I hope to have time to contribute to this awesome project soon!

@BrianAllred commented on GitHub (Nov 10, 2017): Thanks!! I hope to have time to contribute to this awesome project soon!
Author
Owner

@GregorBiswanger commented on GitHub (Nov 10, 2017):

You can execute your logic before the application will exit now:

public void ElectronBootstrap()
{
    // Emitted before the application starts closing its windows. 
    Electron.App.BeforeQuit += App_BeforeQuit;

    // Emitted when all windows have been closed and the application will quit. 
    Electron.App.WillQuit += App_WillQuit;

    // Emitted when the application is quitting.
    Electron.App.Quitting += App_Quitting;
}

private async Task App_BeforeQuit(QuitEventArgs arg)
{
    await Electron.Dialog.ShowMessageBoxAsync("Before Quit");
    await Electron.Dialog.ShowMessageBoxAsync("Before Quit 2");
}

private async Task App_WillQuit(QuitEventArgs arg)
{
    await Electron.Dialog.ShowMessageBoxAsync("Will Quit");
    await Electron.Dialog.ShowMessageBoxAsync("Will Quit 2");
}

private async Task App_Quitting()
{
    await Electron.Dialog.ShowMessageBoxAsync("Quitting");
    await Electron.Dialog.ShowMessageBoxAsync("Quitting 2");
}

Calling args.PreventDefault() will prevent the default behaviour, which is terminating the application:

private async Task App_BeforeQuit(QuitEventArgs arg)
{
    arg.PreventDefault();

    await Electron.Dialog.ShowMessageBoxAsync("Before Quit");
    await Electron.Dialog.ShowMessageBoxAsync("Before Quit 2");
}

The default behavior in Electron.NET is to quit the app on window all closed. If the user pressed Cmd + Q, or the developer called Electron.App.Quit(), Electron will first try to close all the windows and then emit the Electron.App.WillQuit event, and in this case the Electron.App.WindowAllClosed event would not be emitted. To deactivate the default behavior, set the Electron.WindowManager.IsQuitOnWindowAllClosed to false. The Electron.App.WindowAllClosed event would work.

public void ElectronBootstrap()
{
    Electron.WindowManager.IsQuitOnWindowAllClosed = false;

    // Emitted when all windows have been closed.
    Electron.App.WindowAllClosed += App_WindowAllClosed;
}

private async void App_WindowAllClosed()
{
    await Electron.Dialog.ShowMessageBoxAsync("All windows closed");
}

Enjoy!

@GregorBiswanger commented on GitHub (Nov 10, 2017): **You can execute your logic before the application will exit now:** ``` public void ElectronBootstrap() { // Emitted before the application starts closing its windows. Electron.App.BeforeQuit += App_BeforeQuit; // Emitted when all windows have been closed and the application will quit. Electron.App.WillQuit += App_WillQuit; // Emitted when the application is quitting. Electron.App.Quitting += App_Quitting; } private async Task App_BeforeQuit(QuitEventArgs arg) { await Electron.Dialog.ShowMessageBoxAsync("Before Quit"); await Electron.Dialog.ShowMessageBoxAsync("Before Quit 2"); } private async Task App_WillQuit(QuitEventArgs arg) { await Electron.Dialog.ShowMessageBoxAsync("Will Quit"); await Electron.Dialog.ShowMessageBoxAsync("Will Quit 2"); } private async Task App_Quitting() { await Electron.Dialog.ShowMessageBoxAsync("Quitting"); await Electron.Dialog.ShowMessageBoxAsync("Quitting 2"); } ``` **Calling args.PreventDefault() will prevent the default behaviour, which is terminating the application:** ``` private async Task App_BeforeQuit(QuitEventArgs arg) { arg.PreventDefault(); await Electron.Dialog.ShowMessageBoxAsync("Before Quit"); await Electron.Dialog.ShowMessageBoxAsync("Before Quit 2"); } ``` **The default behavior in Electron.NET is to quit the app on window all closed.** If the user pressed Cmd + Q, or the developer called Electron.App.Quit(), Electron will first try to close all the windows and then emit the Electron.App.WillQuit event, and in this case the Electron.App.WindowAllClosed event would **not** be emitted. To deactivate the default behavior, set the Electron.WindowManager.IsQuitOnWindowAllClosed to false. The Electron.App.WindowAllClosed event would work. ``` public void ElectronBootstrap() { Electron.WindowManager.IsQuitOnWindowAllClosed = false; // Emitted when all windows have been closed. Electron.App.WindowAllClosed += App_WindowAllClosed; } private async void App_WindowAllClosed() { await Electron.Dialog.ShowMessageBoxAsync("All windows closed"); } ``` **Enjoy!**
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/Electron.NET#60