I have written an AppleScript and want to convert it to an osascript so I can run it on launch using launchd. Is there any way I can convert this to osascript or do I have to rewrite the whole script as an osascript? If it can't be done is there at least a way to run it as osascript in the terminal? Thank you!
on idle
tell application "System Events" to ¬
if exists process "Launchpad" then run script
tell application "Launchpad"
delay 0
tell application "System Events" to keystroke "b" using {control down, option down, command down}
delay 0
tell application "System Events" to keystroke "b" using {control down, option down, command down}
delay 0
tell application "System Events" to keystroke "b" using {control down, option down, command down}
delay 0
end tell
end idle
If you only need to run it once per second or less frequently, you could save it as a normal script:
tell application "System Events"
if not (exists process "Launchpad") then return
repeat 3 times
keystroke "b" using {control down, option down, command down}
end repeat
end tell
And repeat running the script with launchd:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
http://www.apple.com/DTDs/PropertyList-1.0.dtd>
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.stackoverflow.11945633</string>
<key>ProgramArguments</key>
<array>
<string>osascript</string>
<string>/Users/username/Library/Scripts/script.scpt</string>
</array>
<key>StartInterval</key>
<integer>1</integer>
</dict>
</plist>
The property list has to be loaded manually with launchctl load ~/Library/LaunchAgents/com.stackoverflow.11945633.plist. Applying changes requires unloading and loading it.
Programs are sent a SIGKILL signal after 20 seconds by default. You can override the timeout by adding an ExitTimeOut key. See man launchd.plist.
The script doesn't actually work for changing the Launchpad background. Launchpad.app is just a dummy application that quits immediately when it's opened.
If you just want to change the background style, you can do it with defaults write com.apple.dock springboard-background-filter -int 2; killall Dock.
Related
So I am writing a script that would set up my working environment by opening and then getting several apps in fullscreen via a single command line. I am having trouble with the "getting the apps in fullscreen" part, and the script execution is very confusing to me.
My hardware is a MacBook Pro (15-inch, 2017) running on macOS Catalina 10.15.7.
Here is the part of the script that behaves erraticaly when executed:
script1.scpt:
tell application "Sublime Text"
activate
tell application "System Events"
tell front window of (first process whose frontmost is true)
set value of attribute "AXFullScreen" to true
end tell
key code 123 using {control down}
end tell
end tell
When executed while the app (here, Sublime Text) is not in fullscreen via the command osascript script1.scpt, the app is activated and goes fullscreen, but key code 123 using {control down} does not work, without producing any error message or sound.
When executed while the app is already in fullscreen via the command osascript script1.scpt, the app is activated, stays in fullscreen as intended but I get this error message:
execution error: System Events got an error: Can't get window 1 of process 1 whose frontmost = true. Invalid index. (-1719)
Also, key code 123 using {control down} does not work either.
When executed via a shell script calling script1.scpt while the app is not in fullscreen, the app behaves exactly as in case 1.
When executed via a shell script calling script1.scpt while the app is already in fullscreen, the app behaves exactly as it should and everything seems fine. But if I lengthen the script to get 2 apps in fullscreen in a row as in script2.scpt (see below), the 2nd app does stricly nothing, and I get the error message of case 2 again.
script2.scpt:
tell application "Sublime Text"
activate
tell application "System Events"
tell front window of (first process whose frontmost is true)
set value of attribute "AXFullScreen" to true
end tell
key code 123 using {control down}
end tell
end tell
tell application "Skim"
activate
tell application "System Events"
tell front window of (first process whose frontmost is true)
set value of attribute "AXFullScreen" to true
end tell
key code 123 using {control down}
end tell
end tell
I have been spending hours trying to understand what is going on without success, so any help or clue would be very welcome.
The only way I found to get things working is to separate the code in separate steps with 0.5sec pauses in-between them, like in the following shell script code block. But I would like to find a faster and "cleaner" solution to my problem.
osascript -e "tell application \"Sublime Text\" to activate" ;
sleep 0.5 ;
osascript -e "tell application \"System Events\"" -e "tell front window of (first process whose frontmost is true)" -e "set value of attribute \"AXFullScreen\" to true" -e "end tell" -e "end tell" ;
sleep 0.5 ;
osascript -e "tell application \"Skim\" to activate" ;
sleep 0.5 ;
osascript -e "tell application \"System Events\"" -e "tell front window of (first process whose frontmost is true)" -e "set value of attribute \"AXFullScreen\" to true" -e "end tell" -e "end tell" ;
sleep 0.5 ;
osascript -e "tell application \"Finder\" to activate" ;
sleep 0.5 ;
osascript -e "tell application \"System Events\"" -e "tell front window of (first process whose frontmost is true)" -e "set value of attribute \"AXFullScreen\" to true" -e "end tell" -e "end tell" ;
sleep 0.5 ;
osascript -e "tell application \"Terminal\" to activate" ;
sleep 0.5 ;
osascript -e "tell application \"System Events\"" -e "tell front window of (first process whose frontmost is true)" -e "set value of attribute \"AXFullScreen\" to true" -e "end tell" -e "end tell"'
EDIT: For the moment being, I managed to get my script doing what I wanted it to do pretty reliably. Not completely satisfied though, because I still have to rely on fixed delays and this makes the execution a bit slow. This is what the code looks like:
in .bash_profile:
cd ~/<path>/ ;
osascript workspace_on.scpt
workspace_on.scpt:
tell app "System Events" to tell process "Terminal" to set the value of attribute "AXFullScreen" of window 1 to true
delay 0.6
tell app "Sublime Text" to activate
delay 0.6
tell app "System Events" to tell process "Sublime Text" to set the value of attribute "AXFullScreen" of window 1 to true
delay 0.6
do shell script "open -a skim ~/<path>/main.pdf"
delay 1
tell app "Skim" to set interaction mode of document 1 to full screen mode
delay 0.6
do shell script "open ~/<path>"
delay 1
tell app "System Events" to tell process "Finder" to set the value of attribute "AXFullScreen" of window "latex-template" to true
Just to copy-and-paste my most recent comment from above:
“Like you, I've spent a bit too much time figuring out this problem. It's quite a frustrating situation because I had a few light bulb moments of inspiration that, in theory, ought to have worked, and worked well, but ultimately didn't work at all. ¯_(ツ)_/¯ But in the process, I've at least written out a naive implementation that incorporates conditional checks and operates on each app one-by-one. It's not what I had aimed for in my head, but it works. See below.”
set Apps to {"TextEdit", "ManOpen", "Usenapp", "QuickTime Player"}
tell application id "com.apple.SystemEvents"
set dock to list 1 in the process named "Dock"
repeat with A in the Apps
tell my application named A to activate
set _P to (a reference to the process named A)
set _W to (a reference to _P's front window)
set _B to (a reference to the value of _W's ¬
attribute "AXFullScreenButton")
set _M to (a reference to (_P's menu bar 1's ¬
menu bar items's menu 1's menu items ¬
whose name = "Enter Full Screen"))
tell (a reference to (the dock's ¬
first UI element whose ¬
name = A)) to if ¬
exists then click
tell _W to repeat 60 times -- 60 x 0.5 = 30 seconds
delay 0.5
if it exists then
click _B
if (the value of attribute ¬
"AXFullScreen") ¬
then exit repeat
end if
end repeat
end repeat
end tell
System information:
AppleScript version: 2.8 system version: 12.6 ("Monterey")
I am trying to automate this process.
step 1: change system date to a specific date.
step 2: open an application.
step 3: change system date back to normal.
Now on Automator, I have three apple scripts placed like this.
on run {input, parameters}
tell application "Terminal"
do script with command "sudo date 082704002018"
activate
end tell
delay 1
tell application "System Events"
keystroke "mypassword" & return
delay 3
end tell
end run
on run {input, parameters}
tell application "Terminal"
do script with command "open -a applicationName"
activate
end tell
end run
on run {input, parameters}
tell application "Terminal"
do script with command "sudo ntpdate -u time.apple.com"
activate
end tell
delay 1
tell application "System Events"
keystroke "mypassword" & return
delay 3
end tell
end run
The problem is that Automator only runs the first code. I'm not sure how to make it run all the codes in order.
Sorry if this is a stupid question. I am completely new to automator and applescript.
Thank you
I'm not quite sure why you chose to use three separate AppleScripts. You can combine them all into one AppleScript as I have done in this following example. I'm not quite sure why you used the “activate” commands. I don't think they are necessary so I removed those lines of the code. Anyway, this following code should work for you…
tell application "Terminal"
do script with command "sudo date 082704002018"
end tell
delay 1
tell application "System Events"
keystroke "mypassword" & return
delay 3
end tell
tell application "Terminal"
do script with command "open -a applicationName"
delay 1
do script with command "sudo ntpdate -u time.apple.com"
end tell
delay 1
tell application "System Events"
keystroke "mypassword" & return
delay 3
end tell
Alternately, launching Terminal app to run shell scripts is not necessary all the time as you can run shell scripts in AppleScript by using the “do shell script” command. This following applescript code is your code using only eight lines of code.
do shell script "sudo date 082704002018"
tell application "System Events" to keystroke "mypassword" & return
delay 3
do shell script "open -a applicationName"
delay 1
do shell script "sudo ntpdate -u time.apple.com"
delay 1
tell application "System Events" to keystroke "mypassword" & return
If my versions of your code throw errors, it may be necessary to adjust the delay commands or re-insert the activate commands
If you are hell-bent on using your version of the code and three separate Applescripts, just remove the on run {input, parameters} and end run lines of code from each AppleScript and that should eliminate your problem
I have created aliases of applescripts to open multiple panes on iTerm. However, ever since the latest update the scripts stopped working. I keep getting this error:
syntax error: Expected end of line but found identifier. (-2741)
Here's the script:
newPaneDown() {
osascript -e "
tell application \"iTerm\"
make new terminal
tell the current terminal
activate current session
tell the last session
tell i term application \"System Events\" to key code 2 using {shift down, command down}
end tell
end tell
end tell"
}
newPaneLeft() {
osascript -e "
tell application \"iTerm\"
make new terminal
tell the current terminal
activate current session
tell the last session
tell i term application \"System Events\" to key code 2 using command down
end tell
end tell
end tell"
}
newPanes4x4() {
/usr/bin/env osascript <<-EOF
tell application "iTerm"
activate
launch session "Panes"
tell i term application "System Events" to keystroke "d" using command down
tell i term application "System Events" to keystroke "D" using command down
tell i term application "System Events" to keystroke "[" using command down
tell i term application "System Events" to keystroke "[" using command down
tell i term application "System Events" to keystroke "D" using command down
end tell
EOF
}
alias p2='newPaneLeft'
alias p3='newPaneDown && newPaneLeft'
alias p4='newPanes4x4'
Applescript is not backwards compatible since iTerm2 Version 3.
The new Applescript syntax is described here.
You should replace:
make new terminal
with
create window with default profile
I'm trying to set up Macs for extreme novice computer users so everything is ready out of the box with the exception of their user account.
The problem with this is there are very hard things to install without access to the user account such as Safari extensions. I have Chrome and Firefox set up - I want to install a couple of basics for them and even clicking the install button when they first load up is going to confuse people, I want it totally hands off.
I'm trying to get Adblocker installed. So far I get it so that the script works perfect when run from terminal but when run as a LaunchAgent it gets the install extension window on Safari requiring user input and stops.
It shouldn't stop as originally I had AppleScript click the menu and then I decided to enable full tab control on keyboard and have cliclick press tab and space (as the user can) which installs too.
As I mentioned, run as a script this works perfectly but for some reason the script stalls when Launchagent runs it on login as soon as the extension install window appears.
Is this a bug, is it an extreme security feature? Do i have to adapt my plist to tell Launchagent not to change the way the script works if windows pop up, do I need more in my script for it to behave differently when run by launchd?
Here is the main part, adapted from bits online.
# HARDCODED VALUE FOR "PATHTOEXTENSION" IS SET HERE
pathToExtension="/ext/safari.safariextz"
# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 4 AND, IF SO, ASSIGN TO "PATHTOEXTENSION"
if [ "$4" != "" ] && [ "$pathToExtension" == "" ];then
pathToExtension=$4
fi
# Error if variable appName is empty
if [ "$pathToExtension" == "" ]; then
echo "Error: No value was specified for the pathToExtension variable..."
exit 1
fi
# Turn on full tab control for keyboard
defaults write NSGlobalDomain AppleKeyboardUIMode -int 3
### Launch Safari if not open
osascript -e 'tell application "Safari"
activate
end tell'
### Prompt the user to install the extension given # $4
osascript -e 'tell application "Safari"
open "'"$pathToExtension"'"
tell application "System Events"
tell process "Safari"
set frontmost to true
end tell
end tell
end tell'
#Run cliclick to press tab and space on the keyboard to install extension
sleep 0.7s
cliclick kp:tab kp:space
### Close Safari
osascript -e 'tell application "System Events"
if ((name of processes) contains "Safari") then
tell application "Safari" to quit
end if
end tell'
### Open Getting Started PDF
osascript -e 'tell application "Preview"
open "/Applications/Tutorials/Quick Start Guide.pdf"
end tell'
### Cleanup - delete launch agent so it doesn't run on next boot
rm ~/Library/LaunchAgents/com.ext.install.plist
### Exit silently, as will error if exists & if times out for whatever reason
exit 0
And the plist to run the script is this...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.ext.install</string>
<key>Nice</key>
<integer>20</integer>
<key>ProcessType</key>
<string>Interactive</string>
<key>ProgramArguments</key>
<array>
<string>/Users/Shared/install-ext.command</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/tmp/com.ext.install.err</string>
<key>StandardOutPath</key>
<string>/tmp/com.rxt.install.out</string>
</dict>
</plist>
No errors reported in the logs by the way. Hopefully someone can offer some insight.
Saving this:
install-ext.command
# HARDCODED VALUE FOR "PATHTOEXTENSION" IS SET HERE
pathToExtension="/Users/Shared/ext/wpa.safariextz"
# CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER 4 AND, IF SO, ASSIGN TO "PATHTOEXTENSION"
if [ "$4" != "" ] && [ "$pathToExtension" == "" ];then
pathToExtension=$4
fi
# Error if variable appName is empty
if [ "$pathToExtension" == "" ]; then
echo "Error: No value was specified for the pathToExtension variable..."
exit 1
fi
### Prompt the user to install the extension given # $4
osascript -e 'tell application "Safari"
activate
open "'"$pathToExtension"'"
end tell
delay 2
tell application "System Events"
tell process "Safari"
click button "Install" of window 1
end tell
end tell'
### Exit silently, as will error if exists & if times out for whatever reason
exit 0
I tell Safari to click the Install button. Rather than use a third party app.
Chmod'd the file to allow it to be an executable.
Used your LaunchAgent as is.
Manually loading the LaunchAgent ran the code. But as expected I also got the prompt to authorise install-ext.command to control the computer.
So I had to auth. That first.
Then any subsequent load of the LaunchAgent worked as desired including on login.
Why does this not work when I make it an app? Im trying to make this work but all it does is keystroke the commands in finder not terminal. It even works in the applescript editor just not as an app. Please help!
on run
tell application "Terminal" to quit
delay 5
tell application "Terminal" to activate
delay 3
tell application "System Events" to keystroke "n" using {command down}
delay 1
tell application "System Events" to keystroke "top" & return
delay 1
tell application "System Events" to keystroke "n" using {command down}
delay 1
tell application "System Events" to keystroke "open -a Bartender" & return
delay 1
tell application "System Events" to keystroke "open -a MobileMouseServer" & return
delay 1
tell application "System Events" to keystroke "open -a gfxCardStatus" & return
delay 1
tell application "System Events" to keystroke "open -a Caffeine" & return
delay 1
tell application "System Events" to keystroke "open -a Alfred" & return
delay 1
tell application "System Events" to keystroke "open -a smcFanControl" & return
delay 1
tell application "System Events" to keystroke "w" using {command down}
tell application "Finder" to display dialog "System startup successful." with title "T.R.A.V.I.S." with icon file "Macintosh HD:SCRIPTS:ICNS:travis.icns" giving up after 5
end run
Thanks
Consider this structure:
tell application "Terminal"
if not (exists window 1) then reopen
-- targets an existing window
do script "top" in window 1
-- open a new window
do script "open -a Bartender"
end tell