Deleting app while its running &

I'm writing an uninstaller, lets call it UNINS, for my developer id signed Mac app, lets call it APP(it contains system extensions) . UNINS is supposed to delete APP and its associated data. But after INS is done, it needs to delete itself.

  1. From my experience, when an app is running and we try to delete it, OS does not allow this operation. How to do this correctly?

  2. During uninstallation, if we delete an app from /Applications folder, do we also manually need to delete its data from ~/Library/Containers for all users ? Or this is done automatically by OS?

  3. if I need to unload launchdaemon that we installed, can this UNINS do that ? (Because I think unloading daemons require root priveleges)

Replies

You tagged your thread with System Extensions. Does that mean your app includes a system extension?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • Yes, the APP contains system extensions

Add a Comment

@eskimo Yes, the app contains system extension

Uninstalling an app that contains a system extension is tricky. When you activate a system extension, the system makes a copy of it. The only supported way to remove that copy is to deactivate the system extension using deactivationRequest(forExtensionWithIdentifier:queue:).

As to your specific questions:

  1. From my experience, when an app is running and we try to delete it, OS does not allow this operation. How to do this correctly?

It’s traditional to do this from a tool or script that you copy out of the app into a temporary location. The app then runs that, which waits for the app to quit before deleting it.

  1. During uninstallation, if we delete an app from /Applications folder, do we also manually need to delete its data from ~/Library/Containers for all users ? Or this is done automatically by OS?

It is not done automatically by macOS. That’s true even for apps where macOS manages the install and uninstall process, for example, for a Mac App Store app. That’s because the system doesn’t know whether the user has a copy of the app elsewhere, for example, on an external hard drive.

  1. if I need to unload launchdaemon that we installed, can this UNINS do that?

How did you install it? Ideally you’d use SMAppService, where you can uninstall the daemon using unregister(completionHandler:).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for the answers!

  1. Regarding your question 'how did you install it':

We wanted our main app to run all the time (even if it's force-quit or machine restarted). So during the installation (via bash scripts), we copy a launchagent plist file to /Library/LaunchAgents. At the end of the installation, we load this agent using 'launchctl bootstrap' command, to keep it running forever. Not 100% sure how SMAppService is different (better?) from the plist launch agent.

  1. Regarding your feedback 'The only supported way to remove that copy is to deactivate the system extension using':

Does this mean that the extension is not removed, when the user just deletes the app from /Applications folder ? (or we uninstall it using a script, eg. rm /Applications/APP.app ?

Not 100% sure how SMAppService is different (better?) from the plist launch agent.

SMAppService is better on many axes (-: Sadly, your specific situation isn’t one of them. You’re installing a global launchd agent, which is the one case that SMAppService doesn’t handle. We already have a bug on file about this (r. 92457638), but I have no info to share as to if or when it’ll be fixed. If you want to track its status, file a bug and ask it to be marked as a dup of this one.

At the end of the installation, we load this agent using launchctl bootstrap command, to keep it running forever

FYI, this only loads your agent into the current user’s session. If there are other GUI users logged in, they won’t get your agent until they log out and then log back in again.

Loading your agent into all sessions is… well… possible but challenging.

Does this mean that the extension is not removed, when the user just deletes the app from /Applications folder?

No. If you have an app with a system extension installed and the user drags it to the trash, the Finder will confirms whether they want to uninstall the system extension.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"