trying to add a password to a PDF in AppleScript. The below code gets through
click menu item 23 -- Export Menu item
but fails on the next line with an "invalid index" error "Can't get window 1..."
... and then guessing my next line for the checkbox will need something similar on the end.
Thanks in advance
Tim
set myFolder to path to desktop as string
set myFile to myFolder & "test.pdf"
tell application "Preview"
open myFile
activate
end tell
tell application "System Events"
tell process "Preview"
tell menu bar 1
tell menu bar item "File"
tell menu "File"
click menu item 23 -- Export Menu item
click button "Permissions..." of sheet 1 of window 1
click checkbox "Require Password To Open Document"
text field 1
keystroke "1234"
text field 2
keystroke "1234"
text field 3
keystroke "1234"
text field 4
keystroke "1234"
keystroke return
keystroke return
end tell
end tell
end tell
end tell
end tell
The example AppleScript code, shown below, was tested in Script Editor under macOS Monterey with Language & Region settings in System Preferences set to English (US) — Primary and worked for me without issue1.
The example AppleScript code is coded to check whether or not the [] Use keyboard navigation to move focus between controls checkbox is checked on the System Preferences > Keyboard > Shortcuts tab, as that would affect how one would programmatically navigate the various dialog boxes using the tab key. It's coded to then branch one way to the other to handle the state of that checkbox.
Here is an example of how I would code it:
Example AppleScript code:
property myPassword : "1234"
set myFolder to path to desktop as string
set myFile to myFolder & "test.pdf"
-- # Get the value of AppleKeyboardUIMode to determine if the
-- # 'Use keyboard navigation to move focus between controls'
-- # checkbox is checked on the System Preferences >
-- # Keyboard > Shortcuts tab.
set keyboardNavigation to my checkAppleKeyboardUIMode()
-- # Open the target file in Preview.
tell application "Preview"
open myFile
activate
end tell
-- # Use System Events to export the document
-- # and navigate the ensuing dialog boxes.
tell application "System Events"
tell application process "Preview"
tell its menu "File" of ¬
menu bar item "File" of menu bar 1 to ¬
click (its first menu item whose name is "Export…")
repeat until exists button "Permissions…" of sheet 1 of window 1
delay 0.1
end repeat
tell its sheet 1 of window 1 to click button "Permissions…"
repeat until exists ¬
checkbox "Require Password To Open Document" of ¬
sheet 1 of sheet 1 of window 1
delay 0.1
end repeat
tell its sheet 1 of sheet 1 of window 1
click checkbox "Require Password To Open Document"
delay 0.1
if keyboardNavigation = 0 then
-- # Use keyboard navigation to move focus
-- # between controls is not checked.
key code 48 -- # tab key
delay 0.1
key code 48 -- # tab key
delay 0.1
keystroke myPassword
delay 0.1
key code 48 -- # tab key
delay 0.1
keystroke myPassword
delay 0.1
key code 48 -- # tab key
delay 0.1
keystroke myPassword
delay 0.1
key code 48 -- # tab key
delay 0.1
keystroke myPassword
else
-- # Use keyboard navigation to move
-- # focus between controls is checked.
key code 48 -- # tab key
delay 0.1
keystroke myPassword
delay 0.1
key code 48 -- # tab key
delay 0.1
keystroke myPassword
delay 0.1
repeat 6 times
key code 48 -- # tab key
delay 0.1
end repeat
keystroke myPassword
delay 0.1
key code 48 -- # tab key
delay 0.1
keystroke myPassword
end if
delay 0.1
click button "Apply"
delay 0.1
end tell
click button "Save" of sheet 1 of window 1
delay 0.1
if exists button "Replace" of sheet 1 of sheet 1 of window 1 then ¬
click button "Replace" of sheet 1 of sheet 1 of window 1
delay 0.1
click button 1 of window 1 -- # Close the document.
end tell
end tell
-- ## Handler ##
on checkAppleKeyboardUIMode()
-- # Get the fully qualified POSIX pathname of the target .plist file.
set thePropertyListFilePath to ¬
the POSIX path of ¬
(path to preferences from user domain as string) & ¬
".GlobalPreferences.plist"
-- # Get the value of AppleKeyboardUIMode to determine if the
-- # 'Use keyboard navigation to move focus between controls'
-- # checkbox is checked on the System Preferences >
-- # Keyboard > Shortcuts tab.
try
tell application "System Events" to ¬
tell the property list file thePropertyListFilePath to ¬
return the value of ¬
the property list item "AppleKeyboardUIMode"
on error
return 0
end try
end checkAppleKeyboardUIMode
Notes:
One of the issues in the code of the question was the use of three .
instead of an ellipsis …
in: click button "Permissions..."
Also, the remaining code would not have executed because it is wrapped in a tell menu "File"
statement. The example AppleScript code presented herein focuses in the proper places for the events to take place when compared to how its coded in the question.
Note that UI Scripting is kludgy at best and prone to failure due to changes in the hierarchical UI element structure of the OS and or application being scripted and or timing issues where the use of the delay
command may be necessary and or its value adjusted.
Case in point, I originally coded this to avoid using tabbing and keystroking, however it presented mixed results in that it worked sometimes and not other times, and why I recorded to do those very things. (UI Scripting Ugh!)
Also, as the first dialog box in the export process is not changing the name of the document or the location it is being saved, the password protected document may end up in a different location than from where it was opened. Additional coding required to modify that possible behavior.
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.