Closed fatihkabakk closed 2 years ago
Do you have an anti-virus program running on the system? This looks like an AV blocking the access to the exe file...
Do you have an anti-virus program running on the system? This looks like an AV blocking the access to the exe file...
I just have windows-defender, and tried with disabling it, too. However, issue still exists.
Also, I used this program in the past, and it was working. It got broken after some changes I think.
Also, I used this program in the past, and it was working.
The rest of your system is not exactly frozen in time, either.
It got broken after some changes I think.
If you can pinpoint the breaking change (using git bisect), we can investigate further.
Otherwise, I'm inclined to believe that this is specific to your system/environment; if it was the case of a file not being closed fast enough, as you suspect, then our CI would be falling apart as well, and we'd be likely seeing more reports like this. The ones that we do get, however, typically boil down to AV, e.g., #6463.
But even if this is a legit issue in PyInstaller, I don't think retry loop is a proper solution...
I am also having the permission denied issue:
350 INFO: Python: 3.9.0
350 INFO: Platform: Windows-10-10.0.22000-SP0
352 INFO: wrote C:\Users\anura\Desktop\GUI\gui.spec
359 INFO: UPX is not available.
361 INFO: Extending PYTHONPATH with paths
['C:\\Users\\anura\\Desktop\\GUI']
852 INFO: checking Analysis
2789 INFO: checking PYZ
4160 INFO: checking PKG
4163 INFO: Bootloader c:\users\anura\desktop\gui\venv\lib\site-packages\PyInstaller\bootloader\Windows-64bit\run.exe
4163 INFO: checking EXE
4164 INFO: Building EXE because EXE-00.toc is non existent
4164 INFO: Building EXE from EXE-00.toc
4165 INFO: Copying bootloader EXE to C:\Users\anura\Desktop\GUI\build\gui\gui.exe
4175 INFO: Copying icon to EXE
4175 INFO: Copying icons from ['c:\\users\\anura\\desktop\\gui\\venv\\lib\\site-packages\\PyInstaller\\bootloader\\images\\icon-console.ico']
4177 INFO: Writing RT_GROUP_ICON 0 resource with 104 bytes
4177 INFO: Writing RT_ICON 1 resource with 3752 bytes
4178 INFO: Writing RT_ICON 2 resource with 2216 bytes
4178 INFO: Writing RT_ICON 3 resource with 1384 bytes
4178 INFO: Writing RT_ICON 4 resource with 37019 bytes
4179 INFO: Writing RT_ICON 5 resource with 9640 bytes
4179 INFO: Writing RT_ICON 6 resource with 4264 bytes
4180 INFO: Writing RT_ICON 7 resource with 1128 bytes
4188 INFO: Copying 0 resources to EXE
4188 INFO: Emedding manifest in EXE
4190 INFO: Updating manifest in C:\Users\anura\Desktop\GUI\build\gui\gui.exe
4191 INFO: Updating resource type 24 name 1 language 0
4200 INFO: Appending PKG archive to EXE
Traceback (most recent call last):
File "C:\Users\anura\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Users\anura\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\Users\anura\Desktop\GUI\venv\Scripts\pyinstaller.exe\__main__.py", line 7, in <module>
File "c:\users\anura\desktop\gui\venv\lib\site-packages\PyInstaller\__main__.py", line 124, in run
run_build(pyi_config, spec_file, **vars(args))
File "c:\users\anura\desktop\gui\venv\lib\site-packages\PyInstaller\__main__.py", line 58, in run_build
PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
File "c:\users\anura\desktop\gui\venv\lib\site-packages\PyInstaller\building\build_main.py", line 782, in main
build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
File "c:\users\anura\desktop\gui\venv\lib\site-packages\PyInstaller\building\build_main.py", line 714, in build
exec(code, spec_namespace)
File "C:\Users\anura\Desktop\GUI\gui.spec", line 23, in <module>
exe = EXE(pyz,
File "c:\users\anura\desktop\gui\venv\lib\site-packages\PyInstaller\building\api.py", line 507, in __init__
self.__postinit__()
File "c:\users\anura\desktop\gui\venv\lib\site-packages\PyInstaller\building\datastruct.py", line 155, in __postinit__
self.assemble()
File "c:\users\anura\desktop\gui\venv\lib\site-packages\PyInstaller\building\api.py", line 719, in assemble
with open(self.name, 'ab') as outf:
PermissionError: [Errno 13] Permission denied: 'C:\\Users\\anura\\Desktop\\GUI\\build\\gui\\gui.exe'
I tried disabling the antivirus but it's the same.
Does bouncing back a PyInstaller version or two make any difference?
Edit: I see you tried with develop
too so I imagine that the answer is no.
@bwoodsend No I have not. Which version do you recommend?
I created the exe after using 4.4 build of py installer, but when I run it, I get this error
I used this command :
I created the exe after using 4.4 build of py installer, but when I run it, I get this error
You'd get that error with any version of PyInstaller; what you need to do is ensure that data files of qtstylish
package are collected, for example by adding --collect-data qtstylish
to your pyinstaller command.
Back to the original topic, I suppose 4.4 working means that changes made in #6252 (and released as part of 4.6) might have made us less resilient to AV software's interference: previously, we created a copy of stock bootloader exe to a temporary file, then added icon, resources and manifest. Then we copied the modified exe from the temporary location into final destination and at the same time appended the pkg (without closing the file descriptor in between these two steps). So I suppose if AV kicks in after manifest is embedded, but locks the file only for modification (i.e., still allowing reading/copying), we might copy the prepared bootloader without issues in spite of the AV. And because both the copy and PKG appending is done without closing the file descriptor in between, AV may kick in again only after the whole procedure is complete.
In the simplified, post-#6252 pipeline, we make a copy of stock bootloader exe to the file destination, add icon, resources and manifest, and then append PKG to it. This means that if AV kicks in after manifest is embedded and locks the file for writing, we may fail to open it again in append mode to append the PKG to it.
So perhaps we should go back to using an intermediate temporary file to prepare the bootloader...
Now I am getting this error :
PandasGUI INFO — pandasgui.gui — Opening PandasGUI
qt.svg: Cannot open file 'C:/Users/anura/AppData/Local/Temp/_MEI328882/pandasgui/resources/images/case-sensitive.svg', because: The system cannot find the path specified.
qt.svg: Cannot open file 'C:/Users/anura/AppData/Local/Temp/_MEI328882/pandasgui/resources/images/case-sensitive.svg', because: The system cannot find the path specified.
qt.svg: Cannot open file 'C:/Users/anura/AppData/Local/Temp/_MEI328882/pandasgui/resources/images/regex.svg', because: The system cannot find the path specified.
qt.svg: Cannot open file 'C:/Users/anura/AppData/Local/Temp/_MEI328882/pandasgui/resources/images/regex.svg', because: The system cannot find the path specified.
qt.svg: Cannot open file 'C:/Users/anura/AppData/Local/Temp/_MEI328882/pandasgui/resources/images/match-exactly.svg', because: The system cannot find the path specified.
qt.svg: Cannot open file 'C:/Users/anura/AppData/Local/Temp/_MEI328882/pandasgui/resources/images/match-exactly.svg', because: The system cannot find the path specified.
qt.svg: Cannot open file 'C:/Users/anura/AppData/Local/Temp/_MEI328882/pandasgui/resources/images/arrow-up.svg', because: The system cannot find the path specified.
qt.svg: Cannot open file 'C:/Users/anura/AppData/Local/Temp/_MEI328882/pandasgui/resources/images/arrow-up.svg', because: The system cannot find the path specified.
qt.svg: Cannot open file 'C:/Users/anura/AppData/Local/Temp/_MEI328882/pandasgui/resources/images/arrow-down.svg', because: The system cannot find the path specified.
qt.svg: Cannot open file 'C:/Users/anura/AppData/Local/Temp/_MEI328882/pandasgui/resources/images/arrow-down.svg', because: The system cannot find the path specified.
qt.svg: Cannot open file 'C:/Users/anura/AppData/Local/Temp/_MEI328882/pandasgui/resources/images/close.svg', because: The system cannot find the path specified.
qt.svg: Cannot open file 'C:/Users/anura/AppData/Local/Temp/_MEI328882/pandasgui/resources/images/close.svg', because: The system cannot find the path specified.
Traceback (most recent call last):
File "gui.py", line 308, in <module>
File "gui.py", line 266, in show_img_gui
File "pandasgui\gui.py", line 468, in show
File "pandasgui\gui.py", line 71, in __init__
File "pandasgui\gui.py", line 161, in init_ui
File "pandasgui\gui.py", line 251, in apply_settings
File "qtstylish\qtstylish.py", line 27, in light
ImportError: cannot import name 'qtstylish_rc' from 'compiled' (unknown location)
[22980] Failed to execute script 'gui' due to unhandled exception!
[process exited with code 1 (0x00000001)] ```
So perhaps we should go back to using an intermediate temporary file to prepare the bootloader...
I'd rather see if #6469 and #6470 solve our problems before we start chucking temporary files into the mix.
@Aarekaz
Now I am getting this error :
ImportError: cannot import name 'qtstylish_rc' from 'compiled' (unknown location)
So you need to also add --hiddenimport qtstylish.compiled.qtstylish_rc
to your pyinstaller command (or a --collect-submodules qtstylish
, although I think qtstylish_rc
is the only problematic import).
You should probably also add a --collect-data pandasgui
to your PyInstaller command to avoid warnings about missing svg files.
At any rate, this has nothing to do with the permission denied problem, so if you have any further problems, open a new discussion.
So perhaps we should go back to using an intermediate temporary file to prepare the bootloader...
I'd rather see if #6469 and #6470 solve our problems before we start chucking temporary files into the mix.
Yeah, I agree. It could be that AV is forcing a scan due to the tainted hash of the original bootloader copy (and suppose that it fails the race when we are embedding icon, resources and manifest, so it scans it after that). I wish I could reproduce this, but no luck...
@fatihkabakk @Aarekaz Does the permission-denied problem also occur if you add --debug bootloader
and/or --windowed
to your PyInstaller command (i.e., when run_d.exe
, runw.exe
or runw_d.exe
are used). EDIT: Or, if you rebuild the bootloader instead of using the pre-compiled ones?
@Aarekaz
Now I am getting this error :
ImportError: cannot import name 'qtstylish_rc' from 'compiled' (unknown location)
So you need to also add
--hiddenimport qtstylish.compiled.qtstylish_rc
to your pyinstaller command (or a--collect-submodules qtstylish
, although I thinkqtstylish_rc
is the only problematic import).You should probably also add a
--collect-data pandasgui
to your PyInstaller command to avoid warnings about missing svg files.At any rate, this has nothing to do with the permission denied problem, so if you have any further problems, open a new discussion.
I will try this. Do I add all those parameters in the same line?
So perhaps we should go back to using an intermediate temporary file to prepare the bootloader...
I'd rather see if #6469 and #6470 solve our problems before we start chucking temporary files into the mix.
Yeah, I agree. It could be that AV is forcing a scan due to the tainted hash of the original bootloader copy (and suppose that it fails the race when we are embedding icon, resources and manifest, so it scans it after that). I wish I could reproduce this, but no luck...
@fatihkabakk @Aarekaz Does the permission-denied problem also occur if you add
--debug bootloader
and/or--windowed
to your PyInstaller command (i.e., whenrun_d.exe
,runw.exe
orrunw_d.exe
are used). EDIT: Or, if you rebuild the bootloader instead of using the pre-compiled ones?
Haven't tried this. Will look into it.
The simple solution is to not give a exe
extension to the file at the time when adding bytes to it
for fast solving this issue on Windows 10 I replaced lines: 429
of ...\site-packages\PyInstaller\building\api.py
from :
self.name += '.exe'
to :
self.name += '.e' # can be whatever even an uuid4
After all is done, I just renamed the executable file.
p.s.
In case if system scream as can not modify file name to .exe
just write it to zip archive with relevant name/extension and after unzip it if required
@ArtemConstantinov thanks for the fix. Effectively that is the problem, the .exe
suffix, for some reason. I tried to disable the AV and it still failed until I applied your fix.
And of course, I can confirm this bug using version 4.9
on Windows 10 21H2.
So perhaps we should go back to using an intermediate temporary file to prepare the bootloader...
I'd rather see if #6469 and #6470 solve our problems before we start chucking temporary files into the mix.
Yeah, I agree. It could be that AV is forcing a scan due to the tainted hash of the original bootloader copy (and suppose that it fails the race when we are embedding icon, resources and manifest, so it scans it after that). I wish I could reproduce this, but no luck...
@fatihkabakk @Aarekaz Does the permission-denied problem also occur if you add
--debug bootloader
and/or--windowed
to your PyInstaller command (i.e., whenrun_d.exe
,runw.exe
orrunw_d.exe
are used). EDIT: Or, if you rebuild the bootloader instead of using the pre-compiled ones?
@rokm I just tried this and the same error happens. The only solution is to get rid of the .exe
suffix, because for the life of me disabling the AV doesn't seem to have any effect. Probably Windows Defender does not get disabled, no matter if you tell it so.
As you can see, the problem has been fixed (or rather, dealt with, as it's not a bug on Nuitka
or PyInstaller
, but a weird interaction) on Nuitka.
I've made a very crude modification to PyInstaller
inspired by the fix in Nuitka
, and it works after the first retry, waiting for one second. Of course it is VERY crude and a proper solution should be written because I'm not familiar with the code and I don't know the side effects of adding a retry loop in building/apy.py
.
I'd prefer the changing the suffix option to injecting pauses and retries. It sounds less likely spring back at us the next time an AV engine update occurs.
One question to those saying that they've disabled their antivirus: Which did you disable? It's rare that Windows machines only have one. Microsoft always puts theirs on but most laptop providers are normally endorsed to install some other (invariably the most useless) one too. e.g. Dell and Lenovo come with MacAffee installed and I believe that HPs come with AVG.
A change in suffix and a later rename sounds good, too, as long as it does not fires the race condition in Windows Defender. And yes, that race should not happen in the first place, and it's not PyInstaller
fault but I think it is quite a common problem and it's better if PyInstaller
handles it.
My only real concern with pausing and retrying is the duration of the pause. To me, one second sounds great, but timing a race condition can lead to problems later, you are right.
One question to those saying that they've disabled their antivirus: Which did you disable? It's rare that Windows machines only have one. Microsoft always puts theirs on but most laptop providers are normally endorsed to install some other (invariably the most useless) one too. e.g. Dell and Lenovo come with MacAffee installed and I believe that HPs come with AVG.
I only have Windows Defender, which BTW is quite difficult to completely disable, and the problem still persists even when disabling it, adding the involved folders and binaries to the exceptions list, or even killing the service. And it's not a good solution IMHO, users should not have to disable their AV in order to run a program.
And it's not a good solution IMHO, users should not have to disable their AV in order to run a program.
Yeah I agree. I just idealistically say that an AV issue should be fixed on the AV's side or the AV should be replaced instead of ducked and dodged around by any compiler or build tool that happens to want to copy an executable file and then modify it - particularly when the AV is provided by a company with as many resources as Microsoft and the build tool is maintained by two volunteers who don't even use Windows. Rant ranty rant rant...
I think that this magic pause explains things a bit though. Presumably, when PyInstaller first writes the executable an AV scan is triggered. The AV has to open the file in read mode whilst it scans it and, because on Windows attempting to write to a file that is already open by some other application leads to a permission error, PyInstaller hits this error when it tries to start modifying it again. The short delay is presumably just how long it takes for the scan to complete and the AV to close the file so that PyInstaller can start writing to it again. That would at least explain why #6468 did anything at all - after the 500th or so attempt to open the file, the AV scan had finished so the next attempt worked. So I guess, all we really have to do is either keep the file handle open from start to finish (although I don't think that the bit of Windows API that adds the icon allows this) or just accommodate this pause by merging #6468 (preferably with some time.sleep()
s).
I don't think magic pause is a solution, because we (re)open the file for modification in several places, and the race can occur at any of them (e.g., this report is about appending PKG to exe, while #6506 is about a later stage, when we modify the build timestamp and set exe chekcsum). I.e., there's no reason to believe that re-scan does not occur after every modification.
I'd also prefer avoiding the delay loops at every point where we (re)open the file, because those involve different APIs and different abstraction levels (raw open, WinAPI, pefile).
I find the idea of changing/removing suffix during the assembly process and then renaming the file the least invasive one. That relies on the current behavior of the AV, though (i.e., picking on the file based on its extension instead of the PE header).
And it's not a good solution IMHO, users should not have to disable their AV in order to run a program.
Yeah I agree. I just idealistically say that an AV issue should be fixed on the AV's side or the AV should be replaced instead of ducked and dodged around by any compiler or build tool that happens to want to copy an executable file and then modify it - particularly when the AV is provided by a company with as many resources as Microsoft and the build tool is maintained by two volunteers who don't even use Windows. Rant ranty rant rant...
I think that this magic pause explains things a bit though. Presumably, when PyInstaller first writes the executable an AV scan is triggered. The AV has to open the file in read mode whilst it scans it and, because on Windows attempting to write to a file that is already open by some other application leads to a permission error, PyInstaller hits this error when it tries to start modifying it again. The short delay is presumably just how long it takes for the scan to complete and the AV to close the file so that PyInstaller can start writing to it again. That would at least explain why #6468 did anything at all - after the 500th or so attempt to open the file, the AV scan had finished so the next attempt worked. So I guess, all we really have to do is either keep the file handle open from start to finish (although I don't think that the bit of Windows API that adds the icon allows this) or just accommodate this pause by merging #6468 (preferably with some
time.sleep()
s).
It's not a rant, I totally agree with you, Microsoft should do their laundry here and fix this issue because it's not normal at all you cannot modify an executable you just created. This said, we both know they are not going to fix it anytime soon and meanwhile it's PyInstaller
the one paying the potential consequences by losing users who find this problem.
I agree with @rokm and as long as the AV does not look at the headers but the suffix, it's better to just avoid that suffix until the very last file write. I think it's quite pragmatic and it's easier to implement.
Changing the suffix it is. I'll try to resist the urge to set the temporary suffix to something immature like .msdefenderisstupid
.
Changing the suffix it is. I'll try to resist the urge to set the temporary suffix to something immature like
.msdefenderisstupid
.
Can I +1 that temporary suffix? Because I utterly love it, maybe out of immaturity on my part but 🤣
Now seriously, thanks a lot for dealing with this.
Can someone with this issue give the fix a test?
pip install https://github.com/bwoodsend/pyinstaller/archive/refs/heads/dodge-exe-suffix.zip
Then try building something as normal.
@bwoodsend , your fix is quite similar to the one I was testing, and it works perfectly in a computer where I could reproduce the problem all the time. Thanks A LOT for the fix! That was fast!
If you need me to perform any other test, I've set up a separate venv for testing this in one of the machines where I can reproduce the problem.
Can someone with this issue give the fix a test?
pip install https://github.com/bwoodsend/pyinstaller/archive/refs/heads/dodge-exe-suffix.zip
Then try building something as normal.
BTW, I just noticed a typo in building/api.py
, and since you will be modifying related code:
# Embed the manifest into the executable.
if self.embed_manifest:
logger.info("Emedding manifest in EXE")
self.manifest.update_resources(build_name, [1])
Notice Emedding rather than Embedding. If you prefer I open a new PR for this issue so it is addressed separately, just let me know.
I wouldn't bother chasing spelling errors. PyInstaller is littered with them. One day I'll get bored enough to run codespell
on the whole repo and fix the lot.
Fixed in #6629. Next release will probably be in a few days so you shouldn't have to wait long.
Description of the issue
When creating single exe file in
--onefile
mode, the file\lib\site-packages\PyInstaller\building\api.py
atline 734
,with open(self.name, 'ab') as outf:
the program raises a PermissionError. I have tried adding while loop and an exception catcher, it looped 509 times before properly opening the file. I suppose that file does not get closed completely before the append process starts. I would make a pull request about this problem, but I'm not completely sure how to solve this problem properly. It can be solved without including sleep, but then program loops so many times (509 as stated before). My fix is added below;time
module)My Program's Import Details (None of Importance I think, see A minimal example program which shows the error)
Context information (for bug reports)
Output of
pyinstaller --version
:4.7
(Tried with development version (5.0), too)Version of Python: 3.9
Platform: Windows (Turkish Q) (chcp 65001 [utf-8])
How you installed Python: python.org/downloads
Did you also try this on another platform? Does it work there? No, not relevant.
try the latest development version, using the following command:
Make sure everything is packaged correctly
--noupx
or setupx=False
in your .spec-file--debug
topyi-makespec
orpyinstaller
or useEXE(..., debug=1, ...)
in your .spec file.A minimal example program which shows the error
.py
filepyinstaller --onefile x.py
, raises the error.Stacktrace / full error message
Please also see https://github.com/pyinstaller/pyinstaller/wiki/How-to-Report-Bugs for more about what would use to solve the issue.