✔️ 1. Setup.exe 실행 후 앱이 깜박이는 현상
앞에서 Electron Forge를 이용해 Windows용 Setup.exe를 만들어보았습니다.
실제로 Setup.exe를 실행해보니 설치 과정에서 룰렛 앱 창이 잠깐 나타났다가 사라지는 현상이 발생했습니다.
처음에는 앱이 설치되면서 정상적으로 실행되는 과정이라고 생각할 수도 있지만, 설치 과정에서 발생하는 실행이라면 사용자에게 불필요한 화면이 보이게 됩니다.
🔹 electron-squirrel-startup 설치
이번에 사용한 Setup.exe는 단순히 파일을 복사하는 설치 프로그램이 아니라 Squirrel.Windows를 이용해 Electron 앱을 설치하는 프로그램입니다.
Electron Forge의 Squirrel.Windows 문서에 따르면, 앱을 처음 설치하거나 업데이트 또는 삭제하는 과정에서 Squirrel.Windows가 Electron 앱을 추가로 실행할 수 있습니다.
실제 앱이 일반적으로 실행되지 않도록 먼저 electron-squirrel-startup을 설치합니다.
npm install electron-squirrel-startup
설치가 완료되면 main.js의 가장 위쪽에 다음 코드를 추가합니다.
const { app, BrowserWindow, Menu } = require('electron');
if (require('electron-squirrel-startup')) {
app.quit();
}
Squirrel.Windows에서 설치 등의 작업을 위해 앱을 실행했을 때 이를 감지하고, 일반적인 앱 실행으로 이어지지 않도록 종료하는 역할을 합니다.
🔹 그런데 app.quit()만 사용하면?
여기서 한 가지 문제가 있었습니다.
app.quit();
을 호출했다고 해서 그 아래의 JavaScript 코드 실행이 즉시 중단되는 것은 아닙니다.
app.quit()은 앱을 종료하도록 요청하는 동작이기 때문에, 그 사이에 아래 코드가 계속 진행될 수 있습니다.
app.whenReady().then(() => {
createWindow();
});
이 때문에 createWindow()가 먼저 실행되어 창이 잠깐 나타났다가, 종료 처리가 진행되면서 다시 닫히는 현상이 발생할 수 있습니다.
즉, 사용자가 보게 되는 앱 창이 잠깐 나타났다가 사라지는 깜박임이 발생하는 것입니다.
🔹 return으로 실행 자체를 중단하기
따라서 Squirrel 이벤트를 처리한 뒤에는 일반적인 Electron 앱 초기화 코드가 실행되지 않도록 하는 것이 중요합니다.
Electron의 Squirrel 관련 예제에서도 Squirrel 이벤트를 처리한 뒤 return하여 일반적인 앱 실행 로직으로 넘어가지 않도록 처리하는 패턴을 사용합니다.
const { app, BrowserWindow, Menu } = require('electron');
if (require('electron-squirrel-startup')) {
return;
}
이렇게 하면 app.whenReady() 자체가 등록되지 않기 때문에 설치 과정에서 불필요하게 BrowserWindow가 생성되는 것을 막을 수 있습니다.
💡 app.quit()은 앱을 종료하도록 요청하는 것이고, 이후 코드의 실행 자체를 즉시 중단하는 것과는 다릅니다.
설치 과정에서 앱 창이 잠깐 나타나는 현상을 방지하려면 설치 관련 실행을 일반적인 앱 실행과 분리해서 처리해야 합니다.
설치 완료 후 앱이 자동으로 실행되는 것은?
여기서 한 가지 더 알게 된 점이 있습니다.
위 코드를 적용하면 설치 과정에서 발생하는 불필요한 앱 실행과 깜박임은 해결할 수 있지만, 설치가 모두 끝난 후 Squirrel.Windows가 앱을 자동으로 실행하는 것까지 없애지는 않습니다.
Squirrel.Windows에서는 설치가 완료된 후 앱을 실행하는 동작이 기본 설치 과정에 포함되어 있습니다.
✔️ 2. 설치 중 Setup.exe를 다시 실행하면서 발생한 오류 (주의점)
Setup.exe를 실행한 후 설치가 아직 끝나지 않은 상태에서 `Setup.exe`를 다시 실행해보았습니다.
그러자 다음과 같은 오류가 발생했습니다.

Installation has failed
There was an error while installing the application.
Check the setup log for more information and contact the author.
처음에는 설치 파일 자체에 문제가 있는 것으로 생각했습니다.
그런데 같은 상황을 반복해서 테스트하는 과정에서 다음과 같은 오류창이 나타나기도 했습니다.

A JavaScript error occurred in the main process
Uncaught Exception:
Error: spawn C:\Users\사용자\AppData\Local\electron_app\Update.exe ENOENT
여기서 ENOENT는 실행하려는 파일이나 경로를 찾을 수 없다는 의미입니다.
오류 내용을 보면 다음 경로에 있는 Update.exe를 실행하려고 했지만 찾지 못한 것을 확인할 수 있습니다.
C:\Users\사용자\AppData\Local\electron_app\Update.exe
왜 이런 오류가 발생했을까?
이번에 사용한 Setup.exe는 Squirrel.Windows를 이용한 설치 파일입니다.
Squirrel.Windows는 설치 과정에서 필요한 파일을 준비하고 Update.exe를 이용해 실제 설치 작업을 진행합니다.
치가 완료되기 전에 동일한 Setup.exe를 다시 실행하면 설치 작업이 서로 겹치면서 정상적으로 설치가 진행되지 않을 수 있습니다.
그 과정에서
Installation has failed
오류가 발생하거나,
Update.exe ENOENT
와 같이 설치에 필요한 Update.exe를 찾지 못하는 오류가 나타날 수 있었습니다.
💡 오류를 방지하려면 (결론)
이 문제는 main.js의 일반적인 앱 기능에 문제가 있어서 발생한 것이 아니었습니다.
설치가 진행 중인 상태에서 Setup.exe를 다시 실행한 것이 원인이었습니다.
따라서 설치 프로그램을 실행한 후에는 설치가 완전히 완료될 때까지 다시 실행하지 않고 기다리는 것이 좋습니다.
또한 설치 프로그램을 여러 번 테스트하는 경우에는 이전 설치가 정상적으로 종료되었는지 확인한 후 다음 테스트를 진행하는 것이 좋습니다.
✔️ 3. 설치 완료 후 바탕화면 바로가기가 생성된 것을 알려주기
깜박이는 문제를 해결하고 다시 설치해보니 한 가지 아쉬운 점이 있었습니다.
사용자 입장에서는 프로그램이 바로 실행되기 때문에 설치가 완료되었고 바탕화면에 바로가기가 생성되었다는 사실을 모를 수 있습니다.
그래서 설치가 완료된 후 Squirrel.Windows가 앱을 실행할 때만 안내 알림을 표시하도록 수정했습니다.
🔹 --squirrel-firstrun 확인하기
Squirrel.Windows는 설치가 완료된 후 앱을 처음 실행할 때 --squirrel-firstrun 인자를 전달합니다.
따라서 process.argv에서 해당 인자가 포함되어 있는지 확인하면 일반적인 앱 실행과 설치 완료 후 실행을 구분할 수 있습니다.
`main.js`
const { app, BrowserWindow, Menu, Notification } = require('electron');
if (require('electron-squirrel-startup')) {
return;
}
const createWindow = () => {
const win = new BrowserWindow({
width: 420,
height: 720,
resizable: true,
backgroundColor: '#1B1B2F'
});
win.loadFile('index.html');
// 설치가 끝나고 Squirrel이 앱을 처음 실행시켜줄 때는
// --squirrel-firstrun 인자가 함께 붙습니다. 이때만 안내 알림을 띄웁니다.
if (process.argv.includes('--squirrel-firstrun')) {
showFirstRunNotification();
}
};
function showFirstRunNotification() {
if (!Notification.isSupported()) return;
new Notification({
title: '설치가 완료되었습니다!',
body: '바탕화면에 바로가기가 생성되었습니다.'
}).show();
}
app.whenReady().then(() => {
Menu.setApplicationMenu(null); // 기본 메뉴바 제거 (File, Edit 등)
createWindow();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
이렇게 하면 설치 완료 후 앱이 실행될 때 다음과 같은 알림이 표시됩니다.

그리고 사용자가 이후 바탕화면에 생성된 랜덤 룰렛 바로가기를 실행하는 경우에는 --squirrel-firstrun 인자가 없기 때문에 해당 알림이 표시되지 않습니다.
🔗 참고
Electron Forge에서 Windows용 설치파일을 만들 때 사용하는 Squirrel 관련 내용은 다음 글에서도 확인할 수 있습니다.
'개발공부기록 > Electron 데스크톱 앱 개발' 카테고리의 다른 글
| [Electron 데스크톱 앱 개발] #5: Electron 앱 패키징하기 (Windows 실행 파일 만들기) (0) | 2026.09.16 |
|---|---|
| [Electron 데스크톱 앱 개발] #4: UI 디자인 개선하기 (랜덤 룰렛) (0) | 2026.09.15 |
| [Electron 데스크톱 앱 개발] #3: 첫 번째 Electron 앱 만들기 (랜덤 룰렛) (0) | 2026.09.15 |
| [Electron 데스크톱 앱 개발] #2: Electron 개발환경 준비하기 (Node.js + Electron 설치) (0) | 2026.09.14 |
| [Electron 데스크톱 앱 개발] #1: Electron 입문, 데스크톱 앱 개발을 시작해보자 (0) | 2026.09.11 |