Quitting an application before updating

mconners
Valued Contributor

Forgive me if this topic has been discussed before, but I haven't found what I am expecting to see.

We have a couple of scripts that will uninstall applications like MS Office, Adobe CC 2018 and a few more applications. In these scripts, we simply look for occurrences of items in various folders. They run perfectly on the Macs via self service or other policy mechanisms. The problem is, if a user has one of these applications open when the policy is run, it leaves the computer and applications in a very unstable state.

Ideally, this would be run at logout to ensure no one is logged in. For most of our laptop users, this simply won't happen. Desktops, we hit at night when no one is here.

Does anyone have a script or other mechanism they would use to verify whether or not an application is running before the update process is run? We have tried an AppleScript using the system events stuff, but that will only run locally and I can't find a way to run it via a policy or remotely.

Thank you for your replies and insights. Unfortunately, I am not well versed in scripting so this is a little tougher than it probably needs to be.

13 REPLIES 13

sshort
Valued Contributor

You can add pkill -f Microsoft to force quit any process with "Microsoft" in the title.

mconners
Valued Contributor

Thank you @sshort. Do you know if a user has unsaved work if this will "gently" shutdown the app? I was hoping to be gentle so they can save their work prior to updating.

donmontalvo
Esteemed Contributor III

@mconners wrote:

Thank you @sshort.

@mconners thanks for the laugh (pretty sure it was unintentional). 🙂


--
https://donmontalvo.com

andymcp
New Contributor III

My biggest frustration with Jamf's Patch Policies is that it doesn't have an automatic "if app isn't running, update" and "if app is running, defer" option to perform silent updates that don't interrupt our users. For that, I've been using Auto Update Magic that has an easily customizable script that will check if an app is running and if not, run a policy with a custom trigger to perform an update.

It's also a great way to get familiar with autopkg and develop an automated packaging, testing and deployment workflow. It seems like a lot at first glance, but it's definitely worth spending some time with!

JustDeWon
Contributor III

This should help you. You should be able to check against multiple processes, if you wanted to add more. S/O to @mm2270 giving the idea to kill multiple processes.

#!/bin/sh

# Set the variables
procList=("Microsoft"
"Adobe")
procName=""

#Check to see if either of those processes are running
for proc in "${procList[@]}"; do
    runningProc=$(ps axc | grep -i "$proc" | awk '{print $1}')
    if [[ $runningProc ]]; then
        echo "$proc is running with PID: ${runningProc}"
        procName=$"$procName $proc"
        kill $runningProc
    else
         echo "$proc not running"
    fi
done

ryan_ball
Valued Contributor

I would do something like @JustDeWon posted but if one of the processes is detected then you could display a prompt for the user to close the applications, then once the apps are no longer detected, the script would continue. Of course you should probably have a timeout during the prompt portion so that if they don't close the apps within a certain amount of time the script exits abnormally.

However, if your scripting skills are low, you could just display a prompt with a script before the uninstall script for the user to close the apps.

sshort
Valued Contributor

This is how Microsoft handles it in the preinstall script for Word:

APPNAME="Microsoft Word"

# Tests whether the app to be updated is closed - returns 1 if closed, or 0 if running
function is_app_closed()
{
    /usr/bin/pgrep -q "$APPNAME"
    /bin/echo "$?"
    return
}

# Attempt to gracefully close the app. If the document is dirty, the user will have 120 seconds to respond to the dialog before a timeout occurs
function gracefully_close_app()
{
    /usr/bin/osascript <<-EOD
        tell application "$APPNAME" to quit
    EOD
    sleep 5
}

# AppleScript to alert the user that the app needs to close
function show_update_alert()
{
    /usr/bin/osascript <<-EOD
    tell application "Finder"
        activate
        set DialogTitle to "Microsoft Office"     
        set DialogText to "Word will be updated in 60 seconds. Save all data, then click the 'Update Now' button."
        set DialogButton to "Update Now"
        set DialogIcon to "Applications:Microsoft Word.app:Contents:Resources:MSWD.icns"
        display dialog DialogText buttons {DialogButton} with title DialogTitle with icon file DialogIcon giving up after 60
    end tell
    EOD
}

# Send the app a signal to forcibly close the process
function forcibly_close_app()
{
    /usr/bin/pkill -HUP "$APPNAME"
}

donmontalvo
Esteemed Contributor III

@JustDeWon if @mm2270 got a nickel for beer every time someone used his brilliant loop, he'd be one sloppy drunk JAMF'er. :)

--
https://donmontalvo.com

kendalljjohnson
Contributor II

This is what I came up with to address this. Allows user interaction if the app is open with a deferral system and eventually forces the update. Most up to date version of the script is near the bottom of the thread.

mconners
Valued Contributor

These are amazing guys!! Thank you so much! I will get working on this soon. I have been side tracked by other "duties as assigned." Enjoy your days!!

jan_rosenfeld
New Contributor III

@sshort Question for you! So, if I were to push a MSOffice pkg - let's say the current 16.34 - to a client machine that currently has Word open - this is the script that would run as part of the pkg?

pbowden
Contributor III

@jan.rosenfeld yup, that’s correct. The pkill -HUP was an invention of mine to instruct the apps to flush all files and close as gracefully as possible.

jan_rosenfeld
New Contributor III

@pbowden excellent! ran over the weekend with no problems. big fan of your work by the way - love what you're doing with MS and JAMF - and enjoy the webinars/videos!