Open athenakia opened 2 years ago
This problem does not exist on version 22.14.13 or previous.
23.1.0 version , also not working
same here, version with 23.0.3
Getting the same error when trying to change the install location to Program Files
. When using the default install location, or install to any directory outside of Program Files
, am not getting this error (eg. C:\MyApp
)
Originally using 23.0.3, but tried upgrading to 23.3.1 & 23.3.2 (pre-release), but both also had this issue.
Interestingly if right clicking on the .exe installer and selecting Run as administrator
this issue does not come up. So not sure if this is a signing issue? I do not currently have any signing implemented for windows, but will try this.
Also tried downgrading to 22.14.13, but got a different error: Error opening file for writing: C:\Program Files\MyApp\Uninstall MyApp.exe
Using the custom path described in docs: https://www.electron.build/configuration/nsis.html#common-questions
EDIT: main goal to install to Program Files was resolved by simply setting perMachine
to true
rather than setting manually with custom .nsh script. This issue had the same error message, but ultimately a different issue.
Saw this in our project too - still a problem in v23.3.3.
From a bit of looking around and experimenting it seems that the addition of args.push("-INPUTCHARSET", "UTF8")
to packages/app-builder-lib/src/targets/nsis/NsisTarget.ts is causing the issue (but no idea why).
With that line removed the produced installer works fine.
Hi. Any solutiuon exist or need to downgrade?
I'm fairly impressed that this issue isn't high priority right now... Currently downgrading as this is a breaking bug for our Windows users. A solid 5% of our users got hit with this bug which can't happen in a production build ofcourse
For the developer picking this up, somehow FIND_PROCESS inside packages/app-builder-lib/temapltes/nsis/include/allowOnlyOneInstallerInstance.nsh
says that a process is running while if you execute the same command in the command line, it reports nothing is running. It gets stuck because it reports there is a process active but it can't kill any of the processes as there are non active which causes you to be stuck in an infinite loop.
EDIT 2: Alright so the issue is the following: the exit code of FIND_PROCESS is 0. This is probably because there is a parent process active which doesn't fall under the same name. It's on admin level so the user can't close it as it doesn't know the name, we can't close it as it's on admin level and it keeps looping. I think the solution to this problem is to show a list of running processes and display the list of processes blocking the installer instead of a simple retry.
Edit: Seems I have found it. When I have the installer "test-app-installer.exe" open for "Test App.exe" for an one click installation for an user installation, the allowOnlyOneInstallerInstance.nsh calls FIND_PROCESS which execs the following command: cmd /c tasklist /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq Test App.exe" | %SYSTEMROOT%\System32\find.exe "Test App.exe"
. While having the installer open, I check this command inside my cmd and it returns 0 as exit code (so blocking installation) but if I look at the result, there are no processes active (clear result)
Anyone have a solution ?
Definitely not a solution, but you can include a custom script with a macro so app-builder-lib uses this macro instead of the default one.
In add a path to a custom .nsh script file in your package.json under build:
"nsis": { "include": "installer/installer.nsh" }
Inside the installer.nsh just add:
!macro customCheckAppRunning
!macroend
This will bypass the WHOLE check. You can add the code from allowOnlyOneInstallerInstance.nsh and edit it so it works for you. I don't have enough knowledge to propose permanent a solution but this is a step for people to make their own and create a PR to fix it! To iterate it again: THIS WILL BYPASS THE WHOLE RUNNING CHECK SO THIS MIGHT CORRUPT FILES IF THE PROGRAM IS ALREADY OPEN!
From a bit of looking around and experimenting it seems that the addition of
args.push("-INPUTCHARSET", "UTF8")
to packages/app-builder-lib/src/targets/nsis/NsisTarget.ts is causing the issue (but no idea why). With that line removed the produced installer works fine.
Quick note. This was added to resolve these (based off the commit message):
I'm wondering if there's a way for us to identify it other than "contains" and instead look for an exact match? Not sure if that's where the bug is originating though.
At a base level, my apologies for this issue being stagnant. I've been the only maintainer on this project for some time now and am largely dependent upon community contributions, especially when relating to windows and linux (I'm predominantly a mac user).
I'm wondering if there's a way for us to identify it other than "contains" and instead look for an exact match? Not sure if that's where the bug is originating though.
The weird thing is, even on brand new systems with nothing on it this bug will happen. I have verified the results and every user who reported this error has a clear prompt of the exact tasklist command while it still returns 0 inside the nsis installer. At this point i'm guessing it's find.exe or the ns exec plugin for nsis doing something weird rather than the tasklist command. The tasklist command always returns 0 as result so we can't exclude find.exe without a replacement. I'll take a look myself next week to research all of the nsis file changes but it's really hard to test as I haven't been able to replicate it. (I'm already on my 3rd VPS and still no luck)
Soooo circling back, what do we do here? Completely rewrite the "Application still running" logic? Or just revert the implementation that was introduced in electron-builder 23.x.x? I'm really out of my element here so I personally am unable to do the rewrite approach. I'd love to unblock you guys such that you can update electron-builder to latest.
Curious. Would anyone mind trying out this? Replace the final portion of:
nsExec::Exec `cmd /c tasklist /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq ${_FILE}" | %SYSTEMROOT%\System32\find.exe "${_FILE}"`
With:
| findstr /B /C:"INFO: " > nul
I think that'll provide the return value info we're looking for? Ref: https://stackoverflow.com/questions/56569414/process-names-over-21-characters-not-detected-supported-by-tasklist/56577365#56577365
Curious if this would fix the issue, but I have no manner with which to test
In my case, If I set perMachine: false
, then It will throw the same error when installing .exe file.
All of my version is same as @athenakia .
@mmaietta Is there any solution to prevent this error?
@SergiiMarkin, thanks for chiming in... from re-reading this ticket again, you're saying the exact same thing as everyone else.
Two solutions:
perMachine: true
per https://github.com/electron-userland/electron-builder/issues/6865#issuecomment-1193773494Best way for someone to help me here is: Create a minimum reproducible repo for me to test locally with. I have a windows machine now, but it's not a dev environment
I've created this patch via patch-package
as a potential test
app-builder-lib+23.0.3.patch
diff --git a/node_modules/app-builder-lib/templates/nsis/include/allowOnlyOneInstallerInstance.nsh b/node_modules/app-builder-lib/templates/nsis/include/allowOnlyOneInstallerInstance.nsh
index cc77993..41681dc 100644
--- a/node_modules/app-builder-lib/templates/nsis/include/allowOnlyOneInstallerInstance.nsh
+++ b/node_modules/app-builder-lib/templates/nsis/include/allowOnlyOneInstallerInstance.nsh
@@ -40,8 +40,9 @@
${nsProcess::FindProcess} "${_FILE}" ${_ERR}
!else
# find process owned by current user
- nsExec::Exec `cmd /c tasklist /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq ${_FILE}" | find "${_FILE}"`
+ nsExec::Exec `cmd /c tasklist /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq ${_FILE}" -fo csv | convertfrom-csv`
Pop ${_ERR}
+ Pop $1.PID
!endif
!macroend
Honestly, I have no idea if Pop $1.PID
is the correct syntax. I've tested locally just convertfrom-csv
and it works locally in powershell for IMAGENAME
s that are longer than tasklist
can output. So if anyone has knowledge on how to handle nsExec
in macro
s, I'd really appreciate some guidance.
If no guidance on nsh
scripting and no minimum reproducible repro are provided, then please don't expect any progress to be made from my side.
Hi @mmaietta thanks for your reply.
As for the first solution, I am not able to use the first solution with perMachine: true
.
It has a problem with /allusers
suffix in uninstallstring as you can see here #7472
So I had to use perMachine: false
.
As for the second solution, I would like to edit my npm package app-builder-lib
with your custom code from patch version.
Before I use your code, I have questions.
nsExec::Exec
cmd /c tasklist /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq ${_FILE}" -fo csv | convertfrom-csv``
Why do I have to replace | find "${_FILE}
with -fo csv | convertfrom-csv
?
convertfrom-csv
returns an object that can have keys directly accessed, whereas AFAIK, find
is a simple string search and doesn't capture long app names. Just curious if it'd also resolve this issue tbh
Hi! Any ideas how to resolve the issue? None of the proposed approaches currently solve it for my Windows users. And I can't downgrade the version because of necessary features for "universal" Mac build((
... meaning that every time user sees an "update available" in my app - when installing on Windows this error appears - "App cannot be closed. Please close it manually and click Retry to continue"
I'm using nsisWeb
installer
Hi! Any ideas how to resolve the issue? None of the proposed approaches currently solve it for my Windows users. And I can't downgrade the version because of necessary features for "universal" Mac build((
... meaning that every time user sees an "update available" in my app - when installing on Windows this error appears - "App cannot be closed. Please close it manually and click Retry to continue"
I'm using
nsisWeb
installer
I have some problem for users on 10 pro windows 21H1 version
Ok, as a temporary solution I did this in my package.json
:
...
"scripts": {
"build:electron:mac": "npm i electron-builder@^24.4.0 && electron-builder -m --config build-mac.config.json --publish always",
"build:electron:win": "npm i electron-builder@22.14.13 && electron-builder -w --config build-win.config.json --publish always",
...
}
...
...meaning that every time I initiate the build for Windows - I also rollback to the working electron-builder version (22.14.13)
npm i electron-builder@22.14.13
Thanks! This is good enough workaround for now.
I'm going to try explaining what I think the relevant portions of the NSIS script are doing and what a probable issue is. (I'm not certain about this).
Notice that running app processes are killed like this:
doStopProcess:
DetailPrint `Closing running "${PRODUCT_NAME}"...`
# https://github.com/electron-userland/electron-builder/issues/2516#issuecomment-372009092
!ifdef INSTALL_MODE_PER_ALL_USERS
nsExec::Exec `taskkill /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid"`
!else
# ↓ This line! ↓
nsExec::Exec `cmd /c taskkill /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid" /fi "USERNAME eq %USERNAME%"`
# ↑
# Notice the "PID ne $pid"
!endif
where /fi "PID ne $pid"
causes the command to kill only processes that don't have the same PID as this one (where $pid
is defined at the beginning of _CHECK_APP_RUNNING
to be the pid
of the current process).
Thus, we should (probably) also be filtering the current process' PID out of the list in FIND_PROCESS
.
I'm currently using this patch:
diff --git a/templates/nsis/include/allowOnlyOneInstallerInstance.nsh b/templates/nsis/include/allowOnlyOneInstallerInstance.nsh
index a1fd1875d852ff69c087a3103eff827c20d37ca5..5222614ddad3276876857e7a9dde4017a6b9fc85 100644
--- a/templates/nsis/include/allowOnlyOneInstallerInstance.nsh
+++ b/templates/nsis/include/allowOnlyOneInstallerInstance.nsh
@@ -42,7 +42,7 @@
${nsProcess::FindProcess} "${_FILE}" ${_ERR}
!else
# find process owned by current user
- nsExec::Exec `cmd /c tasklist /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq ${_FILE}" | %SYSTEMROOT%\System32\find.exe "${_FILE}"`
+ nsExec::Exec `cmd /c tasklist /FI "USERNAME eq %USERNAME%" /FI "PID ne $pid" /FI "IMAGENAME eq ${_FILE}" | %SYSTEMROOT%\System32\find.exe "${_FILE}"`
Pop ${_ERR}
!endif
!macroend
It seems to work, but it's based on the assumption that, without this change, the tasklist includes the installer, which might not be true.
Edit: Given this comment:
I'm wondering if there's a way for us to identify it other than "contains" and instead look for an exact match? Not sure if that's where the bug is originating though.
The weird thing is, even on brand new systems with nothing on it this bug will happen. I have verified the results and every user who reported this error has a clear prompt of the exact tasklist command while it still returns 0 inside the nsis installer. At this point i'm guessing it's find.exe or the ns exec plugin for nsis doing something weird rather than the tasklist command. The tasklist command always returns 0 as result so we can't exclude find.exe without a replacement. I'll take a look myself next week to research all of the nsis file changes but it's really hard to test as I haven't been able to replicate it. (I'm already on my 3rd VPS and still no luck)
My guess is that the above patch does not work.
We've (https://www.codux.com/) been hit quite hard with this one. Several of our users have reported failures to install our new version over the old one with the same error dialog. The uninstaller, which gets launched by the installer, fails 5 times. Launching the uninstaller manually from "Apps/Installed-Apps/Add-Remove" works.
Our investigation found several possible changes that caused this: https://github.com/electron-userland/electron-builder/pull/6551 https://github.com/electron-userland/electron-builder/pull/5902
We've forcibly ran the uninstaller in non-silent mode from installer (e.g. removed the /S) and saw it failing to remove the application directory.
Tried several workarounds. We're currently trying to define customRemoveFiles
to RMDir /r $INSTDIR
and see if it helps.
EDIT: we're adding the following .nsh script using electronBuilderConfig->nsis->include
:
!macro customRemoveFiles
DetailPrint "Removing files..."
RMDir /r $INSTDIR
!macroend
Alright, more info. Our installation contained a file with a really long file path (247 characters long). This caused the rename operation to fail on some machines (depending on the user name, where the temp dir is, etc). It probably reached the 256 limit when trying to rename it and failed.
It seems that when the uninstaller fails, the installer assumes it's because the app is still running, giving a wrong error message?
Not sure about the above statement ^, but it wouldn't surprise me if that's the culprit of many failures that were reported here.
It is possible to get same error during first clean installation if install path + file path in the installation is greater than 256.
First installer unzips files into temp directory then copies to install location. If it fails then error XYZ cannot be closed. Please close it manually and click retry to continue.
will be displayed even thought XYZ
was never installed before.
If an installation package contains really long file paths then install path can be the last drop to push file path length over 256 limit when copying files to install location. Different users have different user names or longer default install locations. It explains magic nature of reproducing this bug.
Yes, the error message is incorrect. In our case it was too long file paths.
Any workarounds exists? Now i downgrade to 22.14.13 and it works.
The 'customRemoveFiles' solution as suggested by @AviVahl did the trick for us, but I think this is not much different from downgrade to version 22.14. Using customRemoveFiles completely bypass the atomic renaming stuff (and I think it is a good thing to have... when it works). We don't have long names, nor strange charsets (like chinese), and we hit the problem ONLY on Windows 11, on Windows 10 it' going as expected (is it possible that win11 has more restriction on path length than win10???)
Same issue. Fixed with CRCCheck off https://github.com/electron-userland/electron-builder/issues/6409
StrCpy and RM and other cmd not support long file path, un.atomicRMDir
always failed.
I'm also use "include" to use custom .nsh, but customRemoveFiles
seems not run for my project, customInit
works fine.
Only delete Uninstall.exe
can skip copy program files, and install success.
!macro customInit
Delete "$INSTDIR\Uninstall*.exe"
!macroend
I'm having this issue also, tried most of the fixes suggested but the only thing that worked was reverting to "electron-builder": "22.14.13"
@mirkin The same. Only reverted to this version works as excepted.
I think this chunk of code was changed in this commit. I don't have knowledge on nsh script. maybe someone can check this. https://github.com/electron-userland/electron-builder/pull/6771/files
Weird, renaming the file to a really short name, make it work. No changes needed
I'm also having this problem, we have had no updates yet?
I need help recreating this issue via a minimum reproducible repo, then I can debug into this Ref: https://github.com/electron-userland/electron-builder/issues/6865#issuecomment-1468343573
This is still an issue
StrCpy and RM and other cmd not support long file path,
un.atomicRMDir
always failed. I'm also use "include" to use custom .nsh, butcustomRemoveFiles
seems not run for my project,customInit
works fine. Only deleteUninstall.exe
can skip copy program files, and install success.!macro customInit Delete "$INSTDIR\Uninstall*.exe" !macroend
tested this solution (workaround) on windows 11 electron builder 25.0.4 and it is working, the cause of the issue was long user name on windows account
Also having these issues with 25.0.5, seriously breaking.
StrCpy and RM and other cmd not support long file path,
un.atomicRMDir
always failed. I'm also use "include" to use custom .nsh, butcustomRemoveFiles
seems not run for my project,customInit
works fine. Only deleteUninstall.exe
can skip copy program files, and install success.!macro customInit Delete "$INSTDIR\Uninstall*.exe" !macroend
tested this solution (workaround) on windows 11 electron builder 25.0.4 and it is working, the cause of the issue was long user name on windows account
Will report back on how this goes
In my case, productName of my project is
XYZ
, it allows user to install a service namedXYZ Helper
on Windows, which runs when the operating system starts up. When I use electron-builder(23.0.3) to package(target: NSIS), the installer always showXYZ cannot be closed. Please close it manually and click retry to continue.
even after I'm sure to quit XYZ completely. Only after I also stop the service namedXYZ Helper
, this step can be processed. But XYZ Helper is not part of XYZ, which is a separated process and should not be stopped. electron-builder(22.14.13) doesn't have this problem.