0

I tried to create an exe file, which is able to create json files and store it inside itself. The code of this minimal program looks like this:

import json
from os import listdir
from os.path import isfile, join
import os
from pathlib import Path

basedir = Path(__file__).parent.absolute()

def files_in_directory(path):
    """find all files in directory"""
    return [f for f in listdir(path) if isfile(join(path, f))]

def save_json(data):
    file = os.path.join(basedir, "data") + "/" + data + ".json"
    with open(file, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=4, ensure_ascii=False, sort_keys=False)


while True:
    user_input = input("Input:")
    if user_input == "stop":
        break
    elif user_input == "add":
        number_input = input("Data:")
        save_json(number_input)
    elif user_input == "show":
        print(files_in_directory(os.path.join(basedir, "data")))
    else:
        print("User input unkown")

The json files are stored inside the data folder, which is in the same directory as the python file. I created the exe file with pyinstaller using the following spec-file. The data folder is included in the program.

# -*- mode: python ; coding: utf-8 -*-


block_cipher = None


a = Analysis(
    ['test.py'],
    pathex=[],
    binaries=[],
    datas=[("data", "data")],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='test',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
app = BUNDLE(
    exe,
    name='tesst.app',
    icon=None,
    bundle_identifier=None,
)

When I run the program, I can store and load the names of all data, which has been stored in this setting. But when I close the program and start it again, all data is gone. Is there a way, which keeps the data stored inside the exe file after closing the file?

Mazze
  • 383
  • 3
  • 13
  • [This](https://stackoverflow.com/questions/5316152/store-data-in-executable) is related to your question. Based on these issues, you may want to explain why data has to be stored in an exe file. – Confused Learner Jul 30 '22 at 18:32
  • I want to save the data in a fixed location without being able to easily delete it from the program. – Mazze Jul 30 '22 at 19:40
  • What do you mean by "easily"? You can either make it so that the program deletes it or not, which in no way prevents other programs from deleting it. Is this a question regarding software piracy or encryption of data? You can also split your program so that you need elevated rights to (over)write the file. Then you only give these rights to one part (exe file) of your program, or you create a hidden file. – Confused Learner Jul 30 '22 at 19:58
  • it should simply be a central place where the data is stored. The content in this directory should be modifiable only from the program. – Mazze Jul 30 '22 at 20:13
  • 1
    About storing _in the exe file_: you will not be able to save it _in_ the exe, because you would have to repack your exe. But you can store your file near it, in the same folder, etc. – Ibolit Jul 30 '22 at 20:17
  • Is it possible to add like a config file to the exe file, which includes the the save path to the data folder and then change the content of this config file (which is included when building the exe file) from inside the program. so that the changes are retained after quitting the program – Mazze Jul 30 '22 at 21:22

1 Answers1

0

When your code is "bundled", i.e. when your code is run from the compiled exe file, the __file__ variable does not point to the location of the exe. To find out the location of your exe file, you can use sys.executable and sys.argv[0]. You can find out more here: https://pyinstaller.org/en/stable/runtime-information.html

As far as I remember, __file__ will point to a temporary location where your bundled file was unzipped to. After you quit your exe, that temp location is deleted along with your data

Ibolit
  • 9,218
  • 7
  • 52
  • 96
  • unfortunately `sys.executable` and `sys.argv[0]` both do not work. However, I was not aware that `__file__` point to a temporary location. Thanks for the hint – Mazze Jul 30 '22 at 19:42
  • What do you mean by "do not work"? What do they produce? And I will also repeat in this comment, you will not be able to save data _in_ your exe, but you can save it _near_ it, like in the same folder – Ibolit Jul 30 '22 at 20:19
  • The say that the given directory does not exist as it is "inside" the exe file. But I will store the data in a hidden file in the same folder as the exe file – Mazze Jul 30 '22 at 20:52