As part of an ongoing project I discovered a possible solution via UI scripting. To do a simple test I wrote the following script
tell application "System Events"
tell application process "Word"
click menu item "Save" of menu "File" of menu bar 1
end tell
end tell
I have Word running and a file open that has changes. When I ran the script in Smile I expected either the open file to be saved or an error message. Instead there was no action.
Note I’m running 10.2.8 and the UI scripting beta is installed.
tell application "System Events"
tell application process "Microsoft Word"
click menu item "Save" of menu "File" of menu bar item "File" of menu bar 1
end tell
end tell
tell application “Microsoft Word” to activate
tell application “System Events”
tell application process “Microsoft Word”
tell menu bar 1
tell menu “File”
every UI element
end tell
end tell
end tell
end tell
→ result: {}
I’m using Word v.X in Jaguar. You could use keystrokes:
tell application “Microsoft Word” to activate
tell application “System Events”
tell application process “Microsoft Word”
keystroke “s” with command down
end tell
end tell
From there you get the save dialog and may still get stuck.
EDIT: I found out why. With this version, you need to click on the “File” menu:
tell application “Microsoft Word” to activate
tell application “System Events”
tell application process “Microsoft Word”
tell menu bar 1
tell menu “File”
click
every UI element
end tell
end tell
end tell
end tell
tell application “Microsoft Word” to activate
tell application “System Events”
tell application process “Microsoft Word”
tell menu bar 1
tell menu “File”
click
click menu item “Save”
end tell
end tell
end tell
end tell
The first click clicks on the “File” menu and opens it up. The second click clicks on the menu item since it’s now there.
You may have provided the lynchpin of a problem I’ve been working on for a few weeks.
If your interested, I bought a UPS with a USB connection to the computer. The UPS communicates with the computer after a power failure. Before shutting down the OS and the computer it looks for a file called PowerChute.pre_shutdown in the following path
/etc/comapcpcpe/PowerChute.pre_shutdown
If this file is not provided it “force quits” any running user processes.
What I am trying to do is write a shell script (PowerChute.pre_shutdown) that will
1 - Detect all running visible processes
2 - Detect all open files
3 - Save all open files
4 - Quit all running visible processes
The two significant requirements are that no dialogs pop up (must perform with no one at the computer) and work with app’s that are not scriptable.
The shell script to do this is:
#!/bin/sh
/usr/bin/osascript <<EOT
AppleScript goes here
EOT
I have solved #'s 1, 2 and 4 above but #3 seemed hopeless until I “discovered” UI scripting. Since the “File” and “Save” menu items exist for all app’s that open files (hopefully), I’ve just taken a large step toward solving my problem.
Still some details to work out like separating out app’s that don’t open files (e.g., Mozilla).
If I get this working I will post the solution for all those that have contributed to this.
Very! I started testing this script with a number of app’s. Worked with Word, BBEdit and GraphicConveter. When I got to Excel it did nothing but spit out error messages.
Note, in the past I have found many things that worked for different app’s but not Excel. In this case I would have expected it to work since I am using the UI but it doesn’t. The script dies when it reaches the
“click”
after
tell menu “File”
Would really like to understand why Excel is such a pain in @$%**.
tell application "Microsoft Excel" to Activate
tell application "System Events"
tell application process "Microsoft Excel"
keystroke "s" with command down
end tell
end tell
I still have to test it for a number of app’s plus figure out what to do with multiple open doc’s in one app but - progress.
tell application “Microsoft Excel” to Activate
tell application “System Events”
tell process “Microsoft Excel”
every ui element
end tell
end tell
I get a result {}. So there is no menu bar 1. Here I would use Excels ‘save’ command or do keystrokes:
tell application “Microsoft Excel” to Activate
tell application “System Events”
tell process “Microsoft Excel”
keystroke “s” with command down
keystroke return
end tell
end tell
You would need to check if there is a front document (workbook in excel terminology). I think there is a mixup in Excel’s scripting terminology. I had problems with the ‘modified’ property of document or workbook. The ‘saved’ property of workbook seems to work better for checking if the workbook is modified but I haven’t tested it thoroughly. Mainly, what is the difference between ‘saved’ and ‘modified’. Anyway, after checking for a front document, then running the above script the document can be closed with the ‘close’ command. Using a repeat loop, you can continually get the front document until an error occurs (there are no front documents left). An error handler would trap the error and you may quit Excel.
Note: you may get an error after saving a new document and checking for its ‘saved’ property. Maybe it hasn’t registered yet. A delay may solve this, but an error handler may be better and you could just close the document.
Note: when saving a new document, you need to first check if a file with the same name exists in the save location. Otherwise, you’ll get a window telling you that a document with the same name exists. Here you would have to name the file with keystrokes in the save dialog.
I haven’t checked it out but maybe Jon’s script in the other post may work also with a little modification.
The following script works with the four app’s I’ve tried including Excel (with one remaining issue).
set alwaysExclude to "Finder"
set appstoQuit to {}
tell application "Finder"
set visProcs to name of processes whose visible is true
end tell
repeat with anApp in visProcs
if anApp is not in alwaysExclude then
copy anApp as string to the end of appstoQuit
end if
end repeat
set dumm0 to count of appstoQuit
if dumm0 > 0 then
repeat with i from 1 to dumm0
set test_flag to false
set theApp to item i of appstoQuit
tell application theApp to activate
repeat with j from 1 to 5
try
tell application theApp
get front document
end tell
tell application "System Events"
tell application process theApp
keystroke "s" with command down
keystroke "w" with command down
end tell
end tell
on error
set test_flag to true
tell application theApp to quit
exit repeat
end try
end repeat
if test_flag is false then
tell application theApp to quit
end if
end repeat
end if
The issue is that if the document is in the DOC, a modal window pops up asking you if you want to save. This doesn’t happen if you manually type command-s ???
Note, I had to add some extra garbage (test_flag) since Excel can have hidden documents used for macros.