This presentation describes the ways to add a daemon or an agent to macOS—both using system API (SMJobBless(), SMLoginItemSetEnabled()) and command-line tool launchctl.
with Daemon/Agent configuration to specified location in system* 2. If adding Daemon or Agent for all users, set plist's owner to root (sudo chown root) 3. Load this .plist to launchd (this step can be skipped: in that case launchd will load .plist from listed locations during the next login. But if you want your job to start now, you need to load .plist) */Library/LaunchAgents | ~/Library/LaunchAgents for agent * /Library/LaunchDaemons for daemon for more details on plist configuration files see next slides of this presentation and man launchd.plist
to load Daemon or SMLoginItemSetEnabled() to load Agent. 2. Remember to follow additional requirements for given API to work properly. for more details see next slides of this presentation
all users: sudo launchctl load /Library/LaunchAgents/com.mycompany.myagent.plist * Agent for one user: launchctl load ~/Library/LaunchAgents/com.mycompany.myagent.plist Remove: * Daemon: sudo launchctl unload /Library/LaunchDaemons/com.mycompany.mydaemon.plist * Agents for all users: sudo launchctl unload /Library/LaunchAgents/com.mycompany.myagent.plist * Agent for one user: launchctl unload ~/Library/LaunchAgents/com.mycompany.myagent.plist How to load Daemon/Agent .plist to launchd Command-line API before 10.11
10.11 Add: * Daemon: sudo launchctl bootstrap system /Library/LaunchDaemons/com.mycompany.mydaemon.plist 'system' is the 'domain' of the submitted executable. See man launchctl for details about domains
10.11 Add: * Daemon: sudo launchctl bootstrap system /Library/LaunchDaemons/com.mycompany.mydaemon.plist * Agents for all users: sudo launchctl bootstrap gui/501 /Library/LaunchAgents/com.mycompany.myagent.plist Domain for user agent is 'gui/[user id]'. To register agent for all users you should call this command with every user id as given user (not as root).
the main application bundle’s “Contents/Library/LoginItems” directory. Compatible with AppStore Enable a daemon. Replaces AuthorizationExecuteWithPrivileges() NOT compatible with AppStore How to add Daemon/Agent from code after 10.7
and target executable tool must both be signed. 2. The calling application's Info.plist must include a "SMPrivilegedExecutables" dictionary of strings. Each string is a textual representation of a code signing requirement used to determine whether the application owns the privileged tool once installed (i.e. in order for subsequent versions to update the installed version). See example on next slide. 3. The helper tool must have an embedded Info.plist containing an "SMAuthorizedClients" array of strings. Each string is a textual representation of a code signing requirement describing a client which is allowed to add and remove the tool. How to embed: see futher. 4. The helper tool must have an embedded launchd plist. The only required key in this plist is the Label key. When the launchd plist is extracted and written to disk, the key for ProgramArguments will be set to an array of 1 element pointing to a standard location. You cannot specify your own program arguments, so do not rely on custom command line arguments being passed to your tool. Pass any parameters via IPC. 5. The helper tool must reside in the Contents/Library/LaunchServices directory inside the application bundle, and its name must be its launchd job label. So if your launchd job label is "com.apple.Mail.helper", this must be the name of the tool in your application bundle. Details: https://developer.apple.com/documentation/servicemanagement/1431078-smjobbless
the Daemon) 2. Obtain SFAutorization object (for kAuthorizationRightExecute) 3. Call SMJobBless with required arguments: — domain kSMDomainSystemLaunchd — label of the Daemon — AuthorizationRef from obtained authorization — reference to NSError object That's it: now you can talk to your Daemon via XPC to ask it to do its job.
must reside in the Contents/Library/LoginItems directory inside the application bundle. Details: https://developer.apple.com/documentation/servicemanagement/1501557-smloginitemsetenabled
must reside in the Contents/Library/LoginItems directory inside the application bundle. Details: https://developer.apple.com/documentation/servicemanagement/1501557-smloginitemsetenabled Yes, that's it.
the Agent) 2. Call SMLoginItemSetEnabled() with required arguments: — agent's bundle identifier — `true` or `false` depending if you want to run it right now