Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Close electron app from angular component

I'm trying to figure out how I can close an electron app with an angular component. I removed the menu bar by setting frame: false on BrowserWindow({... inside main.js. I have a close button on the top right corner of the electron app from a component. I want to be able to close the app from the component.ts file on click, but I haven't seen any examples of closing electron from an angular component.

I thought the following would work, but didn't. I'm exporting a function from main.js and calling the function from the component. like so (see closeApp()):

const { app, BrowserWindow } = require('electron')
const url = require("url");
const path = require("path");

let mainWindow

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    frame: false,
    webPreferences: {
      nodeIntegration: true
    }
  })
  mainWindow.maximize();
  mainWindow.loadURL(
    url.format({
      pathname: path.join(__dirname, `/dist/index.html`),
      protocol: "file:",
      slashes: true
    })
  );

...

function closeApp() {
  mainWindow = null
}

export { closeApp };

Then I would try and import it into component like

import { Component, OnInit } from '@angular/core';
import { closeApp } from '../../../main.js';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {

  }
  testClose() {
    closeApp();
  }

}

How can I close the electron app from angular? I appreciate any help!

like image 880
user6680 Avatar asked Jul 14 '26 23:07

user6680


1 Answers

You can use code like this from your browser window. Keep in mind it requires enableRemoteModule which is not recommended for security reasons. You can work around that with more complex code, but this should show you the basic idea

The easier but less secure way

In your main process:

mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    frame: false,
    fullscreen: false,
    webPreferences: {
      nodeIntegration: true,
      enableRemoteModule: true
    }
  })

From your mainWindow, in the renderer

Upon clicking the close button for your app (your custom button) you should have it run the following logic:

const win = remote.getCurrentWindow();
win.close();

https://www.electronjs.org/docs/api/browser-window#winclose

win.destroy() is also available, but win.close() should be preferred.


The harder but more secure way

This requires using a preload script That's another question, but I'll include the code for doing it this way, but it is harder to get working for a number of reasons.

That said, this is the way you should aim to implement things in the long run.

  import { browserWindow, ipcMain } from 'electron';

  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    frame: false,
    fullscreen: false,
    preload: [Absolute file path to your preload file],
    webPreferences: {}
  });

  ipcMain.handle('close-main-window', async (evt) => {
    mainWindow.close();
    // You can also return values from here

  });


preload.js

  const { ipcRenderer } = require('electron');

  // We only pass closeWindow to be used in the renderer page, rather than passing the entire ipcRenderer, which is a security issue
  const closeWindow = async () => {
     await ipcRenderer.invoke('close-main-window'); // We don't actually need async/await here, but if you were returning a value from `ipcRenderer.invoke` then you would need async/await
  }

  window.api = {
    closeWindow
  }

renderer page

  
// I don't know Angular, but just call window.api.closeWindow() in response to the button you want to use

like image 108
Slbox Avatar answered Jul 17 '26 15:07

Slbox



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!