am new to applescript. I want to access elements inside a dialog box/window. I tried following code.
tell application "System Events"
set procs to processes
set windowName to {}
repeat with proc in procs
try
if exists (window 1 of proc) then
repeat with w in windows of proc
if w's name contains "App Name" then
copy w's name to the end of windowName
copy properties of w to the end of windowName
end if
end repeat
end if
end try -- ignore errors
end repeat
end tell
return windowName
But am only able to get the 4 elements from window:
1.Close
2.Minimize
3.Maximize
4.window title
Nothing from inside the window/dilog.
Can any one help me with this pls?
You are only asking the window for its name and properties. If you want its elements then ask for its "ui elements".
Related
Someone tried to help me set up a keyboard macro using a program called keyboard maestro on macos to control youtube, his example had safari:
set tabURL to "YouTube.com"
tell application "Safari"
set windowsList to index of every window
repeat with i in windowsList
try
tell window i
set current tab to (first tab whose URL contains tabURL)
end tell
set index of window i to 1
exit repeat
end try
end repeat
end tell
It worked, I simply changed the name safari to google chrome, I put in this code:
set tabURL to "YouTube.com"
tell application "Google Chrome"
set windowsList to index of every window
repeat with i in windowsList
try
tell window i
set current tab to (first tab whose URL contains tabURL)
end tell
set index of window i to 1
exit repeat
end try
end repeat
end tell
it gave me this error message
2020-09-10 15:02:26 Execute an AppleScript failed with script error: text-script:165:176: script error: A class name can’t go after this identifier. (-2740)
what does it mean? any help appreciated.
tell application "Google Chrome"
repeat with thisWindow in windows
set cnt to 1
repeat with thisTab in (tabs of thisWindow)
if URL of thisTab contains "youtube.com" then
set active tab index of thisWindow to cnt
set index of thisWindow to 1
exit repeat
end if
set cnt to cnt + 1
end repeat
end repeat
end tell
this is the fix if anyone cares.
Applescript newbie question again :) I am trying to create a small applescript that will allow me to select multiple items from a list of currently running applications and then quit those selected apps. Something like this works but rather than having to click on each dialog it would be much easier to chose from a list.
tell application "System Events"
repeat with p in every process
if background only of p is false then
display dialog "Would you like to quit " & name of p & "?" as string
end if
end repeat
end tell
Any and all help would be greatly appreciated!
Thanks!
Try this:
tell application "System Events"
set listOfProcesses to (name of every process where background only is false)
tell me to set selectedProcesses to choose from list listOfProcesses with multiple selections allowed
end tell
--The variable `selectedProcesses` will contain the list of selected items.
repeat with processName in selectedProcesses
do shell script "Killall " & quoted form of processName
end repeat
tell application "System Events"
set processList to get the name of every process whose background only is false
set processNameList to choose from list processList with prompt "Select process to quit" with multiple selections allowed
if the result is not false then
repeat with processName in processNameList
do shell script "Killall " & quoted form of processName
end repeat
end if
end tell
you can use this script which is much simpler
tell application "Finder"
get the name of every process whose visible is true
end tell
You can try this
tell application "System Events"
set AppName to name of every process whose background only is false
choose from list AppName OK button name "Ok" cancel button name "Cancel"
end
& (name of every process whose (name is "AppName") can be added to Michele Percich's and Parag Bafna's solutions to include specific menu bar applications by name.
tell application processName to quit can be used instead of do shell script "Killall " & quoted form of processName.
tell application "System Events"
set processList to ¬
(name of every process where background only is false) & ¬
(name of every process whose ¬
(name is "AppName") or ¬
(name is "AnotherAppName"))
tell me to set selectedProcesses to choose from list processList with prompt "Select process(es) to quit:" with multiple selections allowed
end tell
if the result is not false then
repeat with processName in selectedProcesses
tell application processName to quit
end repeat
end if
I wrote this following AppleScript code a few years back. I consider it to be a “Must Have” because I use it almost every single day.
This code will generate a list of Visible and Hidden application processes, allowing multiple items to be selected to kill their processes. The first items in the list will be visible application processes (not sorted alphabetically), then an empty list item (used to separate the visible from the hidden processes), and the remaining list items will be the hidden application processes (sorted alphabetically)
use framework "Foundation"
use scripting additions
property appsToKill : missing value
property NSArray : a reference to current application's NSArray
listAllAppProcesses()
activate
set killApp to (choose from list ¬
appsToKill with title "Choose The App To Kill" with prompt ¬
"Choose The App/Apps To Kill" & linefeed & linefeed ¬
& "The Empty List Item Separates The Visible From The Hidden Applications" OK button name ¬
"OK" cancel button name "CANCEL" with multiple selections allowed)
set pidList to {}
if killApp is not false then
tell application "System Events"
repeat with i from 1 to count of killApp
set thisItem to item i of killApp
tell application process thisItem
set thePID to unix id
set end of pidList to thePID
end tell
end repeat
end tell
else
return
end if
set text item delimiters to space
do shell script ({"kill -9", pidList} as text)
on listAllAppProcesses()
tell application "System Events"
set visibleAppsToKill to name of every application process ¬
where visible is true
set invisibleAppsToKill to name of every application process ¬
where visible is false
set aList to ((NSArray's arrayWithArray:invisibleAppsToKill)'s ¬
sortedArrayUsingSelector:"caseInsensitiveCompare:") as list
set appsToKill to visibleAppsToKill & "" & aList
end tell
end listAllAppProcesses
If you want it from Terminal, you can use a simple script like this quit.rb
The following example AppleScript code is pretty straight forward and will gracefully quit the selected application(s), providing the selected application(s) is (are) in a stable state:
tell application "System Events" to ¬
set appList to the name of ¬
every process whose visible is true
set quitAppList to ¬
choose from list appList ¬
with multiple selections allowed
repeat with thisApp in quitAppList
quit application thisApp
end repeat
When I present a list to choose from, I prefer to have it in alphabetical order and to that end I use a handler to first sort the list before presenting it:
on SortList(thisList)
set indexList to {}
set sortedList to {}
set theCount to (count thisList)
repeat theCount times
set lowItem to ""
repeat with i from 1 to theCount
if i is not in the indexList then
set thisItem to item i of thisList as text
if lowItem is "" then
set lowItem to thisItem
set lowItemIndex to i
else if thisItem comes before lowItem then
set lowItem to thisItem
set lowItemIndex to i
end if
end if
end repeat
set end of sortedList to lowItem
set end of indexList to lowItemIndex
end repeat
return the sortedList
end SortList
To use this with the first block of code presented I typically add handlers at the bottom of my code and then to use it, add the following example AppleScript code between the tell application "Finder" to ¬ and set quitAppList to ¬ statements:
set appList to SortList(appList)
Note: I acquired this particular handler somewhere on the Internet too many years ago to remember and unfortunately lost who to credit it to. My apologies to whomever you are.
I am trying to write an applescript script that resizes all open windows. In order to make sure that I'm getting to all the windows, I'm making my script say the name of the application as well as the number of open windows of that application.
Interestingly, while I hear the names of all my open applications, my script says that they all have 0 windows open. How can I fix this issue?
Here's my code:
tell application "System Events"
repeat with theProcess in (every process)
if background only of theProcess is false then
if name of theProcess is not "Finder" then
if name of theProcess is "Google Chrome" then
say "Chrome woo hoo"
say (count windows as string)
else
say name of theProcess as string
say (count windows as string)
tell theProcess
repeat with theWindow in windows
say "found a window of"
say (name of theProcess) as string
tell theWindow
click button 2
end tell
end repeat
end tell
end if
end if
end if
end repeat
end tell
I'm on Mac OS X 10.7.5, using automator 2.2.4 to write/run this applescript
You have to tell the process to count windows. After all it's the process that knows about its windows, not system events.
You have told the process to say its name e.g. "say name of theProcess as string" however you only use "say (count windows as string)"... no process is tied to that. Try "count windows of theProcess". Basically you have lines where sometimes you tell the process, other times you don't, and other times where you tell the process even though you've already told the process, so you do it twice. That's where you have "say (name of theProcess) as string" but that code is inside a "tell theProcess" block so it's already being told to theProcess.
Really you need to go through your code and be more precise. A tip... if you want to click a button in a window then the window must be frontmost on the screen otherwise you can't click it. Another tip... "name" is already a string so you don't need to coerce that to a string.
By the way, I agree with Michael Dautermann's comment to your post... there will be processes where you won't get access. But you'll find that out as you progress.
Here's how I would write your code. Basically I would get all of the variables at the beginning using a "tell theProcess" block. Then I can do stuff with those variables. I hope that helps. Notice that I only made the process frontmost which means if it has multiple windows open it will only click a button on the front window. You'll have to add code to make each window come to the front before you can click its button. Good luck.
tell application "System Events"
repeat with theProcess in processes
if not background only of theProcess then
tell theProcess
set processName to name
set theWindows to windows
end tell
set windowsCount to count of theWindows
if processName is "Google Chrome" then
say "Chrome woo hoo"
say windowsCount as text
else if processName is not "Finder" then
say processName
say windowsCount as text
if windowsCount is greater than 0 then
repeat with theWindow in theWindows
say "found a window of " & processName
tell theProcess
set frontmost to true
tell theWindow
click button 2
end tell
end tell
end repeat
end if
end if
end if
end repeat
end tell
I create a list of all open windows of visible applications on Mavericks like this:
tell application "System Events"
set this_info to {}
repeat with theProcess in (application processes where visible is true)
set this_info to this_info & (value of (first attribute whose name is "AXWindows") of theProcess)
end repeat
this_info -- display list in results window of AppleScript Editor
end tell
You need to allow any app using this to access the interface under Accessibility.
I have two monitors set up and I am trying to position the window of an application in the second monitor but nothing I do seems to work. For example I am using my laptop and the terminal window is maximized on the screen. Then I plug in an external monitor. I then want to run the applescript and have the terminal maximize on the larger second monitor.
Here is what I have right now:
set monitorTwoPos to {1050, -600}
set monitorTwoSze to {1200, 1920}
tell application "Microsoft Outlook"
set position of window 1 to monitorTwoPos
set size of window 1 to monitorTwoSze
end tell
Here is the error I get:
/Users/vcutten/AppleScripts/SpacesWork.scpt:1291:1332: execution error:
Microsoft Outlook got an error: Can’t make position of window 1 into type specifier. (-1700)
I'm pretty sure I'm just using set position and set size completely wrong :( When I used bounds it kind of works...
Bonus Question:
How can I loop through the open windows and get their size? Thanks!
What have you tried?
I think to solve this you need to calculate the screen size and coordinates of the second monitor. For example, your main monitor starts at position {0,0}. So the starting position of the second monitor has to be something different and you need to find that. Luckily I have written a tool that will give you both the starting coordinates and screen size of your monitors. Once you have the size and position then it's simple. System events can set the size and position of a window so you could do something like this...
set monitorSize to {800, 600}
set monitorPosition to {-800, 0}
tell application "System Events"
tell process "Terminal"
set frontWindow to first window
set position of frontWindow to monitorPosition
set size of frontWindow to monitorSize
end tell
end tell
So from the above script you just need the size and position variables. You can get my tool here called hmscreens which will give you those. You may need to do some adjusting of the coordinates depending on if the screen is measured from the lower left corner or upper left, but that's just simple math.
I hope that helps...
Use bounds instead of position, it works. You can get bounds of the window like this:
tell application "Microsoft Outlook"
get bounds of first window
end tell
Answer to the bonus question:
tell application "Microsoft Outlook"
repeat with nextWindow in (get every window)
get bounds of nextWindow
end repeat
end tell
If you open Replies tab at bottom part of Applescript editor, you will see all get results.
Hope it helps.
Here is a script that handles saving and restoring size and postion for multiple display configurations. It may have some issues with fullscreen apps but it seems to work ok.
-- allSettings is a list of records containing {width:? height:? apps:{{name:? pos:? size:?},...}
-- for each display setup store the apps and their associated position and size
property allSettings : {}
-- create a variable for the current settings
set currentSettings to {}
display dialog "Restore or save window settings?" buttons {"Restore", "Save"} default button "Restore"
set dialogResult to result
tell application "Finder"
-- use the desktop bounds to determine display config
set desktopBounds to bounds of window of desktop
set desktopWidth to item 3 of desktopBounds
set desktopHeight to item 4 of desktopBounds
set desktopResolution to desktopWidth & "x" & desktopHeight
-- find the saved settings for the display config
repeat with i from 1 to (count of allSettings)
if (w of item i of allSettings is desktopWidth) and (h of item i of allSettings is desktopHeight) then
set currentSettings to item i of allSettings
end if
end repeat
if (count of currentSettings) is 0 then
-- add the current display settings to the stored settings
set currentSettings to {w:desktopWidth, h:desktopHeight, apps:{}}
set end of allSettings to currentSettings
--say "creating new config for " & desktopResolution
else
--say "found config for " & desktopResolution
end if
end tell
tell application "System Events"
if (button returned of dialogResult is "Save") then
say "saving"
repeat with p in every process
if background only of p is false then
tell application "System Events" to tell application process (name of p as string)
set appName to name of p
if (count of windows) > 0 then
set appSize to size of window 1
set appPosition to position of window 1
else
set appSize to 0
set appPosition to 0
end if
set appSettings to {}
repeat with i from 1 to (count of apps of currentSettings)
if name of item i of apps of currentSettings is name of p then
set appSettings to item i of apps of currentSettings
end if
end repeat
if (count of appSettings) is 0 then
set appSettings to {name:appName, position:appPosition, size:appSize}
set end of apps of currentSettings to appSettings
else
set position of appSettings to appPosition
set size of appSettings to appSize
end if
end tell
end if
end repeat
end if
if (button returned of dialogResult is "Restore") then
if (count of apps of currentSettings) is 0 then
say "no window settings were found"
else
say "restoring"
repeat with i from 1 to (count of apps of currentSettings)
set appSettings to item i of apps of currentSettings
set appName to (name of appSettings as string)
try
tell application "System Events" to tell application process appName
if (count of windows) > 0 then
set position of window 1 to position of appSettings
set size of window 1 to size of appSettings
end if
end tell
end try
end repeat
end if
end if
end tell
https://gist.github.com/cmackay/5863257
This is an application specific problem. I am trying to find and select a tab in Terminal.app depending on contents within. Here is what I'm doing:
tell application "Terminal"
set foundTabs to (every tab of every window) whose contents contains "selectme"
repeat with possibleTab in foundTabs
try
set selected of possibleTab to true
end try
end repeat
end tell
This isn't acting as expected and is pretty foolproof. I wonder if someone can suggest a way to do this with much less code (for instance, the looping shouldn't really be necessary, but applescript is an elusive language).
Thanks
Thing is, the following Applescript will do what you want, but unless your "selectme" string is very unique, you will find it in many tabs.
But anyway, here you go:
tell application "Terminal"
set allWindows to number of windows
repeat with i from 1 to allWindows
set allTabs to number of tabs of window i
repeat with j from 1 to allTabs
if contents of tab j of window i contains "selectme" then
set frontmost of window i to true
set selected of tab j of window i to true
end if
end repeat
end repeat
end tell