AppleScript choose file or folder - macos

can I use AppleScript to choose either file or folder in one time?
Now I could use
tell application "SystemUIServer" to return POSIX path of (choose file)
or
tell application "SystemUIServer" to return POSIX path of (choose folder)
to get file or folder. However I cannot get file or folder in one time.

No, you can't do it with "choose file" or "choose folder" verbs, but choosing a file or folder (or multiple files/folders) is supported by the underlying NSOpenPanel. So you can do it with AppleScriptObjC. Here's an example using ASObjCRunner (derived from here):
script chooseFilesOrFolders
tell current application's NSOpenPanel's openPanel()
setTitle_("Choose Files or Folders") -- window title, default is "Open"
setPrompt_("Choose") -- button name, default is "Open"
setCanChooseFiles_(true)
setCanChooseDirectories_(true)
setAllowsMultipleSelection_(true) -- remove if you only want a single file/folder
get its runModal() as integer -- show the panel
if result is current application's NSFileHandlingPanelCancelButton then error number -128 -- cancelled
return URLs() as list
end tell
end script
tell application "ASObjC Runner"
activate
run the script {chooseFilesOrFolders} with response
end tell
ASObjCRunner converts a NSArray of NSURL objects into an AppleScript list of files; the results can look something like:
{file "Macintosh HD:Users:nicholas:Desktop:fontconfig:", file "Macintosh HD:Users:nicholas:Desktop:form.pdf"}

Firstly, you don't need a tell for that.
POSIX path of (choose file)
Secondly, it is not clear why you need this. Do you mean you want to select a file and it's folder? That's not how you do it; you select the file then parse the file path for the containing folder or use one of the many methods to do that, like
set f to (choose file)
set posixF to POSIX path of f
tell application "Finder" to set filesDir to container of f as alias as text
set posixDir to POSIX path of filesDir
{f, posixF, filesDir, posixDir}
If you want to be able to select multiple folders and files at the same time, I don't think there is a "pure applescript" way to do this (aside from using a drag-drop aware script application).

Related

AppleScript - Copy All files/folders from source folder to destination folder

I'm trying to write an AppleScript that will simply copy the contents (both folders and files) from a specified source folder to a specified destination folder. At the moment my script runs but only copies one file and I can't work out how to get it to copy all files in the folder.
Here's my script:
set sourceFolder to (POSIX file "/Users/benny/Desktop/Projects/Source/Project1") as alias
set destinationFolder to (POSIX file "/Users/benny/Documents/Masters/Project1") as alias
tell application "System Events"
set availableSourceFiles to every file of sourceFolder whose visible is true
set filesOfTargetFolder to files of destinationFolder whose visible is true
end tell
-- if no more source file is available, quit this script
if (count of availableSourceFiles) = 0 then
quit
end if
set sourceFile to (first item of availableSourceFiles) as alias
-- use the Finder to copy the file
tell application "Finder"
-- duplicate the file to the target folder
duplicate sourceFile to destinationFolder
end tell
I'm assuming I need to include a for each type loop but can't get the syntax correct here. Haven't written AppleScripts in many years so trying to remember how it all works.
If the destination "Project1" folder doesn't have stuff in it already, then duplicating the folder is likely to be quicker:
tell application id "com.apple.Finder" to duplicate folder POSIX file ¬
"/Users/benny/Desktop/Projects/Source/Project1" to the folder ¬
POSIX file "/Users/benny/Documents/Masters" with replacing
However, if that's not an option, then I'd stick with your method and copy the contents of the folder across instead:
set here to POSIX file "/Users/benny/Desktop/Projects/Source/Project1"
set there to POSIX file "/Users/benny/Documents/Masters"
tell application id "com.apple.Finder" to duplicate ¬
every item in the folder here to there
Bear in mind that if there's a file or folder at any of the destinations that intended to be occupied by one of the incoming source items, Finder will throw an error. You would typically incorporate some sort of check ahead of the copy.

Selecting POSIX file based on file name

I'm having trouble accessing this file while trying to select it on the beginning characters basis...
set location to "/Users/myuser/Desktop/"
set bom to POSIX file (location & (first file of location whose name begins with "thisFile"))
tell application "Preview" to open bom
is it path/alias vs text type of a thing?
Only System Events and the Finder know what a file in the file system is.
The Finder has a property desktop which points always to the desktop of the current user.
tell application "Finder" to set bom to first file of desktop whose name begins with "thisFile"
tell application "Preview" to open (bom as alias)
Or with an arbitrary POSIX path
set location to POSIX file "/Users/myuser/Desktop" as text
tell application "Finder" to set bom to first file of folder location whose name begins with "thisFile"
tell application "Preview" to open (bom as alias)
The alias coercion is needed because Preview doesn't recognize Finder file specifier objects.
vadian's answer works well, but it's worth mentioning that:
you can get access to well-known folders even in the default context, outside the context of System Events and Finder; e.g.:
path to desktop
path to home folder
Use, e.g., POSIX path of (path to home folder) to get the POSIX path.
using context System Events is usually preferable to the Finder context, for reasons of both performance and predictability.
With an arbitrary target folder, using a POSIX path:
tell application "System Events"
set targetFolder to alias "/Users/jdoe/Desktop"
# equivalent of: set targetFolder to (path to desktop)
set targetFile to first file of targetFolder whose name starts with "thisFile"
end tell
tell application "Preview" to open targetFile
Alternatively, if you know your way around the shell, you could try:
set targetFilePosixPath to do shell script "fls=(~/Desktop/*.pdf); printf %s \"$fls\""
tell application "Preview" to open (POSIX file targetFilePosixPath as alias)

POSIX file works in tell block

The following works in Script Editor (or an Applescript App), but not in XCode:
tell application "Finder" to set folder_list to items of folder POSIX file "/Users"
Specifically, I get at runtime:
Finder got an error: Can’t make «class ocid» id «data optr000000002094230000600000» into type integer. (error -1700)
If I try "double coercion":
...((folder POSIX file "/Users") as POSIX file)
I get:
Can’t make «class cfol» «script» of application "Finder" into type POSIX file. (error -1700)
I did see something similar discussed here, but the solution did not work for me:
"POSIX file" works in Applescript Editor, not in XCode
Thanks!
//Reid
p.s. I know I could just use "Macintosh HD:Users"... This works, unless somebody renamed their hard drive.
Applescript has the "path to" command to find paths to well known folders, like a user's home folder, desktop, documents folder etc. That's the best way to access the folders. You can see all the locations applescript knows in the Standard Additions applescript dictionary for the "path to" command. It also knows where the users folder is. As such I would write your code like this...
set usersPath to path to users folder
tell application "Finder" to set folder_list to items of usersPath
You can try to smoothen it out yourself, as I suspect the AppleScript editor does for you:
tell application "Finder" to set folder_list to items of folder (POSIX file "/Users" as text)
What I did, was to coerce the posix file to text, otherwise it is of class furl which really isn't what Finder can take. I'd try to coerce your posix file statements to text, and see if that helps.
This compiles and runs, both from within my Editor, and from the script menu:
tell application "Xcode"
tell application "Finder"
set m to folder (POSIX file "/Users" as text)
set n to name of m
tell me to display alert n
end tell
end tell
I hope this helps.

TextExpander and AppleScript to get file path on Mac

I would like to create a TextExpander snippet that will prompt me to choose a file in the Finder and copy the file path to the text editor I am working in.
It should work like this:
I am working in NVAlt
I enter the TextExpander command (e.g. ;path)
I am prompt top choose a file
The file path is copied to the note I am working in.
I figured I'll do it using AppleScript, so I tried this:
set source_folder to choose file with prompt "Please select a file."
tell application "System Events"
set item_list to POSIX path of every disk item of source_folder
end tell
return "path:" & item_list
But it is not returning anything to the text note I am working in...
Any suggestion how I should do it?
PS: I used the POSIX command to the folder name as ".../.../.../" instead of "...:...:..."
There are multiple things wrong in the script but instead of trying to correct your script I've looked what textExpander tells me to do. On the help section about textExpander on smilesoftware.com site they say:
The script executes in the context of the TextExpander application.
The script can perform various actions, but the snippet will expand to
whatever text is returned.
When looking at the your goal you simply need to coerce the returned alias from the choose file command into a string and return that. So a single line like below should be enough to use to return an HFS path to a file
return choose file with prompt "Please select a file." as string
if you want to return the file path as POSIX Path you only need this:
return POSIX path of (choose file with prompt "Please select a file.")
If you want the path to be prefixed with "path:" like in your example code:
return "path:" & (choose file with prompt "Please select a file.")
NOTE: there is an implicit coerce of the choose file results, no explicit coercion is needed.
EDIT: I've downloaded textExpander myself and it seems that showing dialog in the context of textExpander will behave wrong. So what I did was looking up the front most application and showing the dialog there, it's also better looking. Then I tell that application explicitly to show the choose file prompt and return the result of the choose file prompt. Here is the code:
tell application "System Events"
set applicationName to (name of every process whose frontmost is true) as string
end tell
using terms from application "AppleScript Editor"
tell application applicationName
set expansionString to (choose file "Please select a file.") as string
end tell
end using terms from
return expansionString

Accessing folders in AppleScript

Sorry, complete beginner here with AppleScripting.
I'm trying to do a very simple thing, move files from one folder to another.
tell application "Finder"
set this_folder to "Users:chris.nicol:Movies:SmartConverter:"
set this_list to every file of this_folder
repeat with i in this_list
--if i does not start with "x" then
move i to "users:chris.nicol:music:itunes:itunes media:automatically add to itunes:"
--end if
end repeat
end tell
However I keep getting an error:
I've tried different commands (count, parentContainer, etc.) on the folder, but I get the same type of error. I've tried different formatting for the folder ...
Users/chris.nicol/Movies/SmartConverter/
Macintosh HD:Users:chris.nicol:Movies:SmartConverter
etc.
Any ideas on what I'm doing wrong?
Thanks in advance,
Chris
Simple tip... if you want to find the proper path you should use try this and look in the results field for the proper path. You'll see that the name of the hard drive, Macintosh HD, is required. Note you could use "choose file" as well if you wanted the path to a file.
(choose folder) as text
Next, the path that you will see is a string. Applescript sees it as a string not a path to a file or folder. As such, when you want to use the string as a path then you must put the word "file" or "folder" in front of it as appropriate to make applescript use it properly. Therefore your script should look like this. Note that the move command can handle a list of files so the repeat loop isn't needed.
set this_folder to "Macintosh HD:Users:chris.nicol:Movies:SmartConverter:"
tell application "Finder"
set this_list to every file of folder this_folder
move this_list to folder "Macintosh HD:Users:chris.nicol:music:itunes:itunes media:automatically add to itunes:"
end tell
Try:
set thisFolder to (path to movies folder as text) & "SmartConverter"
set thatFolder to (path to music folder as text) & "itunes:itunes media:automatically add to itunes"
tell application "Finder" to move files of folder thisFolder to thatFolder
You must have some invisible or otherwise uncopyable files in one of the folders. Either add something like without invisibles to the end of your set this_folder line, or get rid of your loop altogether and simply call
move files of entire contents of this_folder to (the Add Automatically folder)

Resources