electron / electron/windows-installer
Running Setup.exe while the app is running can break the installation
- Dominant language
- TypeScript
- Stars
- 1.6k
- Forks
- 267
- Avg merge
- 5h 38m
- Merged PRs (30d)
- 1
Description
## Problem
When running `Setup.exe` while the app is running, it will often break the installation.
The installation fails with the following error message:
```
Failed to remove existing directory on full install, is the app still running???: System.UnauthorizedAccessException: Access to the path 'D:\Users\nikwen\AppData\Local\MyApp\app-99.0.0\d3dcompiler_47.dll' is denied.
```
The file path varies. Sometimes it's a DLL, sometimes it's `MyApp\app-99.0.0\MyApp.exe`.
Full Squirrel error message
```
[04/05/26 23:43:03] error: IEnableLogger: Failed to remove existing directory on full install, is the app still running???: System.UnauthorizedAccessException: Access to the path 'D:\Users\nikwen\AppData\Local\MyApp\app-99.0.0\d3dcompiler_47.dll' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalDelete(String path, Boolean checkHost)
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Squirrel.Utility.<>c__DisplayClass13_1`1.<b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Utility.d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Utility.<>c.<b__19_1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Squirrel.Utility.<>c__DisplayClass13_1`1.<b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Utility.d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Utility.d__42.MoveNext()
[04/05/26 23:43:03] fatal: Finished with unhandled exception: System.AggregateException: One or more errors occurred. ---> System.UnauthorizedAccessException: Access to the path 'D:\Users\nikwen\AppData\Local\MyApp\app-99.0.0\d3dcompiler_47.dll' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalDelete(String path, Boolean checkHost)
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Squirrel.Utility.<>c__DisplayClass13_1`1.<b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Utility.d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Utility.<>c.<b__19_1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Squirrel.Utility.<>c__DisplayClass13_1`1.<b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Utility.d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Utility.d__42.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Update.Program.d__4.MoveNext()
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at Squirrel.Update.Program.executeCommandLine(String[] args)
at Squirrel.Update.Program.main(String[] args)
---> (Inner Exception #0) System.UnauthorizedAccessException: Access to the path 'D:\Users\nikwen\AppData\Local\MyApp\app-99.0.0\d3dcompiler_47.dll' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalDelete(String path, Boolean checkHost)
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Squirrel.Utility.<>c__DisplayClass13_1`1.<b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Utility.d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Utility.<>c.<b__19_1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Squirrel.Utility.<>c__DisplayClass13_1`1.<b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Utility.d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Utility.d__42.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Squirrel.Update.Program.d__4.MoveNext()<---
```
Afterward, it's not possible to launch the app anymore. Usually, the `AppData\Local\MyApp` directory will be empty except for the `AppData\Local\MyApp\app-99.0.0`, which `Setup.exe` failed to fully remove. This is not enough to launch the app.
Sometimes, even running the installer again won't work because `Setup.exe` is still running on the system.
## Why it's happening
If I understand the Squirrel code properly, it [gives applications 500ms to exit before attempting the installation](https://github.com/Squirrel/Squirrel.Windows/blob/51f5e2cb01add79280a53d51e8d0cfa20f8c9f9f/src/Update/Program.cs#L167-L168).
It doesn't seem to wait for the processes to be killed
## Solution ideas
Squirrel is no longer maintained, so if we want to fix this, we need to do it downstream.
As far as I can tell, we'd have to patch Squirrel. `electron-winstaller` currently vendors the `Setup.exe`, so this would involve maintaining a set of patches (similar to the [Squirrel.Mac patches in the main electron repo](https://github.com/electron/electron/tree/main/patches/squirrel.mac)) and building Squirrel as part of building the `electron-winstaller` package.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.