Deploy Automator .Workflow file

alaiuppa
New Contributor

Hello,

I've made a service through Automator, and binded it to a keyboard shortcut.

Would there be any simple way to make this available through say self service? Or deploy it with a policy?

I've tried googling around a little and read about the installation of a .workflow file, so I think I could throw something together but I thought I'd see if anyone has already tried something similar.

Thanks!

4 REPLIES 4

mm2270
Legendary Contributor II

Hi. I assume you want to do more than simply deploy the workflow file onto the Mac. It sounds like you also want to deploy the keyboard shortcut binding, correct?

If so, those shortcuts are stored in a pbs.plist file that lives in the user's /Library/Preferences/ folder.

You have a few options. You can potentially capture that pbs.plist file on a clean system that doesn't have any other custom keyboard shortcuts, and deploy it in a DMG file with the Fill Existing Users option checked. This will push the pbs.plist file into place for each user account. The one big issue with doing this is that you run the risk of overwriting any custom keyboard shortcuts the user may have put in place on their own.
Another option is to write in the shortcut settings to the pbs.plist file (if it exists) using PlistBuddy (defaults can't really do it as its too complicated)

Along with the above steps, you'd also of course need to deploy the .workflow file into the user's /Library/Services/ directory.

If I recall when I had done this, I think a service or application needs to be restarted in order for the Finder to recognize the newly installed service and shortcut. I think actually its the Finder itself that needs the restart, but I'd need to go back and look again.

Note that I haven't done this since around 10.9 and early 10.10, so I don't know if things have changed with 10.11 and 10.12 now.

alaiuppa
New Contributor

@mm2270

Thanks for the quick reply! You are correct in that I also want to deploy the keyboard shortcut binding.

That looks like a great way of going about it but the risk of overwriting any custom keyboard shortcuts is an unfortunate one.

I guess I'll have to work with it a bit and see if I can get the desired result with minimal potential for things to go wrong.

mm2270
Legendary Contributor II

@alaiuppa Just so you don't need to build this all from scratch, here is a version of the script I had done for this, with a few modifications so as to make it into a kind of template to use. This was contained within a pkg installer as a postinstall script. What it did was deploy some files into /private/tmp/ and then the script would either move files into place, or make the needed changes to the plist file. In this script I renamed the workflow to just "Service.workflow" You'd need to rename it to what you called your actual workflow file.

Also, in the section where it uses PlistBuddy to write in the keyboard shortcut, I first examined the pbs.plist file to see how the shortcut was written in. In the script below, you'll see it added in a string like "@~^l" which becomes Command-Option-Control-L. Again, I would do a defaults read against the pbs.plist file that has the shortcut added to examine how it added it so you can duplicate that in a script.

#!/bin/sh

## Get the logged in username
currUser=$(/usr/bin/stat -f%Su /dev/console)

## Check for a 'Services' folder in the user's home directory. Create one if necessary

if [ ! -d /Users/$currUser/Library/Services ]; then
    echo "Creating Services directory for $currUser"
    mkdir /Users/$currUser/Library/Services
    sudo chown -R $currUser /Users/$currUser/Library/Services
fi

## Check to see if the workflow file was installed in /tmp
## and copy it to the current user's home Library folder
if [ -d /private/tmp/Service.workflow ]; then
    sudo cp -R /private/tmp/Service.workflow /Users/$currUser/Library/Services/
        echo "Copied the workflow to $currUser's Services folder"
    sudo chown -R $currUser /Users/$currUser/Library/Services/Service.workflow
        echo "Set permissions on the workflow to $currUser as owner"
    sudo chmod -R go-rwx /Users/$currUser/Library/Services/Service.workflow
        echo "Set access on the workflow for $currUser"
else
    ## Exit the rest of the installation if the workflow wasn't there to copy
    echo "The Service workflow was not found. Exiting installation..."
/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -title "Installation failed" -description "We seem to have run into a problem getting the service installed for you. Try running the Self Service installation again. If you continue to see this error, contact support so we can help correct this for you." -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertCautionIcon.icns" -button1 "OK" -defaultButton 1
    exit 1
fi

## Taking care of the shortcut for the LockScreen workflow in the current user's pbs.plist file
if [ ! -e /Users/$currUser/Library/Preferences/pbs.plist ]; then
    if [ -e /private/tmp/pbs.plist ]; then
        cp /private/tmp/pbs.plist /Users/$currUser/Library/Preferences/
        theDate=$(date +"%s")
        /usr/bin/defaults write /Users/$currUser/Library/Preferences/pbs NSServicesUserDirectoryModDate -float $theDate
        chown $currUser /Users/$currUser/Library/Preferences/pbs.plist
        chmod go-rwx /Users/$currUser/Library/Preferences/pbs.plist
    else
        ## if we couldn't find an existing pbs.plist file for the user and the file was missing from /tmp
        ## then we exit the rest of the installation
        echo "The pbs.plist file was not found. Exiting..."
        exit 1
    fi
    else
    ## If we found an existing plist file for the user, use PlistBuddy to add the keyboard shortcut instead
    /usr/libexec/PlistBuddy -c 'Add :NSServicesStatus:"(null) - Service - runWorkflowAsService":key_equivalent string "@~^l"' /Users/$currUser/Library/Preferences/pbs.plist  
    echo "Added LockScreen shortcut to $currUser's existing plist file"
    ## Update the date modified string for the user's Services directory
    theDate=$(date +"%s")
    /usr/bin/defaults write /Users/$currUser/Library/Preferences/pbs NSServicesUserDirectoryModDate -float $theDate
    chown $currUser /Users/$currUser/Library/Preferences/pbs.plist
    chmod go-rwx /Users/$currUser/Library/Preferences/pbs.plist
fi

## Now we check to make sure everything is in place
if [ -e /Users/$currUser/Library/Services/Service.workflow ]; then
    echo "The Service was installed"
    serviceFile="Yes"
fi

if [ -e /Users/$currUser/Library/Preferences/pbs.plist ]; then
    echo "The shortcut file exists"
    shortcutFile="Yes"
fi

sleep 2
killall Finder

## Final clean up stage
rm -R /private/tmp/Service*
rm /private/tmp/pbs.plist

See if you can use this to get you where you need to go. Remember that I have not used this since around 10.10, so it may need work for 10.11 and 10.12.

kendalljjohnson
Contributor II

@alaiuppa @mm2270

Not sure if either of you care about this conversation anymore but I needed to find a solution like this. The only addition I had to make to your script to make it work on 10.12 was to reload the com.apple.pbs.plist which updated the connection between the pbs.plist shortcut and the new service.

I also made a few tweaks like updating the keyboard shortcut to be in line with High Sierra's lock screen key command. Thanks @mm2270 for the script, saved me a lot of time and brainpower!

#!/bin/sh

## Get the logged in username
currUser=$(/usr/bin/stat -f%Su /dev/console)

## Check for a 'Services' folder in the user's home directory. Create one if necessary

if [ ! -d /Users/$currUser/Library/Services ]; then
    echo "Creating Services directory for $currUser"
    mkdir /Users/$currUser/Library/Services
    sudo chown -R $currUser /Users/$currUser/Library/Services
fi

## Check to see if the workflow file was installed in /tmp
## and copy it to the current user's home Library folder
if [ -d /private/tmp/ScreenSaver/LaunchScreenSaver.workflow ]; then
    sudo cp -R /private/tmp/ScreenSaver/LaunchScreenSaver.workflow /Users/$currUser/Library/Services/
        echo "Copied the workflow to $currUser's Services folder"
    sudo chown -R $currUser /Users/$currUser/Library/Services/LaunchScreenSaver.workflow
        echo "Set permissions on the workflow to $currUser as owner"
    sudo chmod -R go-rwx /Users/$currUser/Library/Services/LaunchScreenSaver.workflow
        echo "Set access on the workflow for $currUser"
else
    ## Exit the rest of the installation if the workflow wasn't there to copy
    echo "The Service workflow was not found. Exiting installation..."
    exit 1
fi

## Taking care of the shortcut for the LockScreen workflow in the current user's pbs.plist file
if [ ! -e /Users/$currUser/Library/Preferences/pbs.plist ]; then
    if [ -e /private/tmp/ScreenSaver/pbs.plist ]; then
        cp /private/tmp/ScreenSaver/pbs.plist /Users/$currUser/Library/Preferences/
        theDate=$(date +"%s")
        /usr/bin/defaults write /Users/$currUser/Library/Preferences/pbs NSServicesUserDirectoryModDate -float $theDate
        chown $currUser /Users/$currUser/Library/Preferences/pbs.plist
        chmod go-rwx /Users/$currUser/Library/Preferences/pbs.plist
    else
        ## if we couldn't find an existing pbs.plist file for the user and the file was missing from /tmp
        ## then we exit the rest of the installation
        echo "The pbs.plist file was not found. Exiting..."
        /Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -windowType utility -title "Installation failed" -description "The Screen Saver shortcut did not install properly." -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertCautionIcon.icns" -button1 "OK" -defaultButton 1
        exit 1
    fi
    else
    ## If we found an existing plist file for the user, use PlistBuddy to add the keyboard shortcut instead
    /usr/libexec/PlistBuddy -c 'Add :NSServicesStatus:"(null) - LaunchScreenSaver - runWorkflowAsService":key_equivalent string "@^q"' /Users/$currUser/Library/Preferences/pbs.plist
    echo "Added LockScreen shortcut to $currUser's existing plist file"
    ## Update the date modified string for the user's Services directory
    theDate=$(date +"%s")
    /usr/bin/defaults write /Users/$currUser/Library/Preferences/pbs NSServicesUserDirectoryModDate -float $theDate
    chown $currUser /Users/$currUser/Library/Preferences/pbs.plist
    chmod go-rwx /Users/$currUser/Library/Preferences/pbs.plist
fi

## Now we check to make sure everything is in place
if [ -e /Users/$currUser/Library/Services/LaunchScreenSaver.workflow ]; then
    echo "The Service was installed"
    serviceFile="Yes"
fi

if [ -e /Users/$currUser/Library/Preferences/pbs.plist ]; then
    echo "The shortcut file exists"
    shortcutFile="Yes"
fi

sleep 2
killall Finder

/bin/launchctl unload /System/Library/LaunchAgents/com.apple.pbs.plist
/bin/launchctl load /System/Library/LaunchAgents/com.apple.pbs.plist

## Final clean up stage
rm -rf /private/tmp/ScreenSaver/