2

Help!!

I have put in many hours trying to solve this and feel it is time to get some help :)

I am trying to write an Applescript in Automator that will execute certain keystrokes in Finder for the parent folder and each sub-folder. So far I can only get the keystrokes to be applied to the parent folder that is selected during the execution of the script; the sub-folders remain as they were without having had the keystrokes applied.

The keystrokes are specific to Finder and make the folder arranged by "Kind" and sorted by "Name".

Here is my code:

activate application "Finder"

tell application "Finder"
    set theFolders to every folder of (choose folder) as alias list
end tell

tell application "System Events"
    repeat with eachFolder in theFolders
        keystroke "2" using {control down, command down}
        keystroke "1" using {control down, option down, command down}
    end repeat
end tell

The code makes sense to me in my limited knowledge of Applescript, but obviously it is not working correctly.

Any advice?

2
  • If I understand your intent correctly, you're not actually moving on to the sub-folders. You would have to enter each subfolder with Command-↓ before applying the settings to the sub-folders, I believe.
    – tubedogg
    Sep 9, 2016 at 2:28
  • I don't know if you've seen my answer yet, however I just undated it. I modified the code slightly and added a few comment to the code and contents of the answer. Sep 9, 2016 at 17:18

2 Answers 2

0

If I understood what you want, i.e. select a folder and then it and every sub-folder within it, including sub-folders of subfolders etc., gets these setting applied.

In order to pass the keystrokes to the target folders each needs to be the active window in Finder first, then System Events can send the keystrokes.

So, I'd write the code as in the example below.

tell application "Finder"
    activate
    set parentFolder to (choose folder) as alias
    set theFolders to every folder of entire contents of parentFolder as alias list
    set theFolders to {parentFolder} & theFolders    -- # Adds the chosen folder to the list of folders to be acted upon.
    repeat with eachFolder in theFolders
        open eachFolder
        delay 0.5
        activate eachFolder    -- # This is done to ensure the target folder's window has focus before being acted upon.
        tell application "System Events"
            keystroke "2" using {control down, command down}    -- # Sets: View > Arrange By > Kind
            keystroke "1" using {control down, option down, command down}    -- # Sets: View > Sort By > Name
        end tell
        close eachFolder
    end repeat
end tell

If you're wanting to act only on the top level sub-folders within the parent folder, then in place of:

set theFolders to every folder of entire contents of parentFolder as alias list

Use the following:

set theFolders to every folder of parentFolder as alias list    

Note that the delay 0.5 may not be absolutely necessary however I added it because without it, the series of opening and closing folder's windows can go by so fast it's disconcerting and slowing it down a bit eases that. Although it may also be necessary, depending on how fast/slow the processing takes place, to ensure each folder's window in the repeat loop is actually available and has focus in order to receive the keystrokes. In either case, the value of delay may/can be changed as necessary/wanted to allow the tasks to properly occur and in a visual manner that appears more natural then a barrage of opening/closing windows leaving one to wonder, what just happened.

4
  • Nice! Thanks this got me on the right track! Thanks very much for you help. I'll post more details below.
    – mvern
    Sep 11, 2016 at 0:47
  • @mvern, I appreciate the thanks however here in the SE communities when am answer is helpful we show thanks in the form of up-voting and or accepting a given answer because it solved the problem or was the most helpful in finding a solution. Sep 11, 2016 at 1:12
  • Thanks for the info. Yes, I did up vote but since I'm a noob it wouldn't show it publicly. I did look for the button to accept your response as the answer, but obviously I missed it. I'll look again and figure it out. Thanks for the guidance :)
    – mvern
    Sep 11, 2016 at 1:16
  • @mvern, I've edited the answer to reflect what was part of the originally tested and written code which had it as ... alias list. Sorry for any confusion it may have caused. Sep 11, 2016 at 1:20
0

@user3439894 deserves the credit for answering this.

The code proposed by user3439894 was:

tell application "Finder"
activate
set parentFolder to (choose folder) as alias
set theFolders to every folder of entire contents of parentFolder as alias
set theFolders to {parentFolder} & theFolders    
repeat with eachFolder in theFolders
    open eachFolder
    delay 0.5
    activate eachFolder 
    tell application "System Events"
        keystroke "2" using {control down, command down} 
        keystroke "1" using {control down, option down, command down}    
    end tell
    close eachFolder
end repeat
end tell

This did not work as written and returned the following error: enter image description here

So, not being an Applescript expert I messed around a little bit with the 4th line of code:

set theFolders to every folder of entire contents of parentFolder as alias

and changed it to this:

set theFolders to every folder of entire contents of parentFolder as list

and it worked!

A few comments about this. I used it to modify the viewing arrange/sort parameters of thousands of folders - most of which I don't look at, but since it was automated and easy, why not. I ran it with a delay of 0.1 instead of 0.5 and it worked fine. I did not try it without a delay. The only kink I ran into was there seemed to be some kind of cumulative black hole associated with the code. When I ran it on my directory that had thousands of sub-folders, it took nearly 7 hours to complete the operation. My MacBook fan kicked in as the CPU temperature rose drastically. Strangely, the time required to execute each set of keystrokes somehow increased with time - it literally just got slower and slower. I was not able to do any diagnosis since the routine was not running in the background, but actually running as if I was doing it manually. I let it run overnight and found that my computer was still sluggish i.e. all programs ran slow and the little spinny wheel popped up for the simplest of tasks. I did manage to open Activity Monitor and noticed that the WindowServer process was using some ~130% of the CPU - how that is possible, I do not know, but that is what it said. So I rebooted and the problem went away. Here is a screenshot of the Automator summary shown at the end of the process:

enter image description here

Like I said, just under 7 hours. But it was worth it! If I were to do it again I would run it only on the parent directories that I access with some regularity. Now I can finally get back to what I was intending to do in the first place before I found this "problem" :) Malcolm in the Middle: Hal tries to change a light bulb

2
  • That was accidentally left off between my copy and paste when editing my original answer, sorry, But as you can plainly see I did say "If you're wanting to act only on the top level sub-folders within the parent folder, then in place of: set theFolders to every folder of entire contents of parentFolder as alias list below the code block. Sep 11, 2016 at 1:15
  • Sorry for any confusion it may have caused. Sep 11, 2016 at 1:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .