The application cannot be opened because its executable is missing - objective-c

I have an application that I have been developing for some time now. Recently launching the application via a double click presents a dialog that says "You can't open the application RepoWatch because it may be damaged or incomplete."
Launching the application via open ./RepoWatch.app gives me "The application cannot be opened because its executable is missing."
I usually launch the application via ./RepoWatch.app/Contents/MacOS/RepoWatch simply out of habit (which DOES work), so I am unsure how long this has been happening, or what change happened immediately before hand. The most likely change is that I put cp Info.plist ./RepoWatch.app/Contents/ into my make file in order to version Info.plist without versioning everything in the .app bundle.
I have looked at Info.plist many times and cannot find anything wrong with it. The file opens up with Property List Editor without any errors. Saving from Property List Editor does not make the file "work" (if it is to blame in the first place).
The permissions as far as I can tell also look sane:
$ ls -l
./RepoWatch.app/Contents/Info.plist
-rw-rw-r--# 1 dgrace staff 789 Feb 1 23:20 ./RepoWatch.app/Contents/Info.plist
$ ls -l
/Applications/Adium.app/Contents/Info.plist
-rw-rw-r-- 1 dgrace staff 5750 Aug 21 15:41 /Applications/Adium.app/Contents/Info.plist
I am at a loss as to what to try next.
And here are the contents of Info.plist (Even though nothing has really changed in quite a while):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>RepoWatch</string>
<key>CFBundleIdentifier</key>
<string>com.doomstick.RepoWatch</string>
<key>CFBundleName</key>
<string>RepoWatch</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.6</string>
<key>CFBundleVersion</key>
<string>Beta26</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>

Building on the answer that #smokris posted:
The problem seems to be with your app's registration in the Launch Services database. There is no need to rebuild the entire database. To force-update the entry for your app (specifically), use lsregister with the -f option:
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f MyApp.app
I was having the same problem you describe, and this worked for me. Thanks, #smokris!

Rebuilding the Launch Services database solves this problem for me.
Try executing the following command in Terminal:
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user

The problem is likely due to an invalid CFBundleExecutable property value in the Info.plist file you are copying into the application.
In Xcode projects the default value for this property is a special variable (placeholder) value (${EXECUTABLE_NAME}) that is expanded (replaced) when the build system builds the application. Are you sure you need to copy this file manually? Maybe you can add a script build phase that makes whatever changes you need after it has been expanded and copied into place by the normal build process.
While you are at it, you should check for other placeholder values in the file. It is likely that you will need to fill in CFBundleName (others may also be necessary, depending on your application type).

OK, some (more) shots in the dark.
The docs for LSMinimumSystemVersion say that the value is supposed to be a string with the form n.n.n. You might try adding a “.0” to the end of your value.
When you use ./RepoWatch.app/Contents/MacOS/RepoWatch to run it manually, are you using some sort of completion or filename generation, or are you typing it all in (especially the filename of the executable)?
Maybe the executable filename has some odd invisible/combining/look-alike character in it that does not match the value in Info.plist. Try ls -w /path/to/RepoWatch.app/Contents/MacOS/ | xxd to look at the bytes for anything non-ASCII.
Does plutil -lint /path/to/Info.plist give you an “OK”?
The # after the permissions in the ls -l output indicates some xattrs. These could be harmless, but have you looked at which ones are there with ls -l#?
If one of the xattrs looks suspect (or even if not) you could (cd /path/to/RepoWatch.app/Contents/ && mv Info.plist Info.plist.save && cat Info.plist.save > Info.plist) to get a copy without the xattrs and test with it.
If using the non-xattr'd file still causes problems, you might try systematically modifying and deleting keys (after making a backup copy, like the .save above) to see if you can cause a different error message that might help indicate the problem.

Project Menu > Set Active Executable

Related

launchctl - remove enabled/disabled override

On OS X Yosemite (10.10), is there any way to remove the enabled/disabled override setting for a service?
For example, to permanently disable non-existent service 'test' for root, do this:
sudo launchctl disable user/0/test
Check that it has been added to the disabled list:
sudo launchctl print-disabled user/0
Result:
disabled services = {
"test" => true
}
login item associations = {
}
Now, how can I delete "test" from the disabled services list?
(I know I can enable it, but I just want to remove the entry entirely.)
Note:
If I reboot my computer, I see that the 'test' override has been added to a launchd disabled file:
sudo cat /var/db/com.apple.xpc.launchd/disabled.0.plist
Result:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>test</key>
<true/>
</dict>
</plist>
I have tried running this command to manually delete it from the .plist file:
sudo /usr/libexec/Plistbuddy /var/db/com.apple.xpc.launchd/disabled.0.plist -c Delete:test
This does delete it from the file, but it just comes back again when I reboot my computer. Any ideas?
It seems like the nature of the info that used to be in overrides.plist has changed..
According to launchctl's man page for the "legacy" load / unload sub-commands..
-w Overrides the Disabled key and sets it to false or true for the load and unload subcommands respectively. In previous versions, this option would modify the configuration file. Now the state of the Disabled key is stored elsewhere on- disk in a location that may not be directly manipulated by any process other than launchd.
I guess now... the info is stored in the /var/db/com.apple.xpc.launchddirectory.
The contents of mine contained several plists.
config
disabled.0.plist
disabled.200.plist
...
disabled.501.plist
...
disabled.migrated
loginitems.0.plist
...
loginitems.501.plist
...
In this case, the file names are referring to the different Users' id's (501 being mine, 0 being root). Changing the keys in these files (as root, obviously) SHOULD remove the corresponding overrides with dark-overlord launchd.
If not, try editing these same files while booted to recovery, or some other drive - so as you can mess with them whilst launchd is not running/relentlessly trying to be boss.
I was able to do this using Single User Mode. The steps are:
Shut down your computer.
On startup, enter single-user mode (Command + S).
From the command line, type /sbin/mount -uw /
Edit the appropriate /var/db/com.apple.xpc.launchd/disabled.*.plist file, removing disabled items, as desired.
Type exit.
I've just solved this kinda problem with LaunchControl on yosemite…
its a must have amazing little GUI for managing your daemons and agents on OSX.
It has a lot of features…
So just install it with cask
$ brew cask install launchcontrol
then find your service (under Use Agents or Global Daemons or whatever… ) in the list on the left.
Select it and in the main menu go to Job=>Override Disabled key=>Always False
Then reboot and check...
Should work!
The configuration-files/scripts used by 'launchctl' are located in:
# Location of the LaunchAgents which run under the user own name (and is logged in).
$ cd $HOME/Library/LaunchAgents
# Location for the Deamons for running jobs without logged in user.
$ cd /Library/LaunchDaemons
# Location for the LaunchAgents which run as root when the user is logged in.
$ cd /Library/LaunchAgents
The following quick-and-easy commands for the XML-scripts (ending on .plist) are (assuming you are in one of the above listed directories and you may need a sudo):
# Loads the specified configuration file.
# Jobs that are not on-demand will be started as soon as possible.
$ The -w option overrides the disabled setting.
# The -F option forces the loading and ignores the Disabled key.
$ launchctl load <script-name.plist>
# Unloads the specified configuration file from the current started session.
$ The -w option overrides the disabled setting.
# The -F option forces the loading and ignores the Disabled key.
$ launchctl unload <script-name.plist>
# Removes the specified configuration from the list and does not appear after rebooting
$ launchctl remove <script-name.plist>
See the man page for launchctl at https://ss64.com/osx/launchctl.html for details.

Why are environment variables always null to Gradle (only) when run from IntelliJ IDEA?

I wrote a task in gradle that grabs an environment variable.
task run(type:Exec) {
def SYS_ENV = System.getenv("SYSTEM_ENV")
// do something with SYS_ENV
}
If I run this task with ./gradlew :taskName it's all fine, but if I run the same task from IntelliJ IDEA, (with the button, or from the gradle panel) the env variable comes out as null.
I tried restarting IntelliJ, I also tried the Invalidate Caches/Restart option, but nothing changes.
Isn't IntelliJ IDEA supposed to run the Gradle script exactly like I run it form the command? What can I do to grab an env variable from Grade so that the script doesn't fail when run form IntelliJ?
EDIT: I did a bunch of trials, and I could make lanchctl setenv MY_PATH MY_VALUE work, but it's not permanent, and adding setenv MY_PATH MY_VALUE to /etc/lanchd.conf does not make it so.
A relatively old question, but the following worked for me on Yosemite (10.10) so answering here in case others have the issue.
Support for launchd.conf was removed in Yosemite. LaunchAgents can be used in OSX to start per-user processes. You can use these to re-run the launchctl step in your question effectively persisting the environment variable
Create a user Launch Agent to set your variables (edit the environment variables and run the following in a terminal window)
cat << EOF > ~/Library/LaunchAgents/user.environment.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>user.environment</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>launchctl setenv MYPATH MY_VALUE</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
EOF
Restart your mac
Make sure you restart any open applications (e.g. IntelliJ). Just restarting didn't work for me, I needed to close and re-launch the apps.
References:
Setting environment variables via launchd.conf no longer works in OS X Yosemite/El Capitan/macOS Sierra?
https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html

Programmatically stop and start daemon

I want to stop my daemon from inside it. In other words daemon should stop and restart itself when a specific event occur. I am using following command it works fine in terminal but not inside daemon.
system("launchctl stop com.test.myDaemon");
Probably the simplest way of doing it.
In your daemon plist file add this
<key>KeepAlive</key>
<true/>
That way iOS will automatically restart your daemon when it quits for whatever reason (signal, exception, daemon itself).
When you need to restart your daemon simply call
exit(0);
creker's answer worked for me on a jailbroken iOS 7.0.4 phone. However, you should be able to make your launchctl work as well (yes, I tested this, too).
Here are some things you might want to check:
Are you doing something in your daemon's plist file that changes which user it runs as? If you are telling launchd to run your daemon as a non-root user, that might prevent your programmatic launchctl command from working.
Do you have an entry in your plist file for the OnDemand key? Normally, you shouldn't. I'm wondering if you do, and it's conflicting with the KeepAlive setting in creker's answer.
Are you sure that this command exactly (launchctl stop com.test.myDaemon) succeeds from the command line?
The reason I ask is that many people build their Launch Daemons based on a tutorial here. In general, it's a great tutorial. But, there is at least one mistake. In the sample daemon .plist file, the value here for Label:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.chrisalvares.DLocationDemon.plist</string>
is not correct. It shouldn't be com.chrisalvares.DLocationDemon.plist. It should just be com.chrisalvares.DLocationDemon. In many cases, it doesn't matter. But, if you are issuing launchctl stop commands, the name for Label must match what you pass to launchctl. If you repeated the mistake in the tutorial, then you either need to fix the plist file, or use this command:
system("launchctl stop com.test.myDaemon.plist");
    4. Finally, there might be an issue with calling exit(0). First, it's possible that if you run this enough times, and call exit(0) enough times, iOS might flag your process as a badly behaving process, and refuse to continue to restart it. I don't think these rules are documented anywhere, but there are other similar features in iOS that work this way. So, that might suggest using launchctl instead. The other thought I had is that, even though exit(0); worked once for me, it's possible that you should chose a different exit code (not 0). I know that with VoIP apps (which are similar to a daemon in some ways), iOS only restarts your app automatically if it exits with a non-zero exit code. So, you might try exit(1);.
Those are my best guesses.
References
https://developer.apple.com/library/mac/documentation/macosx/conceptual/bpsystemstartup/chapters/CreatingLaunchdJobs.html

My sandboxed app was running fine in 10.8 but in 10.9 it seems that user defaults .plist is not saved at all

Sandboxed app was running fine in 10.8 but in 10.9 it seems that user defaults. plist is not saved at all. The location of plist is:
~/Library/Containers/com.example.myapp/Data/Library/Preferences/com.example.myapp.plist
and if I delete it, it will not be created again. In 10.8 this was working.
Has anyone seen this before or can anyone suggest a solution?
Problem solved with a reboot, well short of.
Preferences are saved correctly and it works fine until I delete again the app container folder. Then a reboot is required again to fix this.
My work-around for this problem is to kill the 'cfprefsd' daemon processes after making a change to the .plist file:
ps auwx | grep cfprefsd | grep -v grep | awk '{print $2}' | xargs sudo kill -2
The daemons will be restarted after the next access of the .plist file and will then have the new value for the key that was changed.
It is unfortunate that this work-around is necessary but at least it works reliably.
I had this very issue last night (I am still developing my app). I fixed it by deleting the app container folder (moving the whole ~/Library/Containers/com.domain.appname to trash in Finder) and re-running the app.
I rebooted first as I saw that there was some sort of LSShared file, related to my app, that wouldn't be emptied from the trash before the reboot.
I can only imagine it's an intermittent bug in Mavericks (GM seed).
EDIT The comment about a bug may not be true; it looks like .plist files are "on their way out" according to this Apple Developer Forum thread. However at the end of the day my app (and the OPs) stopped working, so it isn't working reliably.

Deleting plist file does not reset app on macOS 10.9+

While developing a Cocoa application on 10.9, I have noticed that if I go to ~/Library/Preferences and delete the plist file for my app (to reset it), on the next build-and-run, the app behaves as if the plist file had never been deleted at all.
It took me a long time to track down why this happens and I did not see a question/answer about it on SO, so I'm writing this question and answering it myself to help others.
On 10.9, the system is doing some more robust "caching" of preferences. After deleting the plist file, I fired up Activity Monitor and force-killed the "cfprefsd" process. Be careful: there are multiple processes with this name running and you only want to kill the one running under your own user; do not kill the one running as root.
Doing this seems to flush the preferences cache and on the next run of my app, I get a pristine start-from-scratch launch.
Edit: As reported below, using defaults delete [your bundle identifier] at the command line also appears to eliminate the caching issue. I've had mixed success with this.
I found out that killing the user process cfprefsd will reflush the cache, so your changes will be kept
killall -u $USER cfprefsd
In terminal:
defaults delete com.somecompany.someapp
BTW, I've just released a GUI app that may be more convenient than working with the defaults command:
http://www.tempel.org/PrefsEditor
It works practically the same as Xcode's plist editor, but affects the user's app preferences directly.
To delete all your prefs, you could open your prefs in my Prefs Editor, Select All, then delete them with the Backspace or Delete key, and they're instantly all gone.
However, for this particular task, using defaults delete might still be quicker, especially if you put the command into a text file ending in ".command", and make it executable (with chmod +x). Then you can double click it from the Finder to execute it.