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.<<ForEachAsync>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.<DeleteDirectory>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.<<DeleteDirectory>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.<<ForEachAsync>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.<DeleteDirectory>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.<LogIfThrows>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.<<ForEachAsync>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.<DeleteDirectory>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.<<DeleteDirectory>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.<<ForEachAsync>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.<DeleteDirectory>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.<LogIfThrows>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.<Install>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.<<ForEachAsync>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.<DeleteDirectory>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.<<DeleteDirectory>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.<<ForEachAsync>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.<DeleteDirectory>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.<LogIfThrows>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.<Install>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.
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) and building Squirrel as part of building the electron-winstaller package.
Problem
When running
Setup.exewhile the app is running, it will often break the installation.The installation fails with the following error message:
The file path varies. Sometimes it's a DLL, sometimes it's
MyApp\app-99.0.0\MyApp.exe.Full Squirrel error message
Afterward, it's not possible to launch the app anymore. Usually, the
AppData\Local\MyAppdirectory will be empty except for theAppData\Local\MyApp\app-99.0.0, whichSetup.exefailed to fully remove. This is not enough to launch the app.Sometimes, even running the installer again won't work because
Setup.exeis 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.
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-winstallercurrently vendors theSetup.exe, so this would involve maintaining a set of patches (similar to the Squirrel.Mac patches in the main electron repo) and building Squirrel as part of building theelectron-winstallerpackage.