Applescript Editor won't run program - syntax error? - applescript

Here's my script:
on idle
tell application "Finder" to open the startup disk
return 100
end idle
When I hit compile, it appears to compile. When I hit run, nothing happens. I've made several variants and I get get any to run.

It won’t run from AppleScript Editor, because AppleScript Editor doesn’t idle, so to speak.
One solution, if you need to run it from AppleScript Editor for testing, is to put the meat of the script into a separate handler, and then call that handler from both the idle and run handlers;
on openStartup()
tell application "Finder" to open the startup disk
end doMeat
on idle
openStartup()
return 100
end idle
on run
openStartup()
end run
If you don’t need to run it from AppleScript Editor, then just save it as an application. Applications get idle messages, and so it will work from there.
If you need to test multiple iterations of the script in AppleScript Editor, you can fake the idle by just calling the handler twice in your run handler, with a delay between them:
on run
openStartup()
delay 100
openStartup()
end run
And of course you could also use a loop to repeat multiple times.
Just remember to comment out the test run handler when you save it as an application.
For simple scripts, I often just replace idle with run when I’m testing it, then put run back to idle when I save it.

Related

Applescript applicationH

I've made my first apple script (with a bit of help).
It works fine:
delay 5
tell application "SelfControl"
activate
end tell
tell application "System Events"
tell process "SelfControl"
click button "Start" of window 1
end tell
end tell
This was running inside applescript. Now I'm trying to run it as an application, So I've added the line
on run {input, parameters}
[at the top]
and the lines
return input
end run
[at the bottom]
and then exported as an application. however I get the error
"current application doesn’t match the parameters {input, parameters} for run." when I try to run.
Any advice?
What use do you have of these parameters in your code?
How are you going to give them as an input and receive the output?
When I exported AppleScript codes as applications, I didn't add these lines and they worked completely fine. Just try to export without them!
The on run handler with parameters belongs to the Automator AppleScript action.
Every script / application script provides an implicit on run handler (without parameters) and without return value.
on run
...
end run
This handler is only needed explicitly if other basic handlers like on idle or on open are specified, too. In all other cases just omit it.

applescript: how to terminate an executing terminal

I'm trying to make an apple script to allow me to manage a cpp project automatically. And I used Jenkins too.
Basically, the cpp project is a kind of infinite loop, which will execute in a terminal. And I set Jenkins rebuild and execute it per 20 sec. In other words, my pc should do the tasks below:
1) rebuild the project;
2) execute the project;
3) wait for 20 sec;
4) close the terminal.
However, when I arrive at 4), a dialog will pop up: Do you want to close this window?
So I have to click the button "Close".
My question is: how to code in applescript to do the 4) automatically?
Here is my applescript:
tell application "Terminal"
do script "cd /Users/Shared/Jenkins/Home/workspace/test"
do script "make clean" in window 1
do script "make" in window 1
do script "./matrix.out" in window 1
delay 20
close window 1 # problem's here
end tell
However, when I arrive at 4), a dialog will pop up: Do you want to close this window? So I have to click the button "Close".
But you can do that using AppleScript too (via GUI scripting thru System Events), so nothing you've said is a problem so far.
tell application "Terminal" to activate
tell application "System Events"
tell application process "Terminal"
tell its window 1
tell its sheet 1
click button "Close"
end tell
end tell
end tell
end tell
I wonder if this might help:
Running process in background after closing terminal
The problem might be that what you're lastly running in the terminal is a process (matrix.out) that will get killed by closing the window, and you don't want that, right? So it may be that you need to alter the matrix.out script using the technique described (if possible) to keep it from doing that.
It may also be possible to solve your problem by making matrix.out executable (chmod it to executable or use Kilometre) and just "open it" using vanilla applescript.

Apple Script application control

Thanks for reading my question. I have an issue I was hoping you could help me with. the following apple script will run but ends up timing out because the application is not selected; the icon just bounces on the mac server dock (OSX 10.85). What am I doing wrong?
tell application "(Application Name)"
activate
getURL "(Server URL)"
delay 30
tell database "(database name)"
do script "(Script Name)"
delay 60
close
end tell
end tell
do shell script "(Shell script path)"
Also, I'd like to tell the application to quit prior to running the shell script.
Any and all advice would be appreciated.
THANK YOU!
To quit an app, all you do is put a “quit” command inside its tell block, typically as the last command in the tell block:
tell application "Safari"
quit
end tell
Verify that “getURL” is the right command for the app you are targeting. The modern version is “open location.”
When you run your script from AppleScript Editor, you can tap on “Event Log” at the bottom of the window and see a log of events that occurred during your script’s execution. You can often see what went wrong there.
If your AppleScript is what is timing out, you can use with timeout:
with timeout of 3600 seconds
-- do something within an hour
end timeout
As jweaks said, you need to provide more information to get real help. Every application extends AppleScript in its own way. Your script may be perfect or it may not. There is no way for someone to know without knowing what application your script runs on. It’s like asking for help with Photoshop work but not telling anyone it is Photoshop you are working in.

infinite loop in applescript stops logout

So I am writing a basic applescript to end a very annoying program that randomly opens and interrupts me while Im working. The program needs to stay but i don't want to see it. I want my script to open automatically when the computer restarts (I did this in settings). I want to test to make sure it works but upon saving it as an application I cannot logout or shutdown or restart without manually force quitting. I assume this is because of the repeat loop but i don't know how to fix this. Ive tried everything i could think of. Any help would be greatly appreciated. thank you
on appIsRunning(appName)
tell application "System Events" to (name of processes) contains appName
end appIsRunning
repeat
if appIsRunning("LiveUpdate") then
tell application "LiveUpdate"
quit
end tell
end repeat
I'm not sure you have the proper approach either. However, if you want to do what you are trying to do then you want to create a stay-open application. You do that by saving the applescript as an application and checking the "stay open after run handler" checkbox. Here's how you write the code for that...
on idle
if appIsRunning("LiveUpdate") then tell application "LiveUpdate" to quit
return 10
end idle
on appIsRunning(appName)
tell application "System Events" to (name of processes) contains appName
end appIsRunning
Notice the "on idle" handler. That is the handler that is repeatedly run while the application stays open. Notice that I have placed "return 10" at the end of that handler. That determines how often the idle handler runs, in this case every 10 seconds. You can change that to what you want.
The advantage of this method is that you can quit this stay-open application. You won't get stuck in a repeat loop that you can't quit.
You mention that you do not want to see this application while it is running. To make that happen you will have to modify the info.plist file inside the application bundle (right-click on the application and show package contents). You have to add the "LSUIElement" key to the plist and give it a value of true. Then you won't see the application in the Dock while it's running.
Because you can't see it running you will need some way to quit the application. You can do that either using another applescript...
tell application "My Stay Open Application" to quit.
Or you can open activity monitor and quit it from there. Good luck.
Here is another approach:
on idle
if application "LiveUpdate" is running then tell application "LiveUpdate" to quit
return 10
end idle

Google SketchUp close file

The Ruby API to Google SketchUp has a function, open_file, but I can't find a close_file function. Since I have to batch process many files, I want to close each file before moving on to the next, otherwise the program will crash from memory exhaustion.
What is the best way to close SketchUp files programmatically?
I am using Mac OS X and am willing to use AppleScript functions to signal the window to close.
EDIT
I am considering a few approaches that have proven fruitless so far.
Using the appscript Ruby gem, as described in this question. The problem here is that I cannot get SketchUp to recognize my installed gems.
In a similar vein, I am trying to use osascript (a bash program that executes AppleScripts from the shell) to close the window. That is, I call out to the shell from SketchUp's Ruby console window using one of the following:
%x[osascript -e 'tell application "SketchUp" to close window 1']
%x[osascript -e 'tell application "SketchUp" to close window 1' &]
%x[osascript -e 'tell application "SketchUp" to close every window']
%x[osascript -e 'tell application "SketchUp" to close every window' &]
Whenever I try this second approach, SketchUp just freezes. However, when I execute any of these commands from an IRB or directly from the Bash prompt outside of SketchUp, I get the desired behavior: the model window closes (incidentally, the Ruby console window remains open, which is fine).
Have a master script that launches a slave script to process each model. The slave will run within the Google SketchUp program while the master waits. When the slave is finished, it signals the master, and the master closes the SketchUp file. To do this interprocess communication, I tried using drb. However, when I try to require drb within SketchUp, I get the following message:
Error: LoadError: (eval):5:in 'require': no such file to load -- drb
EDIT 2
Having a separate process continuously running that closes Google Sketchup windows using AppleScript when signaled is clumsy for a number of reasons. First, it's ugly to have to have a separate process devoted to closing Sketchup windows. Second, the only effective way of communicating with the external script is through the creation of files, which is wasteful and the disk access may be slowing things down.
However, the most severe issue is that Sketchup is slow at responding to AppleScript commands. I have a pretty computation intensive script running in Sketchup, and it seems to starve the AppleScript response, which means that the osascript times out before the windows close. Sketchup only gets around to responding to AppleScript when there is a dialogue box prompt in Sketchup that pauses the execution of my computationally intensive script.
EDIT 3
I have modified my close_file function to pause execution of the script by displaying a dialog box. This essentially yields the current thread and allows the thread that responds to AppleScript commands to execute:
def close_file()
f = '/temp/mutex.txt' # for finer control, use different mutex for each window you want closed
File.new(f, 'w').close
result = UI.messagebox "Click OK when window has closed."
end
Then the separate ruby script that closes windows via AppleScript will additionally have to click "OK" in the dialog box. AppleScript to do that is:
tell application "System Events"
tell process "SketchUp"
set frontmost to true
keystroke return
end tell
end tell
This modification is an improvement. It corrects the "most severe issue" mentioned in EDIT 2, but the other issues remain.
There is an important limitation with using an external AppleScript to force SketchUp to do something. SketchUp will not accept any user input while a menu script is running.
I found this out trying to setup an automated rendering solution. I added a menu item which opens a WebDialog to get a list of models to download from a server. It then steps through the list and uses cURL to download each model. Once downloaded it loads the model, renders it out, uploads the images using cURL again, and goes to the next model.
What I wanted was to activate the AppleScript after each model is rendered (using the "mutex" file solution shown above) and have it close the model window. Unfortunately, since the menu script is still running, SketchUp will not respond to anything the AppleScript tells it to do. Only once all of the models have been processed and the menu script exits, will the AppleScript finally run.
This would not be so bad if all of the calls to the AppleScript were queued up, but they aren't. It seems that only the last two get honored (that number may be just an accident dependent on the timing of when my calls to the AppleScript were made relative to when the menu script finished).
Because of this limitation, I was not able to use the mutex wait() function in my menu Ruby code. Since the AppleScript was not able to execute, it never created its "I'm done" mutex file, and therefore the wait() function in Ruby never got the signal that it could continue. The result was a deadlock between AppleScript and SketchUp, such that SketchUp just freezes up (well, actually it is just stuck in a really tight loop in the wait() function).
So, when approaching this problem, think of AppleScript as a cleanup tool you can call when all of your processing is done.
One solution is to have a separate process continuously running that will close Google Sketchup windows using AppleScript when signaled. The approach described here uses files to do the interprocess communication (drb did not seem to work).
First, you have to make sure Sketchup supports AppleScripting. To do this, execute the following at the command prompt (with appropriate substitutions for different Sketchup versions, etc.):
$ defaults write /Applications/Google\ SketchUp\ 8/SketchUp.app/Contents/Info NSAppleScriptEnabled -bool YES
Now, create a separate file that will close Sketchup windows. Here is my closer.rb file:
#!/usr/bin/ruby
## closer.rb ##
def wait(f)
while !File::exists?(f)
end
File.delete(f)
end
def signal(f)
File.new(f, 'w').close
end
while true
wait('~/temp/mutex.txt')
msg = %x[osascript -e 'tell application "SketchUp" to close every window']
signal('~/temp/conf.txt')
end
Run this script from the shell. It waits until the file ~/temp/mutex.txt is created. Once the file is created, it runs osascript (essentially AppleScript) to close all the windows in Sketchup, and then signals that the windows were closed by creating a ~/temp/conf.txt file.
Here is the client code (which can be placed in your Sketchup plugins) that signals the closer script:
def wait(f)
while !File::exists?(f)
end
File.delete(f)
end
def signal(f)
File.new(f, 'w').close
end
def close_file
signal('~/temp/mutex.txt')
wait('~/temp/conf.txt')
end
The close_file signals the closer script and then waits for a confirmation that the file was closed before returning. Now you can close files in Sketchup.
You can do a lot with SketchUp using applescript and/or Automator.
tell application "SketchUp"
activate
tell application "System Events"
delay 1.0 --close window, adjust delay to suit
--key code 13 using command down -- Press ⌘W or you can use
keystroke "w" using command down
end tell
end tell
I have a number of status bar items for open new, paste to console, closing, killing SU etc.
They're tiny files that trigger the SU shortcut keys, and can be used externally, from 'Ruby Console' or as part of a plugin.
I'm not sure what kind of 'batch convert' your trying to achieve, but
I used Automator to convert most of my old v5, V6, v7 files to v8 today...
100's of them,
and your probably aware, on opening you get 'alert' warning that saving will convert the file to the latest version (which is what I wanted).
It's tricky to click this "OK" programatically.
Automator on it's own is quite restricted, but you can add an applescript to the workflow and I've found that if you use it's 'record function' to demonstrate what you need to do.
You can then copy/paste that code into 'Script Editor', get rid of the 'dowithTimeout' bits, copy it back into the workflow with delays either side and let it run.
I had to play around with delays, to accommodate some larger files, but achieved >95% success. [Success being able to select all, right click, Create Icon and Preview.]
Unfortunately I then binned the workflow, but could recreate it, if you want to have a look.
success, in Ruby Console
system("osascript -e 'tell application \"suoff\"' -e 'activate' -e 'end tell'")
and this script inside an Automator.app in applications folder....
on run
-- Make sure SU is foremost, don't click on anything else either
tell application "System Events"
tell process "SketchUp"
set frontmost to true
-- gives a message if you try to select when SU's not running
delay 0.2
tell application "SketchUp" to quit saving no
-- no dialog box etc...
delay 0.1
end tell
end tell
end run
the problem is SU has an anti self destruct ruby, that mines any linked files and aborts all efforts to shut it down... from inside itself.
so you need to bury it...
this combination works on 10.5.8 with SU8.1.
if you have a look at SketchUcation [Developer] Forum, I left a call for mac/applescript testers... I've rewritten the app since then but if you PM me I'll send you an open copy of all the bits I've got working..
john
I had to convert hundreds of .skp files with a batch processing script. I faced similar issue, since every time I opened a new file it remained opened. For me it was enough to close the active_model and the file goes with it.
This was true for SketchUp 2019 Pro Mac OS X version.
model = Sketchup.active_model
model.save(filename, Sketchup::Model::VERSION_2015)
model.close
Hope it will help

Resources