14

I have attempted to convert my python program into a .app using PyInstaller. The actual code runs fine through IDLE, but everytime I try and run the newly converted .app, it closes straight away. Below is my .spec file and my .py file. I have edited the .spec file, adding in the text file I import in my .py file.

PYTHON FILE:

#CENTRALCOAST: 2250-2420
#CENTRALCOAST2: 2250-2267
#NORTHERNBEACHES: 2084-2108
CentralCoast = []
NorthernBeaches = []
OOR = []
Invalid = []
import math
def numLen(num):
  return len(str(abs(num)))

with open('postcodes.txt') as input_file:
    long_list = [line.strip() for line in input_file]
    for i in range(len(long_list)):
        long_list[i] = int(long_list[i])
for each in long_list:
    if 2084 <= each <= 2108: #NorthernBeaches
        NorthernBeaches.extend([each])
for each in long_list:
    if 2250 <= each <= 2267: #CentralCoast
        CentralCoast.extend([each])
for each in long_list:
    if not 2250 <= each <= 2267:
        OOR.extend([each])
#for each in long_list:
#    if numLen(each) != 4:
#        Invalid.extend([each])

Total = len(CentralCoast) + len(OOR) + len(NorthernBeaches) + len(Invalid)

print("Central Coast:", len(CentralCoast), "------", round(len(CentralCoast)/Total,2), "%")
print("")
print("Northern Beaches:", len(NorthernBeaches), "------", round(len(NorthernBeaches)/Total,4), "%")
print("")
print("Out of Range:", len(OOR), "------", round(len(OOR)/Total,2), "%")
print("")
#i = 0
#for i in OOR:
#  print(i)
#  i = i + 1
print("Invalid Entry:", len(Invalid), "------", round(len(Invalid)/Total,4), "%")
print("")
print("")
print("Total:", Total)
exit = input("")

SPEC FILE:

# -*- mode: python -*-

block_cipher = None


a = Analysis(['algorithmPOSTCODE.py'],
             pathex=['/Users/CooperTimewell'],
             binaries=[],
             datas=[('postcodes.txt', '.')],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          exclude_binaries=True,
          name='algorithmPOSTCODE',
          debug=False,
          strip=False,
          upx=True,
          console=False )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='algorithmPOSTCODE')
app = BUNDLE(coll,
             name='algorithmPOSTCODE.app',
             icon=None,
             bundle_identifier=None)

How do I stop it from closing straight away? Thankyou.

1
  • 6
    @MitaleeRao You are referring to this exact same page Commented Jul 29, 2019 at 12:41

5 Answers 5

17

Maybe try to launch the executable from the windows >execute >cmd windows instead of double clicking on the executable (I suppose you are using windows)

UPDATE

This method will show it clearly if there is any error causing your application to closes prematurely

11

I had the same problem as you even though I knew my code wasn't supposed to close immediately since it waited for user_input. When I ran my code from the terminal using python my_script.py the program would run fine.

Here is how I fixed it:

I reinstalled pyinstaller using:

pip install pyinstaller

I think that this was my main thing because the first time I installed it, I believe my antivirus prevented some of the components from installing correctly and when I reinstalled it, it probably patched in the holes.

I also tried a different command-line command. I explicitly stated for the final .exe to open a console and keep it open using the -c flag. Note: On Windows, this option will have no effect if the first script is a ‘.pyw’ file. It looked like this:

pyinstaller -c -F -i cm_icon.ico console_monopoly.py 

the -F flag was to bundle everything into one .exe instead of having a lot of files surrounding my .exe in the dist/ folder.

the -i flag is for adding an icon to my program.

Hope this helps!

3
  • I tried this but still the screen disappears after printing the results.. what should do to display the results for a longer time ? Commented May 14, 2019 at 10:26
  • 1
    adding the -c unfortunately has not changed anything in my case
    – Matt Dnv
    Commented Feb 28, 2020 at 14:11
  • Which antiivirus u have? Commented Nov 30, 2020 at 14:02
5

After many hours scouring/tinkering, I think I have found a solution!!

I have been having the same issue. This is defined by a Pyinstaller build that works fine on Windows and Linux, but closes immediately after building on Mac. Like you, the Mac build app closes after opening, but if you navigate through the app folder and open the Unix Executable directly it runs flawlessly. Your spec file looks perfect to me.

For me I traced the issue down to my program having to write files to the disk, whether it be creating a log file, or creating a shelf file (which I use for save date). When you run a pyinstaller build Macs will do all their run-time things in a random temp folder. For some reason Macs can find their way to the correct run-time temp folder when run from the unix executable, but get lost when run from the app. You COULD use _meipass to guide your log/shelf file (or whatever) to the correct temp folder, but this causes other problems. Some newer macs don't have permission to write there, and additionally you get a new temp folder every time you open the program, making it useless for logs or saves.

To resolve this issue use the following snippet:

import sys
import os
if getattr(sys, 'frozen', False):
    Current_Path = os.path.dirname(sys.executable)
else:
    Current_Path = str(os.path.dirname(__file__))

And then connect it to your log/shelf/save file names accordingly:

shelfFile = shelve.open(os.path.join(Current_Path, 'example_data'))

This solution will make any created file drop right next to your Unix Executable in the Mac app bundle, and NOT in the random temp file. Macs will find the location properly, and you will be able to reference the same file every time you open the program. My program also now opens from double clicking the app as intended.

I've been coming back and trying to solve this problem for MONTHS. Hopefully someone else finds this useful.

1
  • Do the lines above go in my .spec file? Any particular location? I tried to insert them, but Current_Path = str(os.path.dirname(__file__)) threw an error message.
    – fishbacp
    Commented Jun 23, 2021 at 16:07
5

The simplest way that I could work around this issue is by adding a input at the end of the code before the code execution completes.

input("Press enter to proceed...")

None of the answers I found could provide a similar functionality

Additionally how this helped me is, if the user hits enter directly, I made it so that the current instance is closed and a new instance of the app pops up right away. This is helpful if the user had accidentally input a wrong value for a previous input.
And if the user enters any other value, the process stops without creating a new instance.

1
  • 1
    worked like charm Commented Sep 14, 2022 at 5:15
2

In your case, because you set the console flag to False in your .spec file, the console window will not be displayed, preventing the output of your program from being displayed. Change this flag to True.

It is also possible that the application may be closing because it is unable to import a package or find an external file, which prevents your application from launching. To view the error messages associated with running your executable, run the .app (or .exe) file from the terminal (or command prompt): /path/to/app/dist/MyApp.app/Contents/MacOS/MyApp for Mac (in Terminal), /path/to/app/dist/MyApp.exe for Windows (in Command Prompt). This will allow you to observe any errors that may exist after the app was bundled. If the program does fail during an import statement, you may need to add a package to the hiddenimports list in the .spec file.

20
  • When I open my app from the terminal using your path (/path/to/app/dist/MyApp.app/Contents/MacOS/MyApp) my app runs perfectly within terminal.
    – CoopDaddio
    Commented Feb 5, 2018 at 20:49
  • Just to make sure that I understand the issue - when you run the .app from the terminal, it works properly (it does not close immediately and produces no error messages). When you try to run the .app by double-clicking the .app file, it will open briefly and then close. Is this correct? Commented Feb 5, 2018 at 20:57
  • @CoopDaddio I examined your .spec file more closely, and I believe the update to my answer may solve your problem. Commented Feb 5, 2018 at 21:08
  • I can only run the .app from the terminal using the address you have provided. Any other way I try and run the .app it opens briefly and then closes, yes.
    – CoopDaddio
    Commented Feb 5, 2018 at 21:09
  • 1
    How did you generate your .spec file to begin with? I would recommend deleting (or moving) your .spec file, deleting (or moving) the build/ and dist/ directories, and running the following command to generate a .app file: pyinstaller --onefile --console --add-data 'postcodes.txt:.', algorithmPOSTCODE.py Commented Feb 6, 2018 at 6:16

Not the answer you're looking for? Browse other questions tagged or ask your own question.