Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PermissionError: [Errno 13] Permission denied --onefile FileIO Issue #6467

Closed
3 of 6 tasks
fatihkabakk opened this issue Dec 27, 2021 · 33 comments
Closed
3 of 6 tasks
Assignees

Comments

@fatihkabakk
Copy link

fatihkabakk commented Dec 27, 2021

Description of the issue

When creating single exe file in --onefile mode, the file \lib\site-packages\PyInstaller\building\api.py at line 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;

  • (500+ loops)
while True:
    try:
        with open(self.name, 'ab') as outf, open(self.pkg.name, 'rb') as inf:
            shutil.copyfileobj(inf, outf, length=64 * 1024)
            break
    except PermissionError:
        pass
  • Better Fix (but needs importing time module)
while True:
    try:
        with open(self.name, 'ab') as outf, open(self.pkg.name, 'rb') as inf:
            shutil.copyfileobj(inf, outf, length=64 * 1024)
            break
    except PermissionError:
        time.sleep(0.05)

My Program's Import Details (None of Importance I think, see A minimal example program which shows the error)

import threading
from tkinter import *
import tkinter.messagebox as messagebox
from tkinter import filedialog
from PIL import Image, ImageTk
from os.path import expanduser

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:

pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip

Make sure everything is packaged correctly

  • start with clean installation
  • use the latest development version
  • Run your frozen program from a command window (shell) — instead of double-clicking on it
  • Package your program in --onedir mode
  • Package without UPX, say: use the option --noupx or set upx=False in your .spec-file
  • Repackage you application in verbose/debug mode. For this, pass the option --debug to pyi-makespec or pyinstaller or use EXE(..., debug=1, ...) in your .spec file.

A minimal example program which shows the error

  • The error raises even with an empty .py file
  • x.py is empty
  • When run pyinstaller --onefile x.py, raises the error.

Stacktrace / full error message

30364 INFO: Appending PKG archive to EXE
Traceback (most recent call last):
  File "C:\Users\Fatih\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\Fatih\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Users\Fatih\AppData\Local\Programs\Python\Python39\Scripts\pyinstaller.exe\__main__.py", line 7, in <module>
  File "C:\Users\Fatih\AppData\Local\Programs\Python\Python39\lib\site-packages\PyInstaller\__main__.py", line 124, in run
    run_build(pyi_config, spec_file, **vars(args))
  File "C:\Users\Fatih\AppData\Local\Programs\Python\Python39\lib\site-packages\PyInstaller\__main__.py", line 58, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
  File "C:\Users\Fatih\AppData\Local\Programs\Python\Python39\lib\site-packages\PyInstaller\building\build_main.py", line 827, in main
    build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
  File "C:\Users\Fatih\AppData\Local\Programs\Python\Python39\lib\site-packages\PyInstaller\building\build_main.py", line 759, in build
    exec(code, spec_namespace)
  File "C:\Users\Fatih\Desktop\txtToCsvConverter\Txt To Csv Converter.spec", line 24, in <module>
    exe = EXE(
  File "C:\Users\Fatih\AppData\Local\Programs\Python\Python39\lib\site-packages\PyInstaller\building\api.py", line 518, in __init__
    self.__postinit__()
  File "C:\Users\Fatih\AppData\Local\Programs\Python\Python39\lib\site-packages\PyInstaller\building\datastruct.py", line 155, in __postinit__
    self.assemble()
  File "C:\Users\Fatih\AppData\Local\Programs\Python\Python39\lib\site-packages\PyInstaller\building\api.py", line 734, in assemble
    with open(self.name, 'ab') as outf:
PermissionError: [Errno 13] Permission denied: 'C:\\Users\\Fatih\\Desktop\\txtToCsvConverter\\dist\\Txt To Csv Converter.exe'

Please also see https://github.com/pyinstaller/pyinstaller/wiki/How-to-Report-Bugs
for more about what would use to solve the issue.

@fatihkabakk fatihkabakk added the triage Please triage and relabel this issue label Dec 27, 2021
@rokm
Copy link
Member

rokm commented Dec 27, 2021

Do you have an anti-virus program running on the system? This looks like an AV blocking the access to the exe file...

@fatihkabakk
Copy link
Author

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.

@fatihkabakk
Copy link
Author

Also, I used this program in the past, and it was working. It got broken after some changes I think.

@rokm
Copy link
Member

rokm commented Dec 27, 2021

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...

@Aarekaz
Copy link

Aarekaz commented Jan 1, 2022

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.

@bwoodsend
Copy link
Member

bwoodsend commented Jan 1, 2022

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.

@Aarekaz
Copy link

Aarekaz commented Jan 1, 2022

@bwoodsend No I have not. Which version do you recommend?

@Aarekaz
Copy link

Aarekaz commented Jan 1, 2022

I created the exe after using 4.4 build of py installer, but when I run it, I get this error
image

I used this command :
image

@rokm
Copy link
Member

rokm commented Jan 1, 2022

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...

@Aarekaz
Copy link

Aarekaz commented Jan 2, 2022

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)] ```

@bwoodsend
Copy link
Member

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.

@rokm
Copy link
Member

rokm commented Jan 2, 2022

@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.

@rokm
Copy link
Member

rokm commented Jan 2, 2022

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
Copy link

Aarekaz commented Jan 2, 2022

@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.

I will try this. Do I add all those parameters in the same line?

@Aarekaz
Copy link

Aarekaz commented Jan 2, 2022

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?

Haven't tried this. Will look into it.

@ArtemConstantinov
Copy link

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

@DervishD
Copy link

@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.

@DervishD
Copy link

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?

@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.

@DervishD
Copy link

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.

@bwoodsend
Copy link
Member

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.

@bwoodsend
Copy link
Member

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.

@DervishD
Copy link

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.

@DervishD
Copy link

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.

@bwoodsend
Copy link
Member

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).

@rokm
Copy link
Member

rokm commented Feb 26, 2022

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).

@DervishD
Copy link

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.

@bwoodsend
Copy link
Member

Changing the suffix it is. I'll try to resist the urge to set the temporary suffix to something immature like .msdefenderisstupid.

@bwoodsend bwoodsend removed the triage Please triage and relabel this issue label Feb 26, 2022
@bwoodsend bwoodsend self-assigned this Feb 26, 2022
@DervishD
Copy link

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.

bwoodsend added a commit to bwoodsend/pyinstaller that referenced this issue Feb 26, 2022
Whenever an intermediate/temporary executable file needs to be written, give it
the filename extension .notanexecutable instead of .exe. This fools Microsoft
Defender into thinking that the file is not an executable which requires
scanning. Even though the scan does not quarantine the EXE, its being opened and
read by Defender means that it can't be opened in write mode by a later step in
the executable assembly process.

I'm choosing to add this suffix on all platforms despite it only being needed on
Windows so as to minimise platform dependent logic.
bwoodsend added a commit to bwoodsend/pyinstaller that referenced this issue Feb 28, 2022
Whenever an intermediate/temporary executable file needs to be written, give it
the filename extension .notanexecutable instead of .exe. This fools Microsoft
Defender into thinking that the file is not an executable which requires
scanning. Even though the scan does not quarantine the EXE, its being opened and
read by Defender means that it can't be opened in write mode by a later step in
the executable assembly process.

I'm choosing to add this suffix on all platforms despite it only being needed on
Windows so as to minimise platform dependent logic.
bwoodsend added a commit to bwoodsend/pyinstaller that referenced this issue Feb 28, 2022
Whenever an intermediate/temporary executable file needs to be written, give it
the filename extension .notanexecutable instead of .exe. This fools Microsoft
Defender into thinking that the file is not an executable which requires
scanning. Even though the scan does not quarantine the EXE, its being opened and
read by Defender means that it can't be opened in write mode by a later step in
the executable assembly process.

I'm choosing to add this suffix on all platforms despite it only being needed on
Windows so as to minimise platform dependent logic.
@bwoodsend
Copy link
Member

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.

@DervishD
Copy link

@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.

@DervishD
Copy link

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.

@bwoodsend
Copy link
Member

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.

bwoodsend added a commit to bwoodsend/pyinstaller that referenced this issue Feb 28, 2022
Whenever an intermediate/temporary executable file needs to be written, give it
the filename extension .notanexecutable instead of .exe. This fools Microsoft
Defender into thinking that the file is not an executable which requires
scanning. Even though the scan does not quarantine the EXE, its being opened and
read by Defender means that it can't be opened in write mode by a later step in
the executable assembly process.

I'm choosing to add this suffix on all platforms despite it only being needed on
Windows so as to minimise platform dependent logic.
bwoodsend added a commit that referenced this issue Mar 1, 2022
Whenever an intermediate/temporary executable file needs to be written, give it
the filename extension .notanexecutable instead of .exe. This fools Microsoft
Defender into thinking that the file is not an executable which requires
scanning. Even though the scan does not quarantine the EXE, its being opened and
read by Defender means that it can't be opened in write mode by a later step in
the executable assembly process.

I'm choosing to add this suffix on all platforms despite it only being needed on
Windows so as to minimise platform dependent logic.
bwoodsend added a commit to bwoodsend/pyinstaller that referenced this issue Mar 1, 2022
Whenever an intermediate/temporary executable file needs to be written, give it
the filename extension .notanexecutable instead of .exe. This fools Microsoft
Defender into thinking that the file is not an executable which requires
scanning. Even though the scan does not quarantine the EXE, its being opened and
read by Defender means that it can't be opened in write mode by a later step in
the executable assembly process.

I'm choosing to add this suffix on all platforms despite it only being needed on
Windows so as to minimise platform dependent logic.
@bwoodsend
Copy link
Member

Fixed in #6629. Next release will probably be in a few days so you shouldn't have to wait long.

bwoodsend added a commit that referenced this issue Mar 1, 2022
Whenever an intermediate/temporary executable file needs to be written, give it
the filename extension .notanexecutable instead of .exe. This fools Microsoft
Defender into thinking that the file is not an executable which requires
scanning. Even though the scan does not quarantine the EXE, its being opened and
read by Defender means that it can't be opened in write mode by a later step in
the executable assembly process.

I'm choosing to add this suffix on all platforms despite it only being needed on
Windows so as to minimise platform dependent logic.
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants