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

macOS console app bundle doesn't launch #5154

Open
llamafilm opened this issue Sep 9, 2020 · 41 comments
Open

macOS console app bundle doesn't launch #5154

llamafilm opened this issue Sep 9, 2020 · 41 comments
Assignees
Labels
feature Feature request

Comments

@llamafilm
Copy link

Description of the issue

I'm building in a clean virtualenv with pyinstaller test.py --windowed
I can't launch the .app bundle by double-clicking nor with open ./test.app in Terminal.
It works fine if I run ./test.app/Contents/MacOS/test

Context information (for bug reports)

  • Output of pyinstaller --version: 4.0

  • Version of Python: 3.7.7

  • Platform: macOS 10.14.6

  • try the latest development version. No change.

  • follow all the instructions in our "If Things Go Wrong" Guide. Done.

A minimal example program which shows the error

print('hello world')
input()

Stacktrace / full error message

$ open dist/test.app/
LSOpenURLsWithRole() failed with error -10810 for the file /Users/elliott/source/private_repo/Colorfront/startTKD_cloud/dist/test.app.

In the Console I see these errors, which aren't very helpful:

default	13:05:14.057647 -0700	lsd	Non-fatal error enumerating at PlugIns/ -- file:///Users/elliott/source/my_app/dist/test.app/Contents/, continuing: Error Domain=NSCocoaErrorDomain Code=260 "The file “PlugIns” couldn’t be opened because there is no such file." UserInfo={NSURL=PlugIns/ -- file:///Users/elliott/source/my_app/dist/test.app/Contents/, NSFilePath=/Users/elliott/source/my_app/dist/test.app/Contents/PlugIns, NSUnderlyingError=0x7f9b0750c2c0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
default	13:05:14.061109 -0700	lsd	Parsed Info.plist for test
default	13:05:14.061129 -0700	lsd	Parsed MobileInstallation data for test
default	13:05:24.858617 -0700	lsd	Non-fatal error enumerating at PlugIns/ -- file:///Users/elliott/source/my_app/dist/test.app/Contents/, continuing: Error Domain=NSCocoaErrorDomain Code=260 "The file “PlugIns” couldn’t be opened because there is no such file." UserInfo={NSURL=PlugIns/ -- file:///Users/elliott/source/my_app/dist/test.app/Contents/, NSFilePath=/Users/elliott/source/my_app/dist/test.app/Contents/PlugIns, NSUnderlyingError=0x7f9b07729230 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
default	13:05:24.863260 -0700	lsd	Parsed Info.plist for test
default	13:05:24.863281 -0700	lsd	Parsed MobileInstallation data for test

So I tried adding an empty PlugIns directory. This makes the "non-fatal" error messages go away, but the app still doesn't launch.

@glennra
Copy link
Contributor

glennra commented Sep 10, 2020

Does the system.log say anything useful? When I had that error recently it was because of a code signing issue.

@bwoodsend
Copy link
Member

You're using --windowed which means no stdin (needed for input()) or stdout (needed for print()) but you're trying to use them both anyway.

@bwoodsend bwoodsend added state:need info Need more information for solve or help. and removed state:need info Need more information for solve or help. labels Sep 10, 2020
@llamafilm
Copy link
Author

So is there no way to make a .app bundle that runs a non-GUI console app? In that case, I’d like to turn this into a feature request. I want users to be able to double run with a double click.

@bwoodsend
Copy link
Member

Yeah, just omit the --windowed option.

@llamafilm
Copy link
Author

But I think —windowed is required to create the .app bundle
https://pyinstaller.readthedocs.io/en/stable/usage.html#building-mac-os-x-app-bundles

@bwoodsend
Copy link
Member

Uggh possibly. I thought .app was just another file suffix type. Without --windowed still gives you something to double click on but it isn't a .app - it's a binary inside a folder. Doesn't --onefile give you what you want? It's still not called a .app but it does the same thing.

@llamafilm
Copy link
Author

The binary cannot be run by a double click on macOS. You have to run it from a Terminal. This makes it hard for non-technical users.

@bwoodsend
Copy link
Member

Then it's broken. You should be able to just click on it. #5109 may be the cause.

@llamafilm
Copy link
Author

Wow, I never knew you could run binaries this way on macOS. My filename had a dot (.) in it and after removing that, it does run with a double-click. That seems to be a macOS limitation, not a problem with PyInstaller.

I would still prefer using a .app bundle for a few reasons:

  • It launches faster because it's not compressed into a single file
  • You can customize the icon to make it look more familiar to the end user
  • You can have dots in the filename

@bwoodsend
Copy link
Member

@rokm Do you know if a console based (as opposed to an app with a GUI) .app application is possible? In the docs it says you get a .app using the --windowed option. Surely there's a reason the making a .app feature is glued to the --windowed option rather than having two independent options. Do you know if OSX has some hidden implication of .app implies GUI or something?

@llamafilm
Copy link
Author

I found an ugly hack to make this work. The binary is located at test.app/Contents/MacOS/test. I renamed that file to test_bin and create an executable shell script called test with contents:

#!/bin/bash
dir=$(dirname $0)
open -a Terminal file://${dir}/test_bin

Now it runs my code in a new Terminal window. Don't forget chmod +x test

@rokm
Copy link
Member

rokm commented Sep 10, 2020

From my experiments, it would seem that .app bundle doesn't get console (regardless of console setting in EXE()).

The minimal test example used here, when ran as an .app (i.e, when double-clicked in Finder, or by running open programName.app from terminal), actually throws exception on the input() call: EOF when reading a line.

Using a wrapper script to run the executable in a Terminal does seem like a way to go here...

@llamafilm
Copy link
Author

llamafilm commented Sep 10, 2020

I've added the following code to the end of the spec file, and this seems to work okay. It would be good to have this integrated into PyInstaller, but I don't know the best way to do that. One problem with this method is the app bundle still will not launch if it has a space in the filename or anywhere in the path.

## Make app bundle double-clickable
import plistlib
from pathlib import Path
app_path = Path(app.name)

# read Info.plist
with open(app_path / 'Contents/Info.plist', 'rb') as f:
    pl = plistlib.load(f)

# write Info.plist
with open(app_path / 'Contents/Info.plist', 'wb') as f:
    pl['CFBundleExecutable'] = 'wrapper'
    plistlib.dump(pl, f)

# write new wrapper script
shell_script = """#!/bin/bash
dir=$(dirname $0)
open -a Terminal file://${dir}/%s""" % app.appname
with open(app_path / 'Contents/MacOS/wrapper', 'w') as f:
    f.write(shell_script)

# make it executable
(app_path  / 'Contents/MacOS/wrapper').chmod(0o755)

@bwoodsend
Copy link
Member

bwoodsend commented Sep 11, 2020

@llamafilm That looks good and certainly could turn into a feature. Possibly it could be implemented in a APP class which inherits from BUNDLE so you can easily switch to it the spec file.

As for you spaces in paths problem, you just should be able to wrap it in either "s or 's?

shell_script = """#!/bin/bash
dir=$(dirname $0)
open -a Terminal "file://${dir}/%s"
""" % app.appname

@bwoodsend bwoodsend added feature Feature request good first issue This is a good issue if you want to start working on PyInstaller labels Sep 11, 2020
@motatoes motatoes self-assigned this Sep 27, 2020
@motatoes
Copy link
Contributor

Started work on this feature to create a new class osx.APP_CONSOLE inherits from BUNDLE which will create the hack of using a bash script to launch a console app

@htgoebel
Copy link
Member

Can one please give a summary of what the exact cause is and how this script helps solving this? (this might also be helpful for documenting the pull-request later). Thanks.

@rokm
Copy link
Member

rokm commented Dec 29, 2020

Can one please give a summary of what the exact cause is and how this script helps solving this? (this might also be helpful for documenting the pull-request later). Thanks.

The macOS app bundles don't seem to open terminal window by themselves when you run them, e.g. by double clicking on them in Finder. (In contrast to, for example console Windows application that will open a terminal if run by double-clicking on the executable. So the behavior of macOS .app bundles is like that of Windows noconsole applications, but the reporter would like to have it behave like a console one).

The idea here is that for macOS .app bundles of CLI applications, we add a launcher script that explicitly opens a macOS Terminal and runs the executable in it.

@motatoes
Copy link
Contributor

Inserting comments of @bwoodsend from discord over here for context:

It was my suggestion to create a separate class but now I consider[...] this would lead to a lot of awkward OSX_APP_CONSOLE if macOS else Bundle in the spec file so I agree that putting it in the BUNDLE class would be better. Add a osx_app_console= option to the BUNDLE class, and a --osx_app_console command line switch which sets osx_app_console to true in the spec file`

@llamafilm
Copy link
Author

Can one please give a summary of what the exact cause is and how this script helps solving this? (this might also be helpful for documenting the pull-request later). Thanks.

I wish I could. After studying this for a few hours, I still cannot figure out why the app doesn't launch. I can build my own app bundle by hand containing nothing more than Info.plist and an executable shell script and that works fine. So this workaround just changes the app executable to a wrapper shell script, which then opens the real binary in Terminal.

This error message:

LSOpenURLsWithRole() failed with error -10810

is not very specific; it can happen for many reasons. Sometimes it can be fixed by reloading Launch Services database:

/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f dist/hello.app

Each user has a separate Launch Services database, so if you run as root (for dtruss debugging) you may need to run that again.

Initially, the system log shows an error:

lsd: (Security) [com.apple.securityd:security_exception] MacOS error: -67062

This means the app is not code-signed, and I think it's harmless. It can be fixed with:

codesign -s <identity> --deep dist/hello.app

There is nothing helpful in the system log. RunningBoard watches the process without managing it, so I don't think that subsystem is responsible for the error.

runningboardd: (RunningBoard) [com.apple.runningboard:assertion] Finished acquiring assertion 286-115-1074 (target:executable<hello(503)>)
runningboardd: (RunningBoard) [com.apple.runningboard:assertion] Invalidating assertion 286-115-1073 (target:executable<hello(503)>) from originator 115
distnoted: [com.apple.distnoted:diagnostic] register name: com.apple.sharedfilelist.change object: com.apple.LSSharedFileList.ApplicationRecentDocuments/hello token: f446b pid: 688
distnoted: [com.apple.distnoted:diagnostic] register name: com.apple.sharedfilelist.launch object: kCFNotificationAnyObject token: f446c pid: 688
Dock: (LaunchServices) [com.apple.launchservices:default] Reading localized string from /Users/elliott/source/temp/dist/hello.app
Dock: (IconServices) PREPARE_ICON_IMAGE
Dock: (IconServices) GET_ICON_IMAGE_NO_IO
amfid: (Security) SecTrustEvaluateIfNecessary
runningboardd: (RunningBoard) Process Event
runningboardd: (RunningBoard) [com.apple.runningboard:process] [executable<hello(503)>:6586] Death sentinel fired!

I don't see anything helpful in dtruss either, it just kills itself with SIGCONT.

Expand for details.
sudo dtruss open dist/hello.app
% sudo dtruss open dist/hello.app
SYSCALL(args) 		 = return
LSOpenURLsWithRole() failed with error -10810 for the file /Users/elliott/source/temp/dist/hello.app.
issetugid(0x0, 0x0, 0x0)		 = 0 0
getentropy(0x7FFEE74ED580, 0x20, 0x0)		 = 0 0
getentropy(0x7FFEE74ED5D0, 0x40, 0x0)		 = 0 0
getpid(0x0, 0x0, 0x0)		 = 6723 0
stat64("/AppleInternal\0", 0x7FFEE74EEAE0, 0x0)		 = -1 Err#2
csops_audittoken(0x1A43, 0x7, 0x7FFEE74EE630)		 = 0 0
proc_info(0x2, 0x1A43, 0xD)		 = 64 0
csops_audittoken(0x1A43, 0x7, 0x7FFEE74EDEB0)		 = 0 0
geteuid(0x0, 0x0, 0x0)		 = 0 0
getuid(0x0, 0x0, 0x0)		 = 0 0
sysctl([CTL_KERN, 14, 1, 6723, 0, 0] (4), 0x7FFEE74ED188, 0x7FFEE74ED168, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74ED470, 0x7FFEE74ED474, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
csops(0x1A43, 0x0, 0x7FFEE74EE1CC)		 = 0 0
proc_info(0x2, 0x1A43, 0xB)		 = 0 0
gettid(0x7FFEE74ED440, 0x7FFEE74ED444, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
stat64("dist/hello.app\0", 0x7FFEE74EED00, 0x0)		 = 0 0
open_nocancel(".\0", 0x0, 0x1)		 = 3 0
fstat64(0x3, 0x7FFEE74EE480, 0x0)		 = 0 0
fcntl_nocancel(0x3, 0x32, 0x7FFEE74EE690)		 = 0 0
close_nocancel(0x3)		 = 0 0
stat64("/Users/elliott/source/temp\0", 0x7FFEE74EE3F0, 0x0)		 = 0 0
stat64("/Users/elliott/source/temp/dist/hello.app\0", 0x7FFEE74EEC40, 0x0)		 = 0 0
stat64("/Users/elliott/source/temp/dist/hello.app\0", 0x7FFEE74EED00, 0x0)		 = 0 0
getaudit_addr(0x7FFEE74EEF60, 0x30, 0x0)		 = 0 0
__mac_syscall(0x7FFF715CDA3F, 0x2, 0x7FFEE74EE9E8)		 = 0 0
workq_kernreturn(0x400, 0x7FFEE74EEB38, 0x18)		 = 0 0
workq_open(0x0, 0x0, 0x0)		 = 0 0
workq_kernreturn(0x20, 0x0, 0x1)		 = 0 0
thread_selfid(0x0, 0x0, 0x0)		 = 171761 0
gettid(0x7FFEE74EEA50, 0x7FFEE74EEA54, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
sysctlbyname(kern.osvariant_status, 0x15, 0x7FFEE74EE968, 0x7FFEE74EE960, 0x0)		 = 0 0
gettid(0x7FFEE74EEA40, 0x7FFEE74EEA44, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74EEAF0, 0x7FFEE74EEAF4, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
stat64("/System/Library/PrivateFrameworks/CoreAnalytics.framework/CoreAnalytics\0", 0x7000024B0400, 0x0)		 = 0 0
proc_info(0x2, 0x1A43, 0x11)		 = 56 0
proc_info(0x2, 0x1A43, 0x11)		 = 56 0
sysctl([CTL_KERN, 14, 1, 6723, 0, 0] (4), 0x7FFEE74EE728, 0x7FFEE74EE718, 0x0, 0x0)		 = 0 0
issetugid(0x0, 0x0, 0x0)		 = 0 0
ulock_wake(0x1000102, 0x7FFF97ADC8C0, 0x0)		 = 0 0
ulock_wait(0x1000002, 0x7FFF97ADC8C0, 0x701)		 = 0 0
workq_kernreturn(0x80, 0x0, 0x20FF)		 = 0 0
kevent_qos(0xFFFFFFFFFFFFFFFF, 0x7FFEE74EDF08, 0x1)		 = 0 0
kevent_qos(0xFFFFFFFFFFFFFFFF, 0x7FFEE74EDEB0, 0x1)		 = 0 0
kevent_qos(0xFFFFFFFFFFFFFFFF, 0x7FFEE74EDED0, 0x1)		 = 0 0
kevent_qos(0xFFFFFFFFFFFFFFFF, 0x7FFEE74EE500, 0x1)		 = 0 0
kevent_id(0x7FB85540EA50, 0x7FFEE74EE500, 0x1)		 = 0 0
ulock_wake(0x1000002, 0x10872D740, 0x0)		 = 0 0
ulock_wait(0x1010002, 0x10872D740, 0x702)		 = 0 0
openat(0xFFFFFFFFFFFFFFFE, "/Library/Preferences/Logging/com.apple.diagnosticd.filter.plist\0", 0x1000104, 0x24B9668)	 = -1 Err#2
shm_open(0x7FFF715B4280, 0x0, 0x0)		 = 3 0
mmap(0x0, 0x1000, 0x1, 0x1, 0x3, 0x0)		 = 0x108793000 0
getattrlist("/usr/bin/open\0", 0x7000024B9020, 0x7000024B9038)		 = 0 0
close_nocancel(0x3)		 = 0 0
access("/usr/bin\0", 0x5, 0x0)		 = 0 0
open_nocancel("/usr/bin\0", 0x1100004, 0x0)		 = 3 0
sysctlbyname(kern.secure_kernel, 0x12, 0x7000024B8B24, 0x7000024B8B28, 0x0)		 = 0 0
openat(0xFFFFFFFFFFFFFFFE, "/Library/Preferences/Logging/com.apple.diagnosticd.filter.plist\0", 0x1000104, 0xFFFFFFFFE74EE568)		 = -1 Err#2
fstatfs64(0x3, 0x7000024B8B28, 0x0)		 = 0 0
getuid(0x0, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74EE990, 0x7FFEE74EE994, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74EE800, 0x7FFEE74EE804, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
getdirentries64(0x3, 0x7FB857008A00, 0x2000)		 = 8160 0
getdirentries64(0x3, 0x7FB857008A00, 0x2000)		 = 8160 0
kevent_id(0x7FB855605870, 0x7FFEE74EE540, 0x1)		 = 0 0
proc_info(0x2, 0x1A43, 0xD)		 = 64 0
kevent_id(0x7FB855605870, 0x7FFEE74EDA80, 0x1)		 = 0 0
getdirentries64(0x3, 0x7FB857008A00, 0x2000)		 = 8176 0
thread_selfid(0x0, 0x0, 0x0)		 = 171762 0
getdirentries64(0x3, 0x7FB857008A00, 0x2000)		 = 8184 0
getdirentries64(0x3, 0x7FB857008A00, 0x2000)		 = 3720 0
close_nocancel(0x3)		 = 0 0
access("/usr\0", 0x5, 0x0)		 = 0 0
open_nocancel("/usr\0", 0x1100004, 0x0)		 = 3 0
fstatfs64(0x3, 0x7000024B8B28, 0x0)		 = 0 0
getdirentries64(0x3, 0x7FB857008A00, 0x2000)		 = 360 0
close_nocancel(0x3)		 = 0 0
access("/usr/bin\0", 0x4, 0x0)		 = 0 0
open("/usr/bin\0", 0x0, 0x0)		 = 3 0
fstat64(0x3, 0x7FB855704470, 0x0)		 = 0 0
csrctl(0x0, 0x7000024B92DC, 0x4)		 = 0 0
fcntl(0x3, 0x32, 0x7000024B8F50)		 = 0 0
close(0x3)		 = 0 0
open("/usr/bin/Info.plist\0", 0x0, 0x4)		 = -1 Err#2
kevent_id(0x7FB855704590, 0x7000024B9B50, 0x1)		 = 0 0
workq_kernreturn(0x100, 0x70000253CB80, 0x1)		 = 0 Err#-2
open("/Library/Application Support/CrashReporter/SubmitDiagInfo.domains\0", 0x20, 0x907)		 = 3 0
kevent_id(0x7FB855704590, 0x70000253C730, 0x1)		 = 0 0
fgetxattr(0x3, 0x7FFF6DED0AE3, 0x7000024B9CBC)		 = 4 0
flock(0x3, 0x8, 0x0)		 = 0 0
lseek(0x3, 0x0, 0x2)		 = 215768 0
lseek(0x3, 0x0, 0x0)		 = 0 0
mmap(0x0, 0x34AD8, 0x1, 0x1, 0x3, 0x0)		 = 0x10879B000 0
getuid(0x0, 0x0, 0x0)		 = 0 0
getgid(0x0, 0x0, 0x0)		 = 0 0
geteuid(0x0, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74EEAF0, 0x7FFEE74EEAF4, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74EEA40, 0x7FFEE74EEA44, 0x0)		 = -1 Err#3
workq_kernreturn(0x100, 0x70000253CB80, 0x1)		 = 0 Err#-2
geteuid(0x0, 0x0, 0x0)		 = 0 0
stat64("/etc/asl/.noquota\0", 0x7000024B9060, 0x0)		 = -1 Err#2
getegid(0x0, 0x0, 0x0)		 = 0 0
bsdthread_ctl(0x100, 0x0, 0x2307)		 = 0 0
__mac_syscall(0x7FFF715CDA3F, 0x2, 0x7FFEE74EE6C8)		 = 0 0
stat64("/System/Library/PrivateFrameworks/CoreServicesInternal.framework/CoreServicesInternal\0", 0x7FFEE74E4A60, 0x0)	 = 0 0
open("/System/Library/PrivateFrameworks/CoreServicesInternal.framework/CoreServicesInternal\0", 0x0, 0x0)		 = 4 0
fcntl(0x4, 0x32, 0x7FFEE74E46D0)		 = 0 0
close(0x4)		 = 0 0
stat64("/System/Library/PrivateFrameworks/CoreServicesInternal.framework/Versions/A/CoreServicesInternal\0", 0x7FFEE74E9B90, 0x0)		 = 0 0
psynch_mutexdrop(0x7FFF97AC1040, 0x100, 0x100)		 = 0 0
psynch_mutexwait(0x7FFF97AC1040, 0x102, 0x0)		 = 259 0
sysctlbyname(kern.osproductversion, 0x15, 0x7FFEE74EE9F0, 0x7FFEE74EE9E8, 0x0)		 = 0 0
stat64("/usr/lib/libstdc++.6.dylib\0", 0x700002532BC0, 0x0)		 = 0 0
stat64("/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/LaunchServices\0", 0x7FFEE74E5170, 0x0)		 = 0 0
sysctlbyname(kern.osproductversion, 0x15, 0x7FFEE74ED950, 0x7FFEE74ED948, 0x0)		 = 0 0
getattrlist("/Users/elliott/source/temp/dist/hello.app\0", 0x7FFEE74EE1B8, 0x7FFEE74EDA00)		 = 0 0
getfsstat64(0x0, 0x0, 0x2)		 = 5 0
getfsstat64(0x7FB856818A00, 0x32D0, 0x2)		 = 5 0
gettid(0x7FFEE74ED100, 0x7FFEE74ED104, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
statfs64(0x7FFF389C7A5C, 0x7FFEE74EC908, 0x0)		 = 0 0
getuid(0x0, 0x0, 0x0)		 = 0 0
getuid(0x0, 0x0, 0x0)		 = 0 0
kevent_qos(0xFFFFFFFFFFFFFFFF, 0x7FFEE74EC7A0, 0x1)		 = 0 0
workq_kernreturn(0x100, 0x70000253CB80, 0x2)		 = 0 Err#-2
kevent_qos(0xFFFFFFFFFFFFFFFF, 0x70000253C7D0, 0x1)		 = 0 0
getattrlist("/Users/elliott/source/temp/dist/hello.app\0", 0x7FFEE74EE138, 0x7FFEE74EDD70)		 = 0 0
gettid(0x7FFEE74ED470, 0x7FFEE74ED474, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
open("/System/Library/CoreServices/SystemVersion.plist\0", 0x0, 0x1B6)		 = 4 0
fstat64(0x4, 0x7FFEE74EE600, 0x0)		 = 0 0
read(0x4, "\n\n\n\n\tProductBuildVersion\n\t19H2\n\tProductCopyright\n\t", 0x214)		 = 532 0
close(0x4)		 = 0 0
open_nocancel("/usr/bin\0", 0x1100004, 0x37575ED0)		 = 4 0
fstatfs64(0x4, 0x7FFEE74ECB18, 0x0)		 = 0 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 8160 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 8160 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 8176 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 8184 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 3720 0
close_nocancel(0x4)		 = 0 0
stat64("/usr/bin\0", 0x7FFEE74EE190, 0x0)		 = 0 0
open_nocancel("/usr/bin\0", 0x1100004, 0x37575ED0)		 = 4 0
fstatfs64(0x4, 0x7FFEE74ECA98, 0x0)		 = 0 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 8160 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 8160 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 8176 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 8184 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 3720 0
close_nocancel(0x4)		 = 0 0
stat64("/usr/bin/open\0", 0x7FFEE74EE000, 0x0)		 = 0 0
open("/usr/bin/open\0", 0x0, 0x1FF)		 = 4 0
read(0x4, "\317\372\355\376\a\0", 0x200)		 = 512 0
close(0x4)		 = 0 0
open_nocancel("/System/Library/CoreServices/SystemVersion.bundle\0", 0x1100004, 0x37575ED0)		 = 4 0
fstatfs64(0x4, 0x7FFEE74ECB88, 0x0)		 = 0 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 1624 0
close_nocancel(0x4)		 = 0 0
stat64("/System/Library/CoreServices/SystemVersion.bundle\0", 0x7FFEE74EE200, 0x0)		 = 0 0
open_nocancel("/System/Library/CoreServices/SystemVersion.bundle\0", 0x1100004, 0x37575ED0)		 = 4 0
fstatfs64(0x4, 0x7FFEE74ECB08, 0x0)		 = 0 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 1624 0
close_nocancel(0x4)		 = 0 0
open_nocancel("/System/Library/CoreServices/SystemVersion.bundle\0", 0x1100004, 0x37575ED0)		 = 4 0
fstatfs64(0x4, 0x7FFEE74EC8E8, 0x0)		 = 0 0
getdirentries64(0x4, 0x7FB856819200, 0x2000)		 = 1624 0
close_nocancel(0x4)		 = 0 0
gettid(0x7FFEE74EDE40, 0x7FFEE74EDE44, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74EDEF0, 0x7FFEE74EDEF4, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
issetugid(0x0, 0x0, 0x0)		 = 0 0
issetugid(0x0, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74ED150, 0x7FFEE74ED154, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
getuid(0x0, 0x0, 0x0)		 = 0 0
geteuid(0x0, 0x0, 0x0)		 = 0 0
getrlimit(0x1008, 0x7FFEE74ECF80, 0x0)		 = 0 0
open_nocancel("/etc/master.passwd\0", 0x0, 0x1B6)		 = 4 0
fstat64(0x4, 0x7FFEE74ECFF0, 0x0)		 = 0 0
fstat64(0x4, 0x7FFEE74EBED8, 0x0)		 = 0 0
read_nocancel(0x4, "##\n# User Database\n# \n# Note that this file is consulted directly only when the system is running\n# in single-user mode.  At other times this information is provided by\n# Open Directory.\n#\n# See the opendirectoryd(8) man page for additional information abo", 0x1000)		 = 4096 0
lseek(0x4, 0xFFFFFFFFFFFFF18F, 0x1)		 = 399 0
close_nocancel(0x4)		 = 0 0
stat64("/var/root\0", 0x7FFEE74ECCE0, 0x0)		 = 0 0
__mac_syscall(0x7FFF715CDA3F, 0x2, 0x7FFEE74ED748)		 = 0 0
kevent_id(0x7FB855613C20, 0x7FFEE74ED770, 0x1)		 = 0 0
kevent_id(0x7FB855613C20, 0x7FFEE74ED510, 0x1)		 = 0 0
workq_kernreturn(0x40, 0x70000253CB80, 0x0)		 = 0 Err#-2
shm_open(0x7FB855614080, 0x0, 0x0)		 = 4 0
mmap(0x0, 0x4000, 0x1, 0x1, 0x4, 0x0)		 = 0x1087E5000 0
close(0x4)		 = 0 0
open_nocancel("/usr/bin\0", 0x1100004, 0x37575ED0)		 = 4 0
fstatfs64(0x4, 0x7FFEE74EC7C8, 0x0)		 = 0 0
getdirentries64(0x4, 0x7FB85681BE00, 0x2000)		 = 8160 0
getdirentries64(0x4, 0x7FB85681BE00, 0x2000)		 = 8160 0
getdirentries64(0x4, 0x7FB85681BE00, 0x2000)		 = 8176 0
getdirentries64(0x4, 0x7FB85681BE00, 0x2000)		 = 8184 0
getdirentries64(0x4, 0x7FB85681BE00, 0x2000)		 = 3720 0
close_nocancel(0x4)		 = 0 0
stat64("/usr/share/icu/icudt64l/metadata.res\0", 0x7FFEE74EC4A8, 0x0)		 = -1 Err#2
stat64("/usr/share/icu/icudt64l.dat\0", 0x7FFEE74EC408, 0x0)		 = 0 0
open("/usr/share/icu/icudt64l.dat\0", 0x0, 0x0)		 = 4 0
mmap(0x0, 0x1B4B600, 0x1, 0x1, 0x4, 0x0)		 = 0x10A6FE000 0
close(0x4)		 = 0 0
stat64("/usr/share/icu/icudt64l/supplementalData.res\0", 0x7FFEE74EC4A8, 0x0)		 = -1 Err#2
open_nocancel("/System/Library/CoreServices/SystemVersion.bundle/\0", 0x1100004, 0x37575ED0)		 = 4 0
fstatfs64(0x4, 0x7FFEE74EC8C8, 0x0)		 = 0 0
getdirentries64(0x4, 0x7FB856827A00, 0x2000)		 = 1624 0
close_nocancel(0x4)		 = 0 0
open_nocancel("/System/Library/CoreServices/SystemVersion.bundle//English.lproj\0", 0x1100004, 0x37575ED0)		 = 4 0
fstatfs64(0x4, 0x7FFEE74EC8C8, 0x0)		 = 0 0
getdirentries64(0x4, 0x7FB856827A00, 0x2000)		 = 112 0
close_nocancel(0x4)		 = 0 0
open_nocancel("/System/Library/CoreServices/SystemVersion.bundle//Base.lproj\0", 0x1100004, 0x37575ED0)		 = -1 Err#2
open("/System/Library/CoreServices/SystemVersion.bundle/English.lproj/SystemVersion.strings\0", 0x0, 0x1B6)		 = 4 0
fstat64(0x4, 0x7FFEE74EE4E0, 0x0)		 = 0 0
read(0x4, "bplist00\323\001\002\003\001\002\004WVersionUBuild_\020\021FullVersionString_\020\025Version %@ (Build %@)\b\017\027\0351\0", 0x6E)		 = 110 0
close(0x4)		 = 0 0
gettid(0x7FFEE74EE560, 0x7FFEE74EE564, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74EE560, 0x7FFEE74EE564, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74EE560, 0x7FFEE74EE564, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74EE560, 0x7FFEE74EE564, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
getattrlist("/Users/elliott/source/temp/dist/hello.app\0", 0x7FFEE74EDDA8, 0x7FFEE74ED9E0)		 = 0 0
gettid(0x7FFEE74ED0E0, 0x7FFEE74ED0E4, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74EE430, 0x7FFEE74EE434, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
gettid(0x7FFEE74ECAA0, 0x7FFEE74ECAA4, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
__mac_syscall(0x7FFF713F3E11, 0x50, 0x7FFEE74EE0E0)		 = -1 Err#93
gettid(0x7FFEE74EDF80, 0x7FFEE74EDF84, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
open("/Users/elliott/source/temp/dist/hello.app\0", 0x0, 0x1B6)		 = 4 0
fstatfs64(0x4, 0x7FFEE74ECDC0, 0x0)		 = 0 0
fcntl(0x4, 0x32, 0x7FFEE74EC010)		 = 0 0
__mac_syscall(0x7FFF713F3E11, 0x52, 0x7FFEE74EC3D0)		 = -1 Err#93
close(0x4)		 = 0 0
shm_open(0x7FFF714B1F6D, 0x0, 0x714B153F)		 = 4 0
fstat64(0x4, 0x7FFEE74ED670, 0x0)		 = 0 0
mmap(0x0, 0x1000, 0x1, 0x1, 0x4, 0x0)		 = 0x1087E9000 0
close(0x4)		 = 0 0
gettid(0x7FFEE74EDB30, 0x7FFEE74EDB34, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
open("/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Exceptions.plist\0", 0x0, 0x1B6)		 = 4 0
fstat64(0x4, 0x7FFEE74EDB30, 0x0)		 = 0 0
fstatfs64(0x4, 0x7FFEE74ED2B8, 0x0)		 = 0 0
stat64("/System/Library/PrivateFrameworks/AppleFSCompression.framework/AppleFSCompression\0", 0x7FFEE74E35B0, 0x0)	 = 0 0
stat64("/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Exceptions.plist\0", 0x7FFEE74ECD88, 0x0)	 = 0 0
getxattr("/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Exceptions.plist\0", 0x7FFF4ABDE163, 0x0)	 = 16 0
getxattr("/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Exceptions.plist\0", 0x7FFF4ABDE163, 0x7FB8557061D4)		 = 16 0
getxattr("/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Exceptions.plist\0", 0x7FFF4ABDE72F, 0x0)	 = 16998 0
mmap(0x0, 0x705B, 0x1, 0x2, 0x4, 0x0)		 = 0x1087EA000 0
close(0x4)		 = 0 0
open("/System/Library/CoreServices/CoreTypes.bundle/Contents/Library/AppExceptions.bundle/Exceptions.plist\0", 0x0, 0x1B6)		 = 4 0
fstat64(0x4, 0x7FFEE74EDB30, 0x0)		 = 0 0
fstatfs64(0x4, 0x7FFEE74ED2B8, 0x0)		 = 0 0
stat64("/System/Library/CoreServices/CoreTypes.bundle/Contents/Library/AppExceptions.bundle/Exceptions.plist\0", 0x7FFEE74ECD88, 0x0)		 = 0 0
mmap(0x0, 0x1AED, 0x1, 0x2, 0x4, 0x0)		 = 0x1087EA000 0
close(0x4)		 = 0 0
open("/System/Library/CoreServices/CoreTypes.bundle/Contents/Library/InternalAppExceptions.bundle/Contents/Resources/Exceptions.plist\0", 0x0, 0x1B6)		 = -1 Err#2
kevent_id(0x7FB855704DB0, 0x7FFEE74EDF40, 0x1)		 = 0 0
workq_kernreturn(0x100, 0x70000253CB80, 0x1)		 = 0 Err#-2
sysctlbyname(hw.cputype, 0xA, 0x7FFEE74EDF3C, 0x7FFEE74EDF30, 0x0)		 = 0 0
getxattr("/Users/elliott/source/temp/dist/hello.app\0", 0x7FFF506E38A6, 0x0)		 = -1 Err#93
kevent_qos(0xFFFFFFFFFFFFFFFF, 0x70000253C8A0, 0x1)		 = 0 0
workq_kernreturn(0x4, 0x0, 0x0)		 = 0 Err#-2
gettid(0x7FFEE74ECA80, 0x7FFEE74ECA84, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
getattrlist("/usr/bin/open\0", 0x7FFEE74EB5B8, 0x7FFEE74EB1F0)		 = 0 0
gettid(0x7FFEE74EA8F0, 0x7FFEE74EA8F4, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
getaudit_addr(0x7FFEE74EDEC0, 0x30, 0x0)		 = 0 0
kevent_id(0x7FB855712D20, 0x7FFEE74EDC40, 0x1)		 = 0 0
kevent_id(0x7FB855712D20, 0x7FFEE74EDA80, 0x1)		 = 0 0
workq_kernreturn(0x40, 0x7000024B9B80, 0x1)		 = 0 Err#-2
stat64("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics\0", 0x7FFEE74E4500, 0x0)		 = 0 0
gettid(0x7FFEE74EDCE0, 0x7FFEE74EDCE4, 0x0)		 = -1 Err#3
geteuid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
getegid(0x0, 0x0, 0x0)		 = 0 0
open("/Users/elliott/source/temp/dist/hello.app/Contents/MacOS/hello\0", 0x0, 0xFFFFFFFF8EE8BAB8)		 = 4 0
fcntl(0x4, 0x65, 0x7FFEE74EDC30)		 = 0 0
close(0x4)		 = 0 0
kill(6724, 19)		 = 0 0
kevent_id(0x7FB8579046E0, 0x7FFEE74EDAC0, 0x1)		 = 0 0
kevent_id(0x7FB8579046E0, 0x7FFEE74EDA20, 0x1)		 = 0 0
workq_kernreturn(0x100, 0x7000024B9B80, 0x1)		 = 0 Err#-2
kevent_id(0x7FB8579046E0, 0x7FFEE74EDA80, 0x1)		 = 0 0
kevent_id(0x7FB8579046E0, 0x7FFEE74EDCD0, 0x1)		 = 0 0
workq_kernreturn(0x100, 0x7000024B9B80, 0x1)		 = 0 Err#-2
workq_kernreturn(0x100, 0x7000024B9B80, 0x1)		 = 0 Err#-2
kevent_qos(0xFFFFFFFFFFFFFFFF, 0x7FFEE74EDE70, 0x1)		 = 0 0
workq_kernreturn(0x100, 0x7000024B9B80, 0x2)		 = 0 Err#-2
kevent_qos(0xFFFFFFFFFFFFFFFF, 0x7FFEE74ED1B0, 0x1)		 = 0 0
workq_kernreturn(0x40, 0x7000024B9B80, 0x0)		 = 0 Err#-2
kevent_qos(0xFFFFFFFFFFFFFFFF, 0x7FFEE74ED1B0, 0x1)		 = 0 0
workq_kernreturn(0x40, 0x7000024B9B80, 0x1)		 = 0 Err#-2
workq_kernreturn(0x20, 0x0, 0x1)		 = 0 0
kevent_qos(0xFFFFFFFFFFFFFFFF, 0x7FFEE74EDF10, 0x1)		 = 0 0
workq_kernreturn(0x100, 0x70000253CB80, 0x1)		 = 0 Err#-2
kevent_id(0x7FB857E04320, 0x7000024B98C0, 0x1)		 = 0 0
workq_kernreturn(0x4, 0x0, 0x0)		 = 0 Err#-2
workq_kernreturn(0x40, 0x7000024B9B80, 0x2)		 = 0 Err#-2
ulock_wait(0x1050002, 0x7FFF9797BE5C, 0x702)		 = 0 0
ulock_wake(0x1000002, 0x7FFF9797BE5C, 0x0)		 = -2 0
write_nocancel(0x2, "LSOpenURLsWithRole() failed with error -10810 for the file /Users/elliott/source/temp/dist/hello.app.\0", 0x65)		 = 101 0
write_nocancel(0x2, "\n\0", 0x1)		 = 1 0
workq_kernreturn(0x40, 0x7000024B9B80, 0x1)		 = 0 Err#-2
workq_kernreturn(0x100, 0x70000253CB80, 0x1)		 = 0 Err#-2

@rokm
Copy link
Member

rokm commented Dec 29, 2020

The reproducer from original report:

print('hello world')
input()

is crashing because input() requires valid stdin, which is missing when running as .app bundle (= no console):

$ open dist/program.app
LSOpenURLsWithRole() failed with error -10810 for the file /Users/[...]/dist/program.app

If the example is expanded with top-level error handling and logging, e.g.:

try:
    print('hello world')
    input()
except Exception as e:
    with open('/Users/username/error.log', 'w') as f:
        f.write(f"{e}\n")

you will find that error.log contains EOF when reading a line.

So the application does launch, but it crashes with unhandled exception, and without console, you get no feedback. Once you ensure that there is console (launcher script that runs executable in Terminal), stdin also becomes available, "solving" the original problem.

@llamafilm
Copy link
Author

Thank you @rokm. I forgot you said that, that's what led me to write the wrapper script in the first place!

@motatoes
Copy link
Contributor

Happy new year! So I'm trying to think of a CLI argument name that is clear enough. Initial suggestion was --osx-app-console but we also already have --console / --windowed which is quite similar

Now I am thinking to use osx-app-cli to distinguish between the two. Any thoughts on this?

@llamafilm
Copy link
Author

Why not use the existing —console option? I never understood why this was related to making a .app bundle.

@motatoes
Copy link
Contributor

motatoes commented Jan 1, 2021

@llamafilm I thought about that, so in the docs the --console is synonymous with --nowindowed, while the .app is only generated with the --windowed option. https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/building/makespec.py#L239

As a result it will have to be a new option otherwise it would break existing behaviour. In this case I will stick with --osx-app-console as its a specialised case of the --windowed (--console) option.

@bwoodsend
Copy link
Member

I'd be against using --windowed because then if you use the same command on another operating system you'd get a windowed app on Windows. So unless you actually want a windowed app on Windows (frankly I wish the feature didn't exist at all) you'd need some conditional magic in a spec file or CI workflow. --osx-app-console sounds fine to me.

@mself
Copy link

mself commented Jan 11, 2021

The comments in this thread let me solve the problem I was having with the .app not launching, but the executable inside working fine. I had literally spent days trying to figure this out.

I think it would be very helpful to include a note in the docs that if you see "LSOpenURLsWithRole() failed with error -10810" when running the app (but the executable inside works fine), then your app is crashing -- probably due to the lack of stdin or a directory your app is writing to being read-only for sandboxed apps. One way to debug it is to use printf-stye debugging, but writing to a log file (since stdout/stderr don't go anywhere).

Thank you!

@meichthys
Copy link

meichthys commented Apr 17, 2021

Any update on this? The workaround by @llamafilm (#5154 (comment)) seems to work, but is quite a pain to do after each build. Also, it would be nice if there was a way to hide the console window in cases where we are building a gui-only application.

@motatoes
Copy link
Contributor

hey @meichthys I'm working on a revision of the PR this weekend, sorry for the delay

@meichthys
Copy link

@motatoes Do you know if the revision was implemented yet? I haven't had the chance to rebuild my dev environment yet to test.

@Merkwurdichliebe
Copy link

This issue is not specific to pyinstaller and it might not be related to print or input (although I can't be sure). I've reported the exact same issue happening with cx_Freeze.

@dseyit
Copy link

dseyit commented May 11, 2022

Hi,

I have the same issue with my app, it runs in terminal but does not run when bundled in .app format,

I realized xprotectservice runs together with the .app,

Can antimalware protection of mac os be preventing it from running?

@bwoodsend
Copy link
Member

There are other differences between running a .app by double clicking it and launching the executable inside it from the terminal. A .app does not run with the environment set in shell initialisation scripts like /etc/profile and ~/.zshrc so os.environ is missing variables that define locales and, if I remember correctly, $HOME. Also, if you're subprocessing command line tools then $PATH is set to only the basics so anything you might have installed on your machine won't be findable.

There's also a chance that .app is a red herring and you've just got some local resource path screwed up. You can verify this just by moving your application to somewhere random, open a terminal in another random folder then launch your application using its full path via that terminal. If it still runs fine then this is not the problem.

If that gets you nowhere then I suggest following Rok's advice.

@dseyit
Copy link

dseyit commented May 13, 2022

My issue was resolved when I use pathlib to get the path of the data files I include when building. Here is a quick method that solved my issue. So everytime I dont use this method, my app crashes (works fine when opened with terminal), so I had to find all of the data read/writes and fix them one by one.

def getResourcePath(relative_path):
    rel_path = pathlib.Path(relative_path)
    dev_base_path = pathlib.Path(__file__).resolve().parent
    base_path = getattr(sys,"_MEIPASS",dev_base_path)
    return base_path / rel_path

Then I used this function to get path of the required data to run my app. Credit goes to this tutorial

p.s. I use Macbook w/ M1 Pro

@18237634625
Copy link

The reproducer from original report:

print('hello world')
input()

is crashing because input() requires valid stdin, which is missing when running as .app bundle (= no console):

$ open dist/program.app
LSOpenURLsWithRole() failed with error -10810 for the file /Users/[...]/dist/program.app

If the example is expanded with top-level error handling and logging, e.g.:

try:
    print('hello world')
    input()
except Exception as e:
    with open('/Users/username/error.log', 'w') as f:
        f.write(f"{e}\n")

you will find that error.log contains EOF when reading a line.

So the application does launch, but it crashes with unhandled exception, and without console, you get no feedback. Once you ensure that there is console (launcher script that runs executable in Terminal), stdin also becomes available, "solving" the original problem.

@rokm

hi, I tried your method. Found EOF when reading a line error in error.log

But I don't understand how to modify

@18237634625
Copy link

18237634625 commented Jul 20, 2022

启动器脚本

I am a beginner. I try to use your script, run it in the terminal,

In the end just opened the terminal and didn't run the '.app'

@18237634625
Copy link

Can one please give a summary of what the exact cause is and how this script helps solving this? (this might also be helpful for documenting the pull-request later). Thanks.

The macOS app bundles don't seem to open terminal window by themselves when you run them, e.g. by double clicking on them in Finder. (In contrast to, for example console Windows application that will open a terminal if run by double-clicking on the executable. So the behavior of macOS .app bundles is like that of Windows noconsole applications, but the reporter would like to have it behave like a console one).

The idea here is that for macOS .app bundles of CLI applications, we add a launcher script that explicitly opens a macOS Terminal and runs the executable in it.

Come and save my week! I tried using the method above, but it didn't work!

dir=$(dirname $0)
open -a Terminal file://${dir}/test

This will only open the executable in the terminal. didn't get the .app to run

I packaged with virtual environment pyhton3.9 + pyinstaller. Running the .app on the real python2.7 environment of the system can run normally. I packaged with virtual environment pyhton2.7 + pyinstaller. Running the .app on the system's real python2.7 environment does not work.

Ultimately I hope to use python2.7 to complete this task!

@rokm
Copy link
Member

rokm commented Jul 20, 2022

Come and save my week! I tried using the method above, but it didn't work!

We're not here to save you from your problems...

open -a Terminal file://${dir}/test

Is your executable within the .app bundle named test?


If your bundle is called program.app and its executable is program.app/Contents/MacOS/program, then:

  1. rename the original executable to program.orig:
mv program.app/Contents/MacOS/program program.app/Contents/MacOS/program.orig
  1. Create a wrapper script with the following contents:
#!/bin/bash
dir=$(cd "$( dirname "${0}")" && pwd )
open -a Terminal "file://${dir}/program.orig"

the script should be running the original (renamed) executable, so make sure you get it right.

Now save that script as program.app/Contents/MacOS/program, so that opening the bundle will launch this script.

  1. Make it executable
chmod +x program.app/Contents/MacOS/program
  1. Open the bundle

Ultimately I hope to use python2.7 to complete this task!

The versions of pyinstaller that support python 2.7 are not supported anymore (same as python 2.7 itself), so if you want to use python 2.7, you're on your own.

@bwoodsend bwoodsend removed the good first issue This is a good issue if you want to start working on PyInstaller label Nov 4, 2022
@avishayil
Copy link

Hi, this workaround stopped working after upgrading OSX to Ventura

Screenshot 2022-12-13 at 11 46 19

@sasha1618
Copy link

sasha1618 commented Jan 31, 2023

Same problem with OSX Ventura.

@avishayil, have you found a solution?

@avishayil
Copy link

Same problem with OSX Ventura.

@avishayil, have you found a solution?

Haven't found a solution. Had to go via the single executable way rather than .app file

@mario-robles
Copy link

mario-robles commented May 29, 2023

I was having this exact same problem and found a way to get it sorted out even though it is more like a hack, anyway this is what is working for me.

  1. Generate the app as usual with pyinstaller: myapp.app
  2. Rename the executable file within the app folder to something else:
    mv myapp.app/Contents/MacOS/myapp myapp.app/Contents/MacOS/myapp_cli
  3. Create a launcher script for your app:
    vi myapp.app/Contents/MacOS/myapp
    Put this in the script:
#!/bin/bash
# This is the launcher for OSX, this way the app will be opened
# when you double click it from the apps folder
open -n /Applications/myapp.app/Contents/MacOS/myapp_cli
  1. Make the script executable:
    chmod +x myapp.app/Contents/MacOS/myapp
  2. Now you can copy the folder myapp.app to the Applications folder and should open your app in the default terminal.

I know it's not related to pyinstaller but it's working for my purposes, not sure if this approach would be even something pyinstaller team would consider adding to the app generation process but at least it's a workaround for some use cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Feature request
Projects
None yet
Development

No branches or pull requests