How to set UI Elements Enabled to true in Applescript? - applescript

tell application "System Events"
if UI elements enabled is true then
tell application "System Preferences"
activate
set current pane to pane id "com.apple.preference.universalaccess"
display dialog "This script requires access for assistive evices be enabled." & return & return & "To continue, click the OK button and enter an administrative password in the forthcoming security dialog." with icon 1
end tell
set UI elements enabled to true
if UI elements enabled is false then return "user cancelled"
delay 1
end if
end tell
When I run this, I get an error. "Can’t set UI elements enabled of application to true"
Any ideas why this may be happening?
Extra info: OS X Yosemite

UI elements enabled is a read-only property since OS X Mavericks. Try this:
tell application "System Events"
if not UI elements enabled then
display dialog "This script requires access for assistive devices be enabled." & return & return & "To continue, click the OK button and enter an administrative password in the forthcoming security dialog." with icon 2
if button returned of result is equal to "OK" then
do shell script "sudo sqlite3 'Library/Application Support/com.apple.TCC/TCC.db' 'insert or replace into access values (\"kTCCServiceAccessibility\",\"com.apple.ScriptEditor2\",0,1,0,null);'" with administrator privileges
end if
end if
end tell

I just answered this basic question for someone recently. See my answer here.

Related

Using AppleScript to modify settings/system preferences

I am trying to make an AppleScript that toggles automatic rearranging of spaces. I am able to get the AppleScript to open system preferences and go into mission control settings, however i am not sure how to check the box which i want to change.
tell application "System Preferences"
activate
end tell
tell application "System Events"
tell process "System Preferences"
click menu item "Mission Control" of menu "View" of menu bar 1
delay 2
tell window "Mission Control"
//additional code goes here
end tell
end tell
end tell
Is there a way to see what the components of the window are so i know if i need to go into a table, or something else, before i am able to access the check boxes that toggle the settings
This is an alternative method using a shell command via AppleScript, which has the benefit of not requiring System Preferences to be open/running/visible. It's also much faster.
If you do happen to have it open in order to monitor whether the script below works, bear in mind that the GUI (what you see) is not updated until you close System Preferences, and open it up again.
To set Automatically rearrange Spaces based on most recent use to true (i.e. so the checkbox is ticked):
do shell script "defaults write com.apple.dock 'mru-spaces' -bool true; killall Dock"
To set it to false, i.e. untick the checkbox, change true to false in the line of code above.
To toggle the setting, this short script will achieve that:
set currentSetting to ¬
(do shell script ¬
"defaults read com.apple.dock 'mru-spaces'") ¬
as integer as boolean
do shell script ¬
"defaults write com.apple.dock 'mru-spaces' -bool " & ¬
(not currentSetting) & ¬
"; killall Dock"
Note: Tested with MacOS High Sierra, but should work (I believe) in OS X Mavericks and later.
Other Settings
When switching to an application, switch to a Space with open windows for the application
do shell script "defaults write -g AppleSpacesSwitchOnActivate -bool true"
(or false if you want the option off.)
Group windows by application
do shell script "defaults write com.apple.dock 'expose-group-apps' -bool true; killall Dock"
(or false if you want the option off.)
Let me start by saying while both of the other answers prior to this one do work, nonetheless I wouldn't use either one of them for the following reasons.
The answer presented by shadowsheep works however it needlessly exposes the System Preferences GUI and I believe unless your system is really slow the value of the delay command is excessive by 50% and only one should be necessary in this use case.
The answer presented by CJK works however it uses killall Dock which is visually distracting and causes all minimized windows on all Desktops to be unminimized leading to further visual distractions, and clutters the Desktop(s), which can then require the User to cleanup the mess. Even without other windows open it's still more so a visual distraction then what I'll present.
Now every User has different work habits so maybe none of the reasons mentioned are of any consequence to you. Personally, I work between four virtual Desktops and can have dozens of windows opened in numerous apps across the Desktops with many, if not most minimized at times. Using killall Dock for me is the last thing I want to do most of the time.
With that said, here's an alternative to both of the existing answers prior to this one.
It's probably safe to say that most Users don't open and leave open System Preferences however the following example AppleScript code checks to see if it's running and if so closes it. This is so it can be opened without showing the GUI, so as not to have to see the the visual distraction of have the GUI change as the script progresses.
This example AppleScript code simply toggles the state of the target checkbox:
if running of application "System Preferences" then
quit application "System Preferences"
delay 1
end if
tell application "System Preferences"
reveal pane id "com.apple.preference.expose"
delay 1
tell application "System Events"
tell group 2 of window 1 of application process "System Preferences"
click checkbox "Automatically rearrange Spaces based on most recent use"
end tell
end tell
quit
end tell
This example AppleScript code conditionally clicks the target checkbox using 0 or 1 in if value is equal to 0 then click it. Use 0 to only click it if it's not checked and 1 to only click it if it's checked.
if running of application "System Preferences" then
quit application "System Preferences"
delay 1
end if
tell application "System Preferences"
reveal pane id "com.apple.preference.expose"
delay 1
tell application "System Events"
tell group 2 of window 1 of application process "System Preferences"
tell checkbox "Automatically rearrange Spaces based on most recent use"
if value is equal to 0 then click it
end tell
end tell
end tell
quit
end tell
Both example AppleScript code blocks shown work fast and without seeing the System Preferences GUI and the only visual effect is the Dock Tile for System Preferences does a single bounce and may not even be noticeable, especially when compared to the visual distraction of killall Dock.
Note that the value of the delay commands may need to be adjusted for your system, and or additional delay commands may or may not be needed. Adjust values of and or add/remove the delay commands as appropriate.
Note: The example AppleScript code is just that and does not employ any other error handling then what's shown and is meant only to show one of many ways accomplish a task. The onus is always upon the User to add/use appropriate error handling as needed/wanted.
This should to what you want.
In this example Automatically rearrange Spaces based on most recent use is the checkbox you want to check.
tell application "System Preferences"
activate
delay 2
set the current pane to pane id "com.apple.preference.expose"
delay 2
tell application "System Events"
click checkbox "Automatically rearrange Spaces based on most recent use" of group 2 of window "Mission Control" of application process "System Preferences"
end tell
quit
end tell
And this if you wanna check it only if it's not checked:
tell application "System Preferences"
activate
delay 2
set the current pane to pane id "com.apple.preference.expose"
delay 2
tell application "System Events"
tell checkbox "Automatically rearrange Spaces based on most recent use" of group 2 of window "Mission Control" of application process "System Preferences"
if (get its value) = 0 then click it
end tell
end tell
quit
end tell
And if you wanna list all the UIElements in the window:
set myArray to {}
tell application "System Preferences"
activate
delay 2
set the current pane to pane id "com.apple.preference.expose"
delay 2
tell application "System Events"
tell window "Mission Control" of application process "System Preferences"
repeat with uiElem in entire contents as list
set myArray to myArray & ((class of uiElem as string) & " : " & name of uiElem as string)
end repeat
end tell
end tell
end tell

How to get IKEv2 VPN connection by AppleScript?

Does anyone experience AppleScript in working with IKEv2 network service?
In El Capitan, I can create an IKEv2 VPN connection and connect correctly. However AppleScript doesn't work with that kind of connection/service, it cannot get the service with name, it cannot list the connection from the service.
tell application "System Events"
tell current location of network preferences
set service_name to "IKEv2_connection_name"
do shell script (do shell script "scutil --nc start \"" & service_name & "\"")
end tell
end tell
And here is the error:
error "System Events got an error: No service" number 1
It appears that AppleScript cannot recognize the IKEv2 VPN connection. So I tried to run another script which to print out all the current internet connections in the system:
tell application "System Events"
tell current location of network preferences
set names to get name of every service
end tell
end tell
The result shows all the network connections (including "Wi-Fi", "USB Ethernet", "Bluetooth PAN", "Thunderbolt Bridge", all VPN connections of type L2TP, PTPP, IPSec) but it doesn't list any IKEv2 connections although I have set a few of them and they're all working.
I was able to get this to work using UI scripting. So far this script seems to work well, and I think I've made it about as user friendly as possible. It requires System Preferences to be opened at all times, but the window can be hidden. If System Preferences is closed when the script starts, the script will launch and then auto-hide System Preferences. Major inconvenience is that System Preferences is essentially locked to the Network pane while the script is running. Feel free to give it a try, let me know if you have any problems or suggestions! You'll need to replace "MY VPN SERVICE NAME" with the name of the VPN service you want to keep connected. You may also want to modify the delay at the bottom.
repeat while true
tell application "System Events"
tell application process "System Preferences"
if not (window 1 exists) then
tell application "System Preferences"
activate
end tell
repeat while not (menu bar 1 exists)
end repeat
repeat while not (menu "System Preferences" of menu bar 1 exists)
end repeat
repeat while not (menu item "Hide System Preferences" of menu "System Preferences" of menu bar 1 exists)
end repeat
delay 3
click menu item "Hide System Preferences" of menu "System Preferences" of menu bar 1
end if
click menu item "Network" of menu "View" of menu bar 1
tell window 1
repeat while not (rows of table 1 of scroll area 1 exists)
end repeat
repeat with current_row in (rows of table 1 of scroll area 1)
if value of static text 1 of current_row contains "MY VPN SERVICE NAME" then
select current_row
exit repeat
end if
end repeat
repeat with current_button in (buttons in group 1)
if name of current_button is equal to "Connect" then
click current_button
exit repeat
end if
end repeat
end tell
end tell
end tell
delay 60
end repeat
This is not a direct answer to your question, but another way to accomplish the same;
This guy created an app (source available also) to do what scutil and AppleScript cannot : https://blog.timac.org/2018/0719-vpnstatus/
There are a few reports of this and it seems to be some changes in AppleScript made in OSX 10.10 which stopped services in connection object to list IKEv2 VPNs.
You are on the right path though, just don't use location:
tell application "System Events"
set service_name to "IKEv2_connection_name"
do shell script "scutil --nc start \"" & service_name & "\""
end tell
Based on this answer, where you can see more options for scutil as well:
In Mac OS X 10.11, Opening a VPN connection window with the command line gives me an error

OS X Programmatically Click Menu Item of Dock Menu

This is my dock menu:
I would like to programmatically click that button "Show Most Recent Window". Can this programmatically be done using Cocoa or CoreFoundation?
I know the PID the dock item is associated with.
There are many ways to achieve this, although generally you can easily set an AppleScript or oascript that can handle this. Basically it involves using AXRaise, which essentially calls on the function to raise the frontmost window of the application specified.
Code:
set mostrecentWindow to "mostrecentWindow"
set theApplication to "Safari"
tell application "System Events"
if exists process theApplication then
--raise frontmost window
tell process theApplication
set frontmost to true
perform action "AXRaise" of (windows whose title is mostrecentWindow)
end tell
else if not (exists process theApplication) then
--display alert
display alert "Warning: process " & theApplication & " is not running"
end if
end tell
The above example checks whether or not the process Safari is running, and if it is then raise it's most recent (or frontmost) window to the foreground; otherwise show a warning that the process is not running.
It sounds like a task that can be done using GUI Scripting using AppleScript.

AppleScript to set up VPN on Mac 10.8 is loosing focus and types text in wrong window, what is wrong?

I wanted to share a very useful AppleScript with other Mac admins but it is losing focus. When it's run in AppleScript editor it runs to a certain stage and then instead of copying text to required windows it replaces text in AppleScript editor. Can anyone suggest why?
set vpnname to "VPN (Primary)"
set vpnserver to "vpn.website.com"
set vpnsecret to "abcdefghij"
set vpnusername to system attribute "USER"
set groupname to "GROUP"
activate application "System Preferences"
tell application "System Events"
-- Checks whether Universal Access is enabled - this is required for all scripts to work
if not (UI elements enabled) then
tell application "System Preferences"
activate
set current pane to pane id "com.apple.preference.universalaccess"
display dialog "This script requires access for assistive devices be enabled." & return & return & "To continue, click the OK button and enter an administrative password in the security dialog." with icon note
end tell
set UI elements enabled to true
if UI elements enabled is false then return "User Cancelled"
delay 1
end if
tell process "System Preferences"
click button "Network" of scroll area 1 of window "System Preferences"
--Creating VPN (CU Primary) interface
tell window "Network"
click button "Add Service"
delay 1
end tell
tell sheet 1 of window "Network"
click pop up button 1
click menu item "VPN" of menu 1 of pop up button 1
delay 1
click pop up button 2
click menu item "Cisco IPSec" of menu 1 of pop up button 2
set focused of text field 1 to true
keystroke "a" using command down
keystroke vpnname
click button "Create"
delay 1
end tell
--Entering server / account details
tell group 1 of window "Network"
click checkbox "Show VPN status in menu bar"
set focused of text field 3 to true
keystroke vpnserver
set focused of text field 1 to true
keystroke vpnusername
click button 2 --pressing "Advanced…" button
delay 1
end tell
--Entering "Advanced…" details
tell sheet 1 of window "Network"
activate
set focused of text field 2 to true
keystroke vpnsecret
set focused of text field 1 to true
keystroke groupname
click button "OK"
delay 1
end tell
-- Apply all changes
tell window "Network"
click button "Apply"
delay 1
end tell
tell application "System Preferences"
quit saving yes
end tell
end tell
end tell
I'm not sure if it will work but if any of the key strokes are going into applescript just run the
tell application "application name here"
activate
end tell
before the keystrokes that are being put into apple script then it will focus on the window you have told it to
Sorry for the lack of code snippet I am new to this forum and I'm not sure how to use it properly

Enable/Disable Fn keys from the command line on the Mac

I hardly ever use the function keys on my macbook pro. I mostly just use them for volume, brightness, etc. Now that I've started playing Starcraft 2 a bunch, I want to use them without having to press the fn key down.
I want to write a little shell script that will flip the "Use all F1, F2, etc keys as standard function keys" check box. I was thinking I could use the defaults command to change it but I wasn't sure what values to use. This way I don't have to change the the preferences every time I want to play. I can just run the script that'll switch the keys and even launch the game.
Any ideas?
An AppleScript that should do the trick -- taken from http://scriptbuilders.net/files/fn1.1.html, with slight modifications
--Check if GUI Scripting is Enabled
tell application "System Events"
if not UI elements enabled then
set UI elements enabled to true
end if
end tell
--Enable/Disable "Use all F1, F2, etc. keys as standard function keys" option in Keyboard & Mouse Preference pane and close System Preferences
tell application "System Events"
tell application "System Preferences"
reveal anchor "keyboardTab" of pane "com.apple.preference.keyboard"
end tell
click checkbox 1 of tab group 1 of window 1 of application process "System Preferences"
end tell
if application "System Preferences" is running then
tell application "System Preferences" to quit
end if
Tested on MacOS 10.6.4
The command is defaults write -g com.apple.keyboard.fnState, although I've had problems in the past changing it. I ended up just using an AppleScript. Give it a try.
defaults write -g com.apple.keyboard.fnState -boolean true
EditTo elaborate, the problems I've had is that the actual value is changed, but it doesn't actively change the setting in System Preferences nor does the fnState toggle, because the file is only read at boot/login etc. Also, making changes to a config file that's opened by another task sounds like a good way to corrupt the file.
You can install the awsome Karabiner-Elements.
Under System Preferences-> Keyboard preferences, make sure "Use all F1, F2, etc. keys as standard function keys" is checked as a perquisites.
Open KeyRemap4MacBook preferences.
Navigate to "Pass Through Mode" option.
Check the 'Change Fn+Escape to toggle "Pass Through Mode"'
Open "Change F1..F19 Key" and check the "Macbook Pro" or "Macbook Air" option choosing your correct mac type.
For anyone else trying to make this work - I've finally gotten my solution to work. Tested with: MacOS Big Sur, 11.4, June 2021.
The code is based here:
https://github.com/MrSimonC/Toggle-Mac-Function-Keys
but for brevity, here is the contents of the apple script file:
-- Apple Script (i.e. Use in Apple's Script Editor Application) to Toggle Function Keys / Media keys on/off
-- Tested on MacOS Big Sur (11.4) June 2021
-- Project Path: https://github.com/MrSimonC/Toggle-Mac-Function-Keys
tell application "System Preferences"
set current pane to pane "com.apple.preference.keyboard"
end tell
tell application "System Events"
if UI elements enabled then
tell application process "System Preferences"
repeat until exists tab group 1 of window "Keyboard"
delay 0.5
end repeat
click radio button "Keyboard" of tab group 1 of window "Keyboard"
click checkbox "Use F1, F2, etc. keys as standard function keys" of tab group 1 of window "Keyboard"
end tell
tell application "System Preferences" to quit
else
-- GUI scripting not enabled. Display an alert
tell application "System Preferences"
activate
set current pane to pane "com.apple.preference.security"
display dialog "UI element scripting is not enabled. Please activate this app under Privacy -> Accessibility so it can access the settings it needs."
end tell
end if
end tell
Hope someone finds it useful!

Resources