Created
September 5, 2016 08:27
-
-
Save Leask/36ba4c97f8fa35fa2a17a71a3e114929 to your computer and use it in GitHub Desktop.
Find and remove existing installations of Parallels Access
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# Find and remove existing installations of Parallels Access | |
export PATH=/bin:/sbin:/usr/bin:/usr/sbin | |
RootCheck () { | |
if [ $(id -u) != "0" ] | |
then | |
sudo -p "This script requires administrative privileges. Please enter your password: " "$0" "$@" | |
exit $? | |
fi | |
} | |
function GetUsers() { | |
for usr in `ls -1 /Users/ | grep -ivw Shared | grep -ve '^\\.'`; do | |
[ -d "/Users/$usr" ] || continue | |
id "$usr" >/dev/null 2>&1 || continue | |
echo "$usr" | |
done | |
} | |
RemoveFile() { | |
local filename="${1}" | |
if [ -e "${filename}" ]; then | |
echo " - Removing ${filename}" | |
rm -rf "${filename}" | |
fi | |
} | |
RemoveStatFiles() { | |
for stat_file in /private/var/db/Parallels/Stats/Parallels\ Access* | |
do | |
RemoveFile "${stat_file}" | |
done | |
} | |
RunCommandForEachUser() { | |
local command="$@" | |
local parent_proc='/System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow' | |
ps -Awww -opid,user,command | \ | |
awk "{if (\$3==\"${parent_proc}\") system(\"launchctl bsexec \"\$1\" sudo -u \"\$2\" ${command}\")}" | |
} | |
UnloadKernelExtension () { | |
local BundlePath="${1}" | |
local KextBundlePath="${BundlePath}/Contents/Library/Extensions/10.6" | |
local KextMod="$KextBundlePath/${2}" | |
local KextModName=`basename "${KextMod}"` | |
if [ -d "${BundlePath}" ]; then | |
kext_id=`defaults read "${KextMod}/Contents/Info.plist" CFBundleIdentifier 2>/dev/null` | |
else | |
kext_id=`defaults read "${KextBundlePath}/${KextModName}/Contents/Info.plist" CFBundleIdentifier 2>/dev/null` | |
fi | |
if [ "${kext_id}" == "" ]; then | |
return | |
fi | |
echo " - Unloading kernel extension: ${KextModName}" | |
res=1 | |
COUNTER=3 | |
while [ $COUNTER -gt 1 ]; do | |
# Return immediately if extension unloaded | |
kextstat | grep -qs "${kext_id}" | |
if [ $? -ne 0 ]; then | |
res=0 | |
break | |
fi | |
# Else retry | |
kextunload "${KextMod}" | |
let COUNTER-=1 | |
done | |
test $res -eq 0 || echo "Failed to unload kernel extension ${KextModName}" | |
} | |
UninstallLaunchdItem() { | |
local launchd_id="${1}" | |
local launchd_type="${2}" | |
case "${launchd_type}" in | |
agent) local launchd_path="/Library/LaunchAgents/${launchd_id}.plist" | |
;; | |
daemon) local launchd_path="/Library/LaunchDaemons/${launchd_id}.plist" | |
;; | |
*) return | |
;; | |
esac | |
if [ ! -e "${launchd_path}" ]; then | |
return | |
fi | |
echo " - Uninstalling Launchd item: $launchd_id" | |
case "${launchd_type}" in | |
agent) RunCommandForEachUser \ | |
launchctl unload -S Aqua "${launchd_path}" | |
;; | |
daemon) launchctl stop "${launchd_id}" | |
launchctl unload -wF "${launchd_path}" | |
;; | |
*) return | |
;; | |
esac | |
rm -f "${launchd_path}" | |
} | |
UninstallInputMethod() { | |
local PrlImBundle="${1}" | |
local PrlIm="${PrlImBundle}/Contents/MacOS/ParallelsIM" | |
if [ ! -e "${PrlImBundle}" ]; then | |
return | |
fi | |
echo " - Uninstalling Input Method: ${PrlImBundle}" | |
"${PrlIm}" --disable | |
"${PrlIm}" --terminate | |
rm -rf "${PrlImBundle}" | |
} | |
TerminateRunningWizards () { | |
local pid_file | |
local pid_files=`find /var/run/parallels -name '*deskctl_wizard*.pid'` | |
# find out prl_deskctl_wizard PID from .pid file(s) and terminate them | |
for pid_file in ${pid_files}; do | |
echo " - Terminating ${pid_file}" | |
kill -TERM `cat ${pid_file}` | |
done | |
sleep 0.5 | |
pid_files=`find /var/run/parallels -name '*deskctl_wizard*.pid'` | |
# find out prl_descktl_wizard processes which were not terminated and kill them | |
for pid_file in ${pid_files}; do | |
echo " - Failed to terminate ${pid_file}; forcing" | |
kill -KILL `cat ${pid_file}` | |
rm -f ${pid_file} | |
done | |
} | |
TerminateRunningWizardsUsingKill() { | |
local WizardName="${1}" | |
ps -Awwwc -opid,command | \ | |
awk "{if (\$2 ~ /${WizardName}/) system(\"echo ' - Unloading Desktop Control Wizard:' ${WizardName} && kill -9 \"\$1\"\")}" | |
} | |
UninstallMainBundle() { | |
local BundlePath="${1}" | |
if [ ! -e "${BundlePath}" ]; then | |
return | |
fi | |
echo " - Uninstalling App bundle: ${BundlePath}" | |
rm -rf "${BundlePath}" | |
} | |
UninstallDispatcherConfigFiles() { | |
local XmlConfigName="${1}" | |
local PlistConfigName="${2}" | |
local XmlConfigBase="/Library/Preferences/Parallels" | |
local PlistConfigBase="/var/root/Library/Preferences/" | |
local XmlConfigPath="${XmlConfigBase}/${XmlConfigName}" | |
local PlistConfigPath="${PlistConfigBase}/${PlistConfigName}" | |
if [ ! -f "${XmlConfigPath}" -a ! -f "${PlistConfigPath}" -a ! -f "${PlistConfigPath}.lockfile" ]; then | |
return | |
fi | |
echo " - Uninstalling Dispatcher config files" | |
rm -f "${XmlConfigPath}" | |
rm -f "${PlistConfigPath}" | |
rm -f "${PlistConfigPath}.lockfile" | |
if [ -z "`find ${XmlConfigBase} -type f`" ]; then | |
rm -r "${XmlConfigBase}" | |
fi | |
} | |
RootCheck | |
echo "Purging Parallels Access" | |
UnloadKernelExtension "/Applications/Parallels Access.app" "prl_virtual_sound.kext" | |
UninstallLaunchdItem "com.parallels.mobile.kextloader.launchdaemon" daemon | |
UninstallLaunchdItem "com.parallels.mobile.dispatcher.launchdaemon" daemon | |
UninstallLaunchdItem "com.parallels.mobile.prl_deskctl_agent.launchagent" agent | |
UninstallLaunchdItem "com.parallels.mobile.startgui.launchagent" agent | |
UninstallLaunchdItem "com.parallels.mobile.agent.launchagent" agent | |
UninstallLaunchdItem "com.parallels.mobile.startgui.launchdaemon" agent | |
UninstallInputMethod "/Library/Input Methods/ParallelsIM.app" | |
TerminateRunningWizards | |
TerminateRunningWizardsUsingKill "prl_deskctl_wizard" | |
TerminateRunningWizardsUsingKill "prl_deskctl_agent" | |
TerminateRunningWizardsUsingKill "prl_pm_service" | |
UninstallDispatcherConfigFiles "dispatcher.pmobile.xml" "com.parallels.mobile.plist" | |
UninstallMainBundle "/Applications/Parallels Access.app" | |
UninstallMainBundle "/Applications/Parallels Mobile.app" | |
UninstallMainBundle "/Applications/Parallels Personal Cloud.app" | |
for user in $(GetUsers): | |
do | |
RemoveFile "/Users/$user/Library/Preferences/com.parallels.Parallels Access.plist" | |
RemoveFile "/Users/$user/Library/Preferences/com.parallels.Parallels Access.plist.sdb" | |
done | |
RemoveFile "/Library/Preferences/com.parallels.Parallels Access.plist.sdb" | |
RemoveFile "/Library/Preferences/Parallels/vmdirectorylist.pmobile.xml" | |
RemoveFile "/private/etc/com.parallels.mobile.prl_deskctl_agent.launchd" | |
RemoveStatFiles | |
echo "Done. Your system is pristine." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment