Editing a pyinstaller .exe file
Asked Answered
S

2

7

I managed to create an executable file in Windows, out of a Python script using pyinstaller. I tried pyinstaller myscript.py and the build and dist folders were created, along with the .spec file

However, at a later time, I made changes to the underlying code. So what I need to do is recompile and my application works again.

But, is there a way in which I can edit the already existing application? Or do I always have to recompile after making a change?

Also, what is the purpose of the .spec file?

Spill answered 13/12, 2016 at 5:44 Comment(1)
You are not supposed to be able to edit executable binaries. I don't know what pyinstaller actually does but if it's creating a real executable (which probably isn't the case) then reverting it to readable code anywhere near the original code is borderline impossible. If it is actually just a compact Python interpreter with your script hidden somewhere in .pyc format then reverting would be possible, but a rather complicated process that is definitively not something you would want to do since you already have the code in editable format.Salespeople
F
4

Spec-file is needed to keep some options for pyinstaller to build your project such as hidden imports, attached data files, the name of output exe-file, etc. It is always created by using pyinstaller first time. Next time if you want to build your changed project use this command specifying the spec-file:

$ pyinstaller myscript.spec

For more information about spec-files read documentation: https://pyinstaller.readthedocs.io/en/stable/spec-files.html

Flagelliform answered 13/12, 2016 at 8:43 Comment(0)
E
0

Rather than editing already complied files, a better way to change the content of your application after being created without actually recompiling the whole code would be to create the executable of a another python file in such a way that it reads the content of your code file at the time of execution.

For instance, consider making an additional file "dummy_python_file.py" that

  1. Reads the file containing actual code to be executed.(say from "actual_code_file.py")
  2. Uses exec function (exec statement incase of python2) to execute the code of the "actual_code_file.py"

Now, make executable of this "dummy_python_file.py" instead of "actual_code_file.py" using pyinstaller as usual. Now this newly created "dummy_python_file.exe" will interpret the code from your "actual_code_file.py" every-time you execute the application. This way you won't need to recompile the updated file repeatedly. ( p.s. also see the Note on exec command at the end. )

Example:

the dummy_python_file.exe created from dummy_python_file.py having below code will always execute whatever code is present in "actual_code_file.py" at the moment when "dummy_python_file.exe" is initiated. ( i.e. you would be able execute the code after creating that ".exe" file.

# python 3.12.3
# dummy_python_file.py
# This file has to be converted to ".exe"

import os, sys

# Fetches the directory of executable "dummy_python_file.exe"
# at the moment when "dummy_python_file.exe" is ran.
# This is done so as to find the "actual_code_file.py" relatively
sys.path.append(os.getcwd())

# Opens and reads the "actual_code_file.py"
exceutable_code_str = ""
try:
    with open("./actual_code_file.py") as _code:
        executable_code_str = _code.read()
except FileNotFoundError as err:
    print(err) #In python 2: print err
    input("") ## Will avoid console window from abruptly closing after displaying error.

# Executes the code string.
exec(executable_code_str)

# In python 2: exec executable_code_str

Working demo:

Say our "actual_code_file.py" has some code as follows before making the ".exe" file:

# python 3.12.3
# actual_code_file.py
# This file can an be edited even after making "dummy_python_file.exe"

print("Hello World!")

input("") ## Will avoid console window from abruptly closing after displaying error.

Then, ... ( short gif uploaded here ): Editable EXE.gif

<img src="https://archive.org/download/editable-exe/Editable%20EXE.gif" alt="Editable EXE.gif"  width="550" />

Ideally it should work for nested cases too. Just make sure that all the libraries were properly added during making of ".exe" file from pyinstaller.

In more general sense, this is just like creating a static isolated python environment that runs a designated file.

!Note

Usage of exec function is sort of considered to be dangerous, since in case somebody apart from you also might have access to the "actual_code_file.py" and that somebody might intent to inject some harmful code. ( see more on this here or here ). A simple workaround this would be to make the "dummy_python_file.py" in such a way that it stores a encrypted copy of "actual_code_file.py" first time the "dummy_python_file.exe" file is ran and stores it and later compares the text from that encrypted file with "actual_code_file.py" each time the "dummy_python_file.exe" is ran and asks for a password incase some changes are made in the code of "actual_code_file.py" and if authenticated updates the stored encrypted file. But, as long as you are are sure that only you are going to be the user it be should be fine either way.

Eloquence answered 11/6, 2024 at 10:5 Comment(5)
Welcome to SO. You wrote a rather long-ish answer that managed to answer not a single question in the OP. While I'm sure you only want to share some great stuff, please write answers that address the question. You can always edit to improve your post.Hardnosed
No need to apologize. You seem to answer the how? but not whether? and why? Questions lacking focus (like this one) give rise to partial answers. They make it hard to accept a single, best answer. Best to avoid writing partial answers.Hardnosed
@Hardnosed , I apologise if that's the case. I wanted to answer this part of the asked question: "But, is there a way in which I can edit the already existing application? Or do I always have to recompile after making a change? p.s. I have edited the answer to make the scope of answer a bit clearer.Eloquence
Oh...okay, Thanks for the clarification, I didn't realise in that sense.Eloquence
@Eitan Considering the intent of OP's question, it seems that OP simply wishes avoid the step of (re)compiling the whole python environment along with their (updated) code as done by pyinstaller which may take few minutes in general (and at a times, OP might just want change a single statement of a their (probably) large code) and thus wishes to avoid the inherent hassle, (and so asks the question). So, I guess OP meant to ask if actually recompiling again is their only option or is there a possible workaround to get the exe to run updated code.Eloquence

© 2022 - 2025 — McMap. All rights reserved.