I'm trying to write a script that logs the current app, switches to another app, does some task, and comes back to the original app. This is what I have
set currentApp to my getCurrentApp()
activate application "Safari"
# Some task
activate application currentApp
to getCurrentApp()
set front_app to (path to frontmost application as Unicode text)
set AppleScript's text item delimiters to ":"
set front_app to front_app's text items
set AppleScript's text item delimiters to {""} --> restore delimiters to default value
set item_num to (count of front_app) - 1
set app_name to item item_num of front_app
set AppleScript's text item delimiters to "."
set app_name to app_name's text items
set AppleScript's text item delimiters to {""} --> restore delimiters to default value
set MyApp to item 1 of app_name
return MyApp
end getCurrentApp
The weird thing is that the activate application command works if you type in a string literal, but if you pass it a string variable, it will not activate the application. Any ideas why?
Your script works for me. Activating an application with a string variable has always worked in any version of OSX... so you have some different problem happening. The problem is not in the code you are showing.
Although your code works, you can shorten your getCurrentApp() subroutine like this...
set currentApp to my getCurrentApp()
activate application "Safari"
delay 1
activate application currentApp
to getCurrentApp()
return (path to frontmost application as text)
end getCurrentApp
You really don't even need "as text" in the subroutine if you also remove "application" from the activate line...
set currentApp to my getCurrentApp()
activate application "Safari"
delay 1
activate currentApp
to getCurrentApp()
return (path to frontmost application)
end getCurrentApp
So after all is said and done, your code could look like this...
set currentApp to path to frontmost application
activate application "Safari"
delay 1
activate currentApp
EDIT: Sometimes when you try to get the frontmost application, the applescript that you are running is the frontmost application instead of the app you think is frontmost. It's very hard to detect when this happens but I suspect this may be happening to you. So here's a subroutine that I use the get the frontmost app. This ensures that the applescript is not returned as the frontmost app. Give it a try and see if it helps...
on getFrontAppPath()
set frontAppPath to (path to frontmost application) as text
set myPath to (path to me) as text
if frontAppPath is myPath then
try
tell application "Finder" to set bundleID to id of file myPath
tell application "System Events" to set visible of (first process whose bundle identifier is bundleID) to false
-- we need to delay because it takes time for the process to hide
-- I noticed this when running the code as an application from the applescript menu bar item
set inTime to current date
repeat
set frontAppPath to (path to frontmost application) as text
if frontAppPath is not myPath then exit repeat
if (current date) - inTime is greater than 2 then exit repeat
end repeat
end try
end if
return frontAppPath
end getFrontAppPath
Related
When I get the reference to a window using for example:
tell application "Safari"
set theWindow to first window
end tell
log(process(theWindow)) -- # Safari
tell application "Terminal"
set theWindow to first window
end tell
log(process(theWindow)) -- # Terminal
to process(theWindow)
-- How to get app name from "theWindow"
end process
From the variable theWindow, is it possible to extract the app name "Safari"? I need to know this information from a handler because the handler can accept window reference of other application as well.
tell application "Safari"
set theWindow to first window
end tell
log (process(theWindow))
tell application "Terminal"
set theWindow to first window
end tell
log (process(theWindow)) -- # Terminal
to process(theWindow)
try
theWindow as text
on error errorMessage
end try
set ATID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "\""
set appName to text item 2 of errorMessage
set AppleScript's text item delimiters to ATID
return appName
end process
This script works when terminal application(or any application) is not in FullScreen mode. It will return the correct value of false. When you make the application fullscreen it returns any empty value. The only thing I can think of is that when you go fullscreen it puts it on a different desktop? Am I missing something to activate the app differently now that it is fullscreen?
tell application "System Events" to set the visible of every process to true
set white_list to {"Finder", "AppleScript Editor", "Google Chrome"}
tell application "System Events"
set process_list to the displayed name of every process whose visible is true
set process_number to (number of items in process_list)
set myList to process_list
end tell
repeat with theItem in myList
if theItem is not in white_list then
log theItem
tell application "System Events" to tell process theItem
set isFullScreen to the value of attribute "AXFullScreen" of windows
end tell
end if
end repeat
return theItem & " application is FullScreen: " & isFullScreen
This line won't work as written...
set isFullScreen to the value of attribute "AXFullScreen" of windows
"windows" will return a list of windows and you can't get that attribute from a list. So you would want to write it as...
set isFullScreen to the value of attribute "AXFullScreen" of window 1
However, with that said I tried this and it seems you can't get the windows from a full screen process. The list of windows is always empty {}. So this approach of determining if an application is full screen will not work.
You'll need to think of another way to figure out if an application is full screen. I tried a couple things and couldn't find a solution. Sorry.
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 wrote a simple script that finds out how many active processes are running on the machine right now, and outputs the paths of each one into an array as a string.
Here's my code (it really has no legitimate function, I'm just trying to try different things to see how applescript works):
tell application "System Events"
set activeProcess to number of process
set paths to {0}
repeat with n from 1 to activeProcess
set last item of list paths to (file of process n as string)
end repeat
end tell
And here's the error applescript editor returns when I hit run:
System Events got an error: Can’t set list {0} to "Macintosh HD:System:Library:CoreServices:loginwindow.app:".
What am I don't wrong?
Try:
tell application "System Events" to set myprocess to files of processes
or
set AppleScript's text item delimiters to linefeed
tell application "System Events" to set myprocess to paragraphs of (files of processes as text)
set AppleScript's text item delimiters to {""}
You can build a list from a repeat loop like this:
set paths to {}
tell application "System Events"
set activeProcess to processes
repeat with n from 1 to count activeProcess
set end of paths to (file of item n of activeProcess as text)
end repeat
end tell
or like this:
set paths to {}
tell application "System Events"
set activeProcess to processes
repeat with aProcess in activeProcess
set end of paths to (file of aProcess as text)
end repeat
end tell
How would I quit all running user applications using Applescript?
It's okay... I think I found my answer:
tell application "System Events" to set the visible of every process to true
set white_list to {"Finder"}
try
tell application "Finder"
set process_list to the name of every process whose visible is true
end tell
repeat with i from 1 to (number of items in process_list)
set this_process to item i of the process_list
if this_process is not in white_list then
tell application this_process
quit
end tell
end if
end repeat
on error
tell the current application to display dialog "An error has occurred!" & return & "This script will now quit" buttons {"Quit"} default button 1 with icon 0
end try
After some googling, I found a better approach:
It uses background only to build the initial app list, rather than
visible is true. The difference is that the other scripts will fail
to quit an app that's been hidden with ⌘H.
It provides an exclusions
list so that, for example, you can prevent your script editor from
quitting each time you test the script.
Adapted from a thread on MacScripter.
-- get list of open apps
tell application "System Events"
set allApps to displayed name of (every process whose background only is false) as list
end tell
-- leave some apps open
set exclusions to {"AppleScript Editor", "Automator", "Finder", "LaunchBar"}
-- quit each app
repeat with thisApp in allApps
set thisApp to thisApp as text
if thisApp is not in exclusions then
tell application thisApp to quit
end if
end repeat
tell application "System Events" to set the visible of every process to true
set white_list to {"Finder"}
try
tell application "Finder"
set process_list to the name of every process whose visible is true
end tell
repeat with i from 1 to (number of items in process_list)
set this_process to item i of the process_list
if this_process is not in white_list then
tell application this_process
quit
end tell
end if
end repeat
on error
tell the current application to display dialog "An error has occurred!" & return & "This script will now quit" buttons {"Quit"} default button 1 with icon 0
end try
tell application "System Events" to set quitapps to name of every application process whose visible is true and name is not "Finder"
repeat with closeall in quitapps
quit application closeall
end repeat