From 6b10bdb9e1983d9d4e1336a020e9ca4cbca7948b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Alm=C3=A9n?= <78877636+almenscorner@users.noreply.github.com> Date: Mon, 6 Oct 2025 13:02:22 +0200 Subject: [PATCH 1/2] Refactor uninstall script for improved clarity and functionality --- SupportCompanion/Scripts/Uninstall.zsh | 155 +++++++++++++++++++------ 1 file changed, 119 insertions(+), 36 deletions(-) diff --git a/SupportCompanion/Scripts/Uninstall.zsh b/SupportCompanion/Scripts/Uninstall.zsh index 7e16de4..515c752 100755 --- a/SupportCompanion/Scripts/Uninstall.zsh +++ b/SupportCompanion/Scripts/Uninstall.zsh @@ -1,40 +1,123 @@ #!/bin/zsh -# Script requires root so check for root access -if [ $(id -u) -ne 0 ]; then - echo "Please run this script as root or using sudo" - exit 1 +set -u # error on unset vars + +# --- helpers --------------------------------------------------------------- +log() { print -- "[uninstall] $*" } +warn() { print -- "[warn] $*" >&2 } +err() { print -- "[error] $*" >&2 } + +# run a command, ignore if it fails; print message +_try() { + local desc="$1"; shift + if "$@"; then + log "$desc: ok" + else + warn "$desc: skipped/failed" + fi +} + +# delete a file/dir if it exists +_rm_if_exists() { + local path="$1" + if [ -e "$path" ] || [ -L "$path" ]; then + /bin/rm -rf -- "$path" && log "removed: $path" || warn "failed to remove: $path" + else + log "not present: $path" + fi +} + +# get console user + uid +get_console_user() { + /usr/sbin/scutil <<< "show State:/Users/ConsoleUser" \ + | /usr/bin/awk '/Name :/ && $3 != "loginwindow" { print $3 }' +} +get_console_uid() { + /usr/sbin/scutil <<< "show State:/Users/ConsoleUser" \ + | /usr/bin/awk '/kCGSSessionUserIDKey/ {print $NF; exit}' +} + +# --- preflight ------------------------------------------------------------- +if [ "$(id -u)" -ne 0 ]; then + err "Please run this script as root or using sudo" + exit 1 fi -# Use Apple Recommended Method to detect the user signed in to the desktop -current_user=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') -console_user_uid=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/kCGSSessionUserIDKey/ {print $NF; exit}' ) -# Kill the process -echo "Killing the process..." -pkill -f SupportCompanion -# Remove user defaults -echo "Removing user defaults..." -sudo -u "${current_user}" defaults delete com.github.macadmins.SupportCompanion -# Unload launchctl job -echo "Unloading helepr launchctl job..." -launchctl unload -w /Library/LaunchDaemons/com.github.macadmins.SupportCompanion.helper.plist -# Remove launchctl job -echo "Removing helper launchctl job..." -rm -f /Library/LaunchDaemons/com.github.macadmins.SupportCompanion.helper.plist -# Remove launch agent -if [ -f "/Library/LaunchAgents/com.github.macadmins.SupportCompanion.agent.plist" ]; then - echo "Unloading launch agent..." - /bin/launchctl asuser "${console_user_uid}" /bin/launchctl unload -w /Library/LaunchAgents/com.github.macadmins.SupportCompanion.agent.plist - echo "Removing launch agent..." - rm /Library/LaunchAgents/com.github.macadmins.SupportCompanion.agent.plist + +APP_ID="com.github.macadmins.SupportCompanion" +HELPER_ID="com.github.macadmins.SupportCompanion.helper" +AGENT_ID="com.github.macadmins.SupportCompanion.agent" + +APP_PATH="/Applications/SupportCompanion.app" +HELPER_PATH="/Library/PrivilegedHelperTools/${HELPER_ID}" +DAEMON_PLIST="/Library/LaunchDaemons/${HELPER_ID}.plist" +AGENT_PLIST="/Library/LaunchAgents/${AGENT_ID}.plist" + +CONSOLE_USER=$(get_console_user || true) +CONSOLE_UID=$(get_console_uid || true) + +log "Console user: ${CONSOLE_USER:-unknown} (uid ${CONSOLE_UID:-n/a})" + +# --- stop processes -------------------------------------------------------- +log "Stopping application and helper if running" +_try "kill app" pkill -f SupportCompanion + +# --- defaults cleanup (non-fatal) ----------------------------------------- +if [ -n "${CONSOLE_USER:-}" ]; then + # Only attempt if domain exists to avoid noisy errors + if sudo -u "$CONSOLE_USER" /usr/bin/defaults domains | /usr/bin/grep -q -- "$APP_ID"; then + _try "delete user defaults" sudo -u "$CONSOLE_USER" /usr/bin/defaults delete "$APP_ID" + else + log "user defaults domain not present: $APP_ID" + fi +else + warn "No console user detected; skipping user defaults removal" fi -# Remove the app -echo "Removing the app..." -rm -rf /Applications/SupportCompanion.app -# Remove app data -echo "Removing helper..." -rm -rf "/Library/PrivilegedHelperTools/com.github.macadmins.SupportCompanion.helper" -# Forget the package -echo "Forgetting the package..." -pkgutil --forget com.github.macadmins.SupportCompanion > /dev/null 2>&1 -pkgutil --forget com.github.macadmins.SupportCompanion.LaunchAgent > /dev/null 2>&1 -pkgutil --forget com.github.macadmins.SupportCompanion.suite > /dev/null 2>&1 + +# --- launchd: daemon (helper) --------------------------------------------- +if [ -f "$DAEMON_PLIST" ]; then + log "Unloading helper launch daemon" + _try "launchctl unload daemon" /bin/launchctl unload -w "$DAEMON_PLIST" +else + log "daemon plist not present: $DAEMON_PLIST" +fi + +# Remove daemon plist regardless of unload outcome +_rm_if_exists "$DAEMON_PLIST" + +# --- launchd: agent (per-user) -------------------------------------------- +if [ -f "$AGENT_PLIST" ]; then + if [ -n "${CONSOLE_UID:-}" ]; then + log "Unloading launch agent for uid $CONSOLE_UID" + _try "launchctl unload agent" /bin/launchctl asuser "$CONSOLE_UID" /bin/launchctl unload -w "$AGENT_PLIST" + else + warn "No console uid; unloading agent in current context" + _try "launchctl unload agent (fallback)" /bin/launchctl unload -w "$AGENT_PLIST" + fi +else + log "agent plist not present: $AGENT_PLIST" +fi + +# Remove agent plist +_rm_if_exists "$AGENT_PLIST" + +# --- remove bits ----------------------------------------------------------- +log "Removing installed components" +_rm_if_exists "$APP_PATH" +_rm_if_exists "$HELPER_PATH" + +# --- pkg receipts ------------------------------------------- +forget_if_present() { + local package="$1" + if /usr/sbin/pkgutil --pkgs | /usr/bin/grep -qx -- "$package"; then + _try "forget $package" /usr/sbin/pkgutil --forget "$package" + else + log "receipt not present: $package" + fi +} + +forget_if_present "${APP_ID}" +forget_if_present "${APP_ID}.LaunchAgent" +forget_if_present "${APP_ID}.suite" + +log "Uninstall completed" +exit 0 From e455955207614e9f568ed4a6aae50b57b25afc0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Alm=C3=A9n?= <78877636+almenscorner@users.noreply.github.com> Date: Mon, 6 Oct 2025 13:02:30 +0200 Subject: [PATCH 2/2] Bump version --- CHANGELOG.md | 4 ++ SupportCompanion/Info.plist | 78 ++++++++++++++++++------------------- 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eba2f9a..1d48241 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.3.1] - 2025-10-06 +### Changed +- Refactored the uninstall script with better error handling and logging. + ## [2.3.0] - 2025-09-18 ### Changed - Updated UI elements to match the new look introduced in macOS 26 (Tahoe). diff --git a/SupportCompanion/Info.plist b/SupportCompanion/Info.plist index 9bb3fbf..3ada032 100644 --- a/SupportCompanion/Info.plist +++ b/SupportCompanion/Info.plist @@ -1,42 +1,42 @@ - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleIconFile - AppIcon - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - CFBundleShortVersionString - 2.3.0 - CFBundleVersion - 2.3.0 - CFBundleURLTypes - - - CFBundleURLName - com.github.macadmins.SupportCompanion - CFBundleURLSchemes - - supportcompanion - - - - SMPrivilegedExecutables - - com.github.macadmins.SupportCompanion.helper - anchor apple generic and identifier "com.github.macadmins.SupportCompanion.helper" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = $(TEAM_ID)) - - - + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleIconFile + AppIcon + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + CFBundleShortVersionString + 2.3.1 + CFBundleVersion + 2.3.1 + CFBundleURLTypes + + + CFBundleURLName + com.github.macadmins.SupportCompanion + CFBundleURLSchemes + + supportcompanion + + + + SMPrivilegedExecutables + + com.github.macadmins.SupportCompanion.helper + anchor apple generic and identifier "com.github.macadmins.SupportCompanion.helper" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = $(TEAM_ID)) + + + \ No newline at end of file