I am trying to access the Privacy -> Accessibility tab using Applescript. Can anyone help me?
I need to display a list of all the programs in the section:
Accessibility
Camera
Microphone
Photos
etc...
The request itself and the output in the terminal using osascript -e.
It is necessary to exclude interaction with the GUI. Here's what I managed to find
osascript -e 'tell application "System Events" to get the name of every login item'
I need to find the same solution for Accessibility? And get the result the same as in the screenshot below.
The main goals are
Locally get the information contained in Security & Privacy
2)Connect to mac OS via SSH and get the information contained in Security & Privacy. If this is not possible, then how to display the information using a single Apple script.
It is necessary to exclude interaction with the GUI (on the remote system).
Testing with the remote system being macOS Big Sur 11.6 and having checked [√] Allow full disk access for remote users in System Preferences > Sharing > Remote Login on the remote system, then the example shell script code executed in Terminal on the local system in a ssh session to the remote system will give you a raw dump of what's listed under Accessibility in System Preferences > Security & Privacy > Privacy without the need for UI Scripting with AppleScript.
sqlite3 '/Library/Application Support/com.apple.TCC/TCC.db' 'SELECT client FROM access WHERE service="kTCCServiceAccessibility";'
On the test system its output was:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/Support/AEServer
com.apple.AccessibilityInspector
com.apple.Automator
com.apple.ScriptEditor2
com.apple.Terminal
com.latenightsw.ScriptDebugger8
If you really have a need to use AppleScript you could, however, say you needed the output to be pretty. In other words, using an AppleScript script saved as a shell script using a #!/usr/bin/osascript shebang the output on the same remote system would be e.g.:
AEServer, Accessibility Inspector, Automator, Script Editor, Terminal, Script Debugger
Example AppleScript code:
#!/usr/bin/osascript
set theAccessibilityList to paragraphs of (do shell script "sqlite3 '/Library/Application Support/com.apple.TCC/TCC.db' 'SELECT client FROM access WHERE service=\"kTCCServiceAccessibility\";'")
set theAccessibilityApplicationNamesList to {}
repeat with thisItem in theAccessibilityList
if thisItem starts with "/" then
set shellCommand to (do shell script "f=" & quoted form of thisItem & "; echo ${f##*/}")
set end of theAccessibilityApplicationNamesList to shellCommand
else
try
set end of theAccessibilityApplicationNamesList to the name of application id thisItem
end try
end if
end repeat
return theAccessibilityApplicationNamesList
Notes:
I created, saved and made executable the example AppleScript code, shown above, on the local system and then copied it the from the local system to the remote system using scp.
Note: The example AppleScript code is just that and sans any included error handling does not contain any additional error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors. Additionally, the use of the delay command may be necessary between events where appropriate, e.g. delay 0.5, with the value of the delay set appropriately.
You should escape the nested quotes following way. And, activate the System Preferences.
osascript -e "
tell application id \"com.apple.systempreferences\"
activate
reveal anchor named \"Privacy_Accessibility\" in pane id \"com.apple.preference.security\"
end tell
tell application id \"sevs\" to tell process \"System Preferences\"
repeat until window \"Security & Privacy\" exists
delay 0.02
end repeat
tell scroll area 1 of group 1 of tab group 1 of window \"Security & Privacy\"
get value of static text 1 of UI element 1 of rows of table 1
end tell
end tell"
Or, if needed table view (on right) of needed item (on left) is already opened, you can use following osascript on the Catalina:
osascript -e "
tell application id \"sevs\" to tell process \"System Preferences\"
set frontmost to true
tell scroll area 1 of group 1 of tab group 1 of window \"Security & Privacy\" to get value of static text 1 of UI element 1 of rows of table 1
end tell"
Related
I used to use two AppleScript scripts to find out the file name of the actual wallpaper image from desktop 1 and desktop 2 (dual monitor mode) under macOS Mojave. One script for the main monitor and another one for the second monitor. Under macOS Catalina the scripts are not working anymore.
Here is the script:
tell application "System Events"
set posix_path to (pictures folder of desktop 2)
set picPath to (POSIX file posix_path) as string
end tell
set thePictures to (do shell script "sqlite3 ~/Library/Application\\ Support/Dock/desktoppicture.db \"SELECT data.value FROM preferences INNER JOIN data on preferences.key=16 and preferences.picture_id=7 and preferences.data_id=data.ROWID\"")
set fullPath to picPath as string
set rotationImage to fullPath & thePictures
tell application "Finder"
try
set aliasItem to item rotationImage
if class of aliasItem is alias file then
reveal original item of aliasItem
end if
end try
end tell
Here is the error message:
tell application "System Events"
get pictures folder of desktop 1
--> "/Users/peter/Library/Caches/com.apple.preference.desktopscreeneffect.desktop/69948584/DSKPhotosRootSource"
get POSIX file "/Users/peter/Library/Caches/com.apple.preference.desktopscreeneffect.desktop/69948584/DSKPhotosRootSource"
--> error number -1728 from POSIX file "/Users/peter/Library/Caches/com.apple.preference.desktopscreeneffect.desktop/69948584/DSKPhotosRootSource"
end tell
tell current application
do shell script "sqlite3 ~/Library/Application\\ Support/Dock/desktoppicture.db \"SELECT data.value FROM preferences INNER JOIN data on preferences.key=16 and preferences.picture_id=1 and preferences.data_id=data.ROWID\""
--> "13725B"
end tell
tell application "Finder"
get item "Macintosh HD:Users:peter:Library:Caches:com.apple.preference.desktopscreeneffect.desktop:69948584:DSKPhotosRootSource13725B"
--> error number -1728 from item "Macintosh HD:Users:peter:Library:Caches:com.apple.preference.desktopscreeneffect.desktop:69948584:DSKPhotosRootSource13725B"
end tell
Tried to find the problem but couldn't find a solution. I am not an experienced AppleScript writer. Hope somebody can help.
On Catalina and Mojave, I'm able to get the current wallpaper by using a sqlite command similar to yours:
sqlite3 ~/Library/Application\ Support/Dock/desktoppicture.db "select * from data" | tail -2
Or in Applescript:
do shell script "sqlite3 ~/Library/Application\\ Support/Dock/desktoppicture.db 'select * from data' | tail -2"
On my Mac, the last 2 items in the data table appear to be some combination of the most recently set wallpaper and last 2 displays that were most recently set, so I tail the list. Like you, I'm also using a large folder of wallpapers and I have it set to change every 30 minutes. As long as I don't manually change a wallpaper, the last 2 items are consistently the names of the 2 active wallpapers because both monitors change at the same time every 30 minutes.
Something to note: When you are using a Folder with the "Change picture:" checkbox checked, the items returned from select * data is just the file name (i.e., wallpaper.jpg). If you've set the wallpaper to a single image, the item returned from the select command is the full path of the image (i.e., /path/to/folder/wallpaper.jpg). Since I'm using a folder, so I get just the image names in my select results. Then I can split the 2 names by newline to get each wallpaper name in an array and then open them. Here's my whole script:
#!/bin/bash
#reads and opens the last 2 items from the 'data' table in the desktoppicture.db sqlite db
last_two=`sqlite3 ~/Library/Application\ Support/Dock/desktoppicture.db "select * from data" | tail -2`
IFS=$'\n' read -rd '' -a y <<<"$last_two"
#echo "first is ${y[0]}"
#echo "second is ${y[1]}"
open /Users/myusername/Pictures/Desktop\ Pictures/${y[0]}
open /Users/myusername/Pictures/Desktop\ Pictures/${y[1]}
I realize you asked an AppleScript question and this is largely a bash script answer, but the do shell script item at the top of my answer should get you going enough to be able to capture and manipulate the image names inside of AppleScript.
Just to close this out, I use this bash script in Alfred using a keyword "retire" to retire a wallpaper I'm tired of. I type the keyword, this script runs to open the images in Preview, another script runs to open my Desktop Pictures folder and a Desktop Pictures Retired folder and then I manually move the photo into the Retired folder.
If you currently have two monitors connected and you're simply looking to retrieve the names of the Desktop Wall Papers for each, this following Apple script code should be what you're looking for.
tell application "System Events"
set everyDesktop to desktops
set desktopOnePicture to picture of item 1 of everyDesktop
set desktopTwoPicture to picture of item 2 of everyDesktop
end tell
I can't guarantee the code below will fair any better than the solution already posted, but it should, in theory, target desktop images per screen (monitor) rather than by desktop (space). However, I don't have Mojave or Catalina, or a computer to test this out:
use framework "AppKit"
property NSScreen : a reference to NSScreen in the current application
property NSWorkspace : a reference to NSWorkspace in the current application
property currentScreen : a reference to the mainScreen of NSScreen
on screen(i as integer)
local i
if i = 0 then return the currentScreen()
return NSScreen's screens()'s item i
end screen
on desktopImageURLForScreen:(i as integer)
local i
set S to screen(i)
tell NSWorkspace's sharedWorkspace() to return the ¬
desktopImageURLForScreen_(S) as «class furl»
end desktopImageURLForScreen:
return the POSIX path of my desktopImageURLForScreen:0
The bottom line is the one you will most likely want to experiment with, by changing the index number passed to the handler. If you have three monitors, then they would each be identified by one of the indices 1, 2, or 3 (I can't predict how index corresponds to arrangement of monitors). Index 0 will always refer to the screen that currently has keyboard focus.
My applescript gave correct output when ran inside automator as service with no input but it gives error message when ran outside automator (safari, preview etc.)
It also gives correct output when ran through applescript editor, no problem running it with safari, preview or any other application.
The reason I was so keen to get it done with automator was that I don't want to install a 3rd party app just for assigning one shortcut to one script.
I debugged this portion which after removing from code allowed automator to run the script. Ran it with try, error in automator & viola, no issues at all.
But I want to know why this code earlier & without try-error function was giving the error messages when ran outside automator application.
Here's the portion of the script with try-error function:
try
set writ to do shell script "/usr/bin/python Users/[username]/Documents/tech_toolkit/windtitle"
tell application writ
if the (count of windows) is not 0 then
set window_title to name of front window
end if
end tell
on error
delay 2
end try
For shell script /windtitle , windtitle is an executable file
#!/usr/bin/env python
from AppKit import NSWorkspace
active_app_name = NSWorkspace.sharedWorkspace().frontmostApplication().localizedName()
print active_app_name
The error is:
Your python script return the "Automator Runner" application when it run as service , it's
the frontmost in the background but not in the foreground.
To get the frontmost application, use this script:
try
tell application (path to frontmost application as text)
set window_title to name of front window
set writ to its name -- get the name of this application
end tell
on error
return -- quit this script, because this application is not scriptable, or no window
end try
In previous versions of OS X, to allow AppleScript to be run you needed to check “Enable access for assistive devices” in the Accessibility pane of System Preferences.
With Mavericks, this is now a per-app setting that is enabled from Security & Privacy -> Accessibility. How do I enable assistive access if the script is being run from the command line with osascript from within a Jenkins task? As far as I understand, there is no GUI task to authorize then; I get no message dialog asking for permissions. The error message I get in the Jenkins output is:
take_screenshot_iossim.sh:246:303: execution error: System Events got an error: osascript is not allowed assistive access. (-1719)
I also tried adding all applications to the permissions dialog and still receive the permissions denied error.
Problem
If I understand correctly, you want to enable GUI scripting from a command line.
Solution
I believe you will need to use the following code to enable GUI Scripting from within an applescript. That script can then be executed from the command line. You may want to exclude the display dialog as needed -- this script just presents the dialog to confirm that the GUI settings have been made active.
if enabledGUISCripting(true) then
-- GUI Scripting statements go here
display dialog "GUI Scripting is enabled"
else
--non-GUI scripting statements go here
display dialog "GUI Scripting is disabled"
end if
on enabledGUISCripting(switch)
tell application "System Events"
activate
if not (UI elements enabled) then set (UI elements enabled) to true
return (UI elements enabled)
end tell
end enabledGUISCripting
The key parts of this are:
tell application "System Events"
activate
if not (UI elements enabled) then set (UI elements enabled) to true
end tell
You could combine the key parts mentioned above into a file and tell osascript to execute it using:
osascript file.scpt
If you want to send osascript multiple commands on a single line instead of using a script file you could try (note multiple -e flags per command):
osascript -e “line 1″ -e “line 2″ -e “line 3″
You may want to run this using sudo (if needed):
If you get an error such as this one when running such scripts from Terminal you will need to enable accessibility for Terminal in the privacy preferences (Mavericks, see image below)
execution error: System Events got an error: Can’t set UI elements enabled of application to true. (-10006)
System Preferences > Security & Privacy > Accessibility (Click to enable Terminal)
I worked round this by starting the jenkins slave by using JNLP rather than SSH. You can set this up in the slave node settings on the jenkins master.
To set this up i created an automator script which runs at login so the jenkins slave runs as a real user.
curl -o slave.jar http://server:8080/jnlpJars/slave.jar && java -jar slave.jar -jnlpUrl http://server:8080/computer/<slaveName>/slave-agent.jnlp -secret <secret from the node settings on master>
This causes osx to popup an enable application access to assistive devices popup for the automator script which then allows it to access everything.
For me this is not a complete solution as i have problems with JNLP slaves going offline more than the SSH launched slaves, which is how i found this issue :D
Another solution is to run the command by spawning a terminal which i guess is not in apple's banned list of things for assitive access.
After a bit of messing around i found the following worked over ssh
osascript -e 'tell application "Terminal" to do script "take_screenshot_iossim.sh"'
This then pops up the assitive dialog again and you can approve access
You need to setup the terminal to auto close after success otherwise you'll end up with millions of them :D
I am using Applescript to automate some tasks in the OSX Finder. The script opens up a folder and selects the first image in that folder. I would like it to also bring up the "quick look" window (exactly as if the user had pressed the space bar).
I did find a way to fire up quick look from the command line using qlmanage, but that brings up a static quick look window, which is no longer tied to the finder selection.
Code so far:
property folderPath : "/Volumes/Media/Images"
on run {}
tell application "Finder"
activate
set imageFolder to folder (folderPath as POSIX file)
set imageFile to first item of imageFolder
select imageFile
-- show quick look?
end tell
end run
If you don't want to do it by scripting the Finder you can run the following shell command
qlmanage -p thefile
In an Applescript you might do this like
do shell script "qlmanage -p " & "thepath/thefile"
Depending upon what you are doing this might be much easier. Especially if you primarily just have a set of paths.
If you have an existing Applescript path you can send it like this
set p to POSIX path of mypath
do shell script "qlmanage -pr " & quoted form of p
Updated (with thanks to Kevin Ballard):
tell application "System Events" to keystroke "y" using command down
Note: this requires that "enable access for assistive devices" is selected in the "Universal Access" control panel.
I would like to write an AppleScript that would allow me to launch iTunes with a given Library instead of having to hold down the Option key and browsing for one. I'm already aware of Doug's Library manager, which is not quite what I want. The AppleScript would be for a specific library.
iTunes doesn't allow you to do this with AppleScript, but you can write directly into iTunes' preferences, where it stores a bookmark (alias) to the currently selected library (or nothing, if you're using a library in the default location).
First, you'll need to obtain the alias data for your selected library location. Open iTunes holding down the Option key, select your library and quit iTunes. Then, in Terminal, run:
defaults read com.apple.itunes 'book:1:iTunes Library Location' | pbcopy
This will copy the library alias data to the clipboard.
Finally, here's the script:
property otherLibraryLocation : "" -- paste location between the quotes
property libraryLocationPref : "com.apple.iTunes 'book:1:iTunes Library Location'"
-- first, quit iTunes if it's running
tell application "System Events"
if exists (application process "iTunes") then
tell application "iTunes" to quit
end if
end tell
-- then, set the location
do shell script "defaults write " & libraryLocationPref & " " & quoted form of otherLibraryLocation
-- uncomment the following line to use the default iTunes library instead
-- do shell script "defaults delete " & libraryLocationPref
-- finally, relaunch iTunes
tell application "iTunes" to activate
Paste the library location between the quotes in the first line of the script, and you should be all set. To return to the original library, uncomment the line including defaults delete.
You can create a symlink from ~/Music/iTunes to your chosen directory path in a unix shell script (man ln). And an AppleScript can call a unix shell script by sending the appropriate message to the Terminal app.