SMLoginItemSetEnabled Demystified

Have you ever wondered how the SMLoginItemSetEnabled function works? How to remove an application from launching at login from outside that application? Well, read on.

Consider you have an Mac application that is to run sandboxed and that you want to provide with launch at login functionality. The only working way to achieve this is to use the SMLoginItemSetEnabled function, which is part of the Service Management Framework. For a more detailed explanation on how to get launch at login functionality up and running in such a situation, see my tutorial.

Consider further that you have successfully implemented such a feature and shipped your application, but now want to update your application to not run in a sandbox anymore. Sounds like a strange turn of things, but this may happen, e.g., if you designed an application to be distributed in the Mac App Store (and shipped it), but now there are compelling reasons to remove the sandbox functionality and to switch to direct distribution outside the Mac App Store.

It is then sensible to provide launch at login functionality no longer via SMLoginItemSetEnabled (and a helper app), but via a shared file list as provided by the Launch Services Framework, which has the distinctive advantage that your application will be visibly marked as launching at login in the System Preferences and that the user can edit this behaviour from the System Preferences (which is not the case with the launch at login functionality providing via SMLoginItemSetEnabled).

In such a situation your updated application is not sandboxed anymore. However, you can still disable the application launching at login via SMLoginItemSetEnabled by using one of these approaches:

  1. Leave the helper app you had in your old application version inside the updated application bundle and call SMLoginItemSetEnabled to remove the helper app from launching at login. This will work, even if neither the main application nor the helper app are sandboxed anymore. Calling SMLoginItemSetEnabled will fail if the (now dysfunctional) helper app is not in your updated application bundle anymore.
  2. Fidlle around with the property list file located at /var/db/launchd.db/<UID>/overrides.plist, where <UID> is your user id as retrievable via the System Configuration Framework’s SCDynamicStoreCopyConsoleUser Function. Helper apps to be launched at login via SMLoginItemSetEnabled are stored inside this overrides.plist file, just delete the appropriate lines containing the helper app’s bundle identifier and you’re done.