Relative file paths with Applescript - applescript

I'm trying to make an Applescript that will open a file on a user's computer without knowing the hard drive or user name, presuming the file is in the same place in the user directory.
tell application "Finder" to open "/Users/jim/Dropbox/Getting Started.pdf" as POSIX file
works great, whereas
tell application "Finder" to open "~/Dropbox/Getting Started.pdf" as POSIX file
fails.
Is there any way to accomplish this simply?

You can't use tilde paths in AppleScript basically because POSIX file is in fact an URL. URLs for file paths doesn't support incremental paths, only absolute paths. But the meaning of the tilde in POSIX paths is not something special, it's just replaced by the home folder. SO to get the same results we only need to change your code to:
tell application "Finder" to open (POSIX path of (path to home folder)) & "Dropbox/Getting Started.pdf" as POSIX file

To accomplish this, you could use a shell script instead of tell application "Finder", or you could use a shell script to get the home folder and insert it into your tell block.
To use a shell script, you can use the following code: do shell script "open ~/Dropbox/Getting\\ Started.pdf. To insert a shell script into your Finder tell block, you could use this code: tell application Finder to open (do shell script "echo $HOME") & "/Dropbox/Getting Started.pdf". This uses a shell script to print the path to the logged in user's home directory and uses it in the path you give Finder.
I hope these suggestions help you solve your problem! ✌️ 🇺🇦

Related

How to open an EMACS file in OS X by double-clicking on it, using the `emacsclient` command?

I want to open an org-mode file selected in the Finder, by double clicking on it. But since I use Emacs in daemon-mode, I want to use the emacsclient command for that.
Thus the primary idea was to wrap the command emacsclient -c posixPathToFile in an AppleScript App to open it.
tell application "Finder"
set fileAlias to the selection as alias
set fileName to name of fileAlias
set posixPath to POSIX path of fileAlias
end tell
-- tell application "Emacs" to activate
try
do shell script "/usr/local/bin/emacsclient -c " & quoted form of posixPath
end try
I know some set commands are not needed. Let's assume this script is saved as Xemacs.app and that I associate this app to always open .org file.
Using this App does not work by double-clicking on the file, but rather if I select the file in the Finder and then call the Xemacs.app independently. Why ? I'm not confident enough with AppleScript to figure out what happens.
So the workaround was to use the Automator service
on run {input, parameters}
set posixPath to POSIX path of input
tell application "iTerm" to do shell script "/usr/local/bin/emacsclient -c " & quoted form of posixPath
return input
end run
The service is saved as 'Open in Emacs'
Now selecting a file and right-clicking and callig Service > "Open in Emacs" works and opens the file.
What is wrong with the first approach ?
ok, I solved my issue. The problem comes from my misunderstanding of the difference between ScriptEditor and the Automator. If I use the Automator to create an App and use the former script instead of creating an App using the ScriptEditor, then it works as expected.
One can simplify the process by creating an App in Automator and running a shell script instead of wrapping the command in Ascript.

How to debug droplets using AppleScript

Just 3 lines of script to be able to test a droplet application without leaving applescript editor
set fich to POSIX file "/Appli/conv2spct.app" as string
tell application "Finder" to open POSIX file "/Users/yourusername/Desktop/somefile" using application file fich
If there are errors in your droplet a display dialog will be opened by the script editor applescript
The same script with choose file for the 2 elements
set fileappli to POSIX path choose file of type {"APPL"} with prompt "Choose a Droplet application to debug"--the droplet for debug
set fileargument to POSIX path choose file --the file argument to pass at droplet
tell application "Finder" to open fileargument using application file fileappli
If there are errors in your droplet a display dialog will be opened by the script editor applescript
Here's a pragmatic alternative using do shell script, which potentially allows you to specify multiple file arguments:
do shell script "open -a /Appli/conv2spct.app ~/Desktop/somefile1 ~/Desktop/somefile2"
The above paths happen not to need quoting (escaping) for the shell, but when using variables to specify the file paths, it's best to use quoted form of (to pass multiple arguments, apply quoted form of to each):
do shell script "open -a " & quoted form of fileappli & " " & quoted form of fileargument
Looks like this has become simpler since the question was first asked. According to this documentation you can write:
open {choose file}
on open theDroppedItems
...
end open
Run this from within the AppleScript editor and the file you choose will be opened as if it had been dropped onto the compiled script.

Run several Applescripts from within current script

I'd like to expand my existing...
run script file "Macintosh HD:Users:pathTo:myScript.scpt"
to run all scripts found in a given directory. I've tried...
tell application "Finder" to set scriptsToRun to files of folder POSIX file "/Users/pathTo/" as alias list
run script file scriptsToRun
but no luck with that. Also unless necessary I don't particularly need to involve Finder in my equation. Any suggestions appreciated.
scriptsToRun is a list, so you need to repeat over the list and run each one separately. Notice I used parenthesis to ensure the code is interpreted correctly in the Finder line.
Also notice you don't need "file" in the "run script" line because the list of files is already a list of alias files... from the Finder line. You would only need the word "file" if you had a list of files in string format, then you'd use "file" before each string to make it a file specifier before running it.
Good luck.
tell application "Finder" to set scriptsToRun to (files of folder POSIX file "/Users/pathTo/") as alias list
repeat with aScript in scriptsToRun
run script aScript
end repeat

Applescript run bash script from same directory

I'm trying to build an AppleScript to launch my shell script.
Path structure is as follows
/Users/ryan/myscript/
applescript.scpt
bash.sh
My AppleScript is as follows:
tell application "Terminal"
set folder_path to path to me
set run_cmd to "/bin/bash " & folder_path & "/bash.sh"
do script run_cmd
activate
end tell
Problem is the 'path to me' is not always returning the correct path. When executed using the Mac cd/dvd autoplay behavior folder_path is equal to:
disk:System:Library:CoreServices:SystemUIServer.app:Contents:XPCServices:com.apple.systemuiserver.scriptrunner.xpc:
Is there is a better way of getting the folder path?
If this Script is in a static location, you can do this:
do shell script "/bin/bash" & POSIX path of (path to current user folder) & "myscript/bash.sh"
Path to me refers to the location of the applescript that is running. So if your script is on a disk then it will reference the location on the disk where the script is saved
if it is expected that the shell script will always exist in a folder called "myscripts" that exists in the current user folder then you could use path to current user folder and build out from there
set user_folder to path to current user folder
set folder_path to quoted form of POSIX path of (("" & user_folder & "myscript"))
tell application "Terminal"
activate
set run_cmd to "/bin/bash " & folder_path & "/bash.sh"
do script run_cmd
end tell
Is there a reason why you have to store the shell script in a separate file? Typically, you would put it inline, within the AppleScript code. As far as I know, the “do shell script” command only operates on text, not on a script at a file path. If you give it a variable that contains a path, it will try to run that path as a command. It won’t run the contents of the file as a command.
Here is an example of an AppleScript that runs an inline shell script and puts the results in TextEdit:
property theShellScript : "#!/bin/bash
echo Hello World"
tell application "TextEdit"
activate
set theScriptResult to do shell script theShellScript
make new document
set the text of document 1 to theScriptResult
end tell
… you can of course replace the above shell script with the contents of your own shell script.
If you do need to keep the script in a separate file, the best way to do that is probably to save your AppleScript as an Application, and put the shell script within the Application bundle. “Path to me” is the path of the application that is running the script — not to the script itself — but if you save your AppleScript as an Application, then it runs its own script, and “path to me” works as you originally expected.
Here is an example of an AppleScript that runs a shell script contained within a file that is stored within its own application bundle:
property theApplicationPath : the path to me as text
property theShellScriptPath : theApplicationPath & "Contents:Resources:Scripts:bash.sh"
tell application "TextEdit"
open alias theShellScriptPath
set theShellScript to the text of document 1
set theScriptResult to do shell script theShellScript
make new document
set the text of document 1 to theScriptResult
end tell
With the above script Copy/Pasted into a new document in AppleScript Editor, hold down the Option key and choose File ▶ Save As, and in the Save dialog box, on the File Format pop up menu, choose “Application” and of course give your application a name and click Save. Then in Finder, navigate to where you Saved your application, and 2-finger tap (or right-click) on your application and choose “Show Package Contents.” That opens your application up as a folder, exposing the file system within. Put your shell script file named “bash.sh” inside the folder “Contents/Resources/Scripts” within your application and then close the window that represents your application.
Now when you run your application from anywhere in the file system, it will still be able to find and run its incorporated shell script.

OS X 10.9 Applescript changes: using the `move` command in the "System Events" context to move a file

I went to run an old script and it broke after the 10.9 update. I used to move files with system events with the following code.
set Somefilepath to "Design_005_HD:Users:Design_005:Desktop:Start:TextFile.txt"
set somefolderpath to "Design_005_HD:Users:Design_005:Desktop:End:"
tell application "System Events"
move file (Somefilepath) to folder (somefolderpath)
end tell
Now it gives me the following error.
error "System Events got an error: Can’t make file
\"Design_005_HD:Users:Design_005:Desktop:Start:TextFile.txt\" into
type integer." number -1700 from file
"Design_005_HD:Users:Design_005:Desktop:Start:TextFile.txt" to integer
I know I can swap it out and use finder but I rather not use it. What changed that is no longer works?
Update 4/2/14
I have tried this in every way of giving the file/folder location to system events and it doesn't work. I am glad it is just not me who cannot get it to work. I will update this post if I find an answer or a working update is made.
Update 4/3/14
It seems this is just a bug that system events can't move files. I have reported it here http://bugreport.apple.com/ and everyone else should too.
Please do not take my code to heart, it is just where things ended up when I couldn't get it to work. I have working code for 10.8.5 and it is what is shown above minus the folder tag in the system events tell block. No idea why it works with out the folder tag but it does. Tested on multiple comps. If it isn't broken don't fuss over it. Noted it and moved on.
Update 10/20/14
For anyone interested. I have received an e-mail stating my ticket has been closed/resolved. So mavericks will for ever be broken but there might be light for Yosemite when it comes out.
In general, Applescript works with colon delimited paths (:) not slash delimited paths (/). I say in general because some applications will work with slashes but all programs will work with colons. For an example of what the colon paths look like try this code and look at the result...
set colonPath to (path to desktop as text) & "untitled folder 2:"
So first I would convert your slashes to the colon style.
Also to applescript these are just strings not paths. To make applescript understand they are paths we can do a few things. First you can add the words file or folder in front of them as appropriate. I notice in your code you are using "file" in front of the file string but you aren't using "folder" in front of the folder string. So try that. Second you can just use "alias" in front of the strings whether they're files or folders. There are other ways as well but I'll stop here. Either of those ways should work.
UPDATE: with all of the above being said, it seems System Events in 10.9 still has trouble with the move command. As such here's 2 alternatives for you. I used slash style paths since that's what you're using.
set somefilepath to POSIX file "/Users/Design_005/Desktop/Start/TextFile.txt"
set somefolderpath to POSIX file "/Users/Design_005/Desktop/End"
tell application "Finder"
move somefilepath to somefolderpath
end tell
or
set somefilepath to "/Users/Design_005/Desktop/Start/TextFile.txt"
set somefolderpath to "/Users/Design_005/Desktop/End"
do shell script "mv " & quoted form of somefilepath & space & quoted form of somefolderpath
Good luck.
You can’t do that. System Events can delete and open, but not move. Here’s a simple example in case it helps someone else find a better answer in a future OS. System Events appears to treat move differently than delete and open.
tell application "System Events"
set myFile to file "Macintosh HD:Users:velma:Desktop:Test.png"
set myFolder to folder "Macintosh HD:Users:velma:Desktop:Test"
--delete works! with both type “file/folder” and type “disk item”
--delete myFile
--delete myFolder
--open works!
open myFile
open myFolder
--move fails!
move myFile to myFolder
end tell
The error it’s returning, in this case, is “Can’t get file”, number -1728.
There appears to be bug in the move command in the "System Events" context in OX 10.9 (and possibly 10.8).
The workaround is the to use the "Finder" context instead:
Using HFS-style paths (separator is :)
set somefilepath to "Design_005_HD:Users:Design_005:Desktop:Start:TextFile.txt"
set somefolderpath to "Design_005_HD:Users:Design_005:Desktop:End:"
tell application "Finder"
move file somefilepath to folder somefolderpath
end tell
Using POSIX-style paths (separator is /) - as in the original question
set somefilepath to "/Users/Design_005/Desktop/Start/TextFile.txt"
set somefolderpath to "/Users/Design_005/Desktop/End"
# Note that we use `as POSIX file` even in the case of the *folder*
# - this works, however.
tell application "Finder"
move somefilepath as POSIX file to somefolderpath as POSIX file
end tell
Note:
as POSIX file returns a file object in both cases, but Finder still handles the move properly - it is fine to use POSIX file with both files and folders.
Note that using the prefix form of POSIX file- e.g., POSIX file "/Library", only works with a path string literal; if you try to build the path string as an expression, it breaks (in the "Finder" context, but NOT in the AppleScript context(!)): POSIX file ("/" & "Library") - by contrast, "/" & "Library" as POSIX file works (in both contexts) - go figure. To be safe, always use the postfix form: ... as POSIX file
A downside of using as POSIX file - at least as of OS X 10.9 - is that the error messages are cryptic if a file/folder doesn't exist: you'll see Finder got an error: Handler can’t handle objects of this class. and Finder got an error: AppleEvent handler failed. - both with number -10000.
(Using folder directly with a POSIX path, as in an earlier version of the question - e.g., folder "/Library" - ONLY works in a "System Events" context, and is therefore NOT an option in the "Finder" context.)
As for what changed in AppleScript OS X 10.9:
The behavior you see appears to be a bug (also see #Jerry Stratton's answer); nothing in the AppleScript release notes for 10.9 indicates a change in that area.
I now think that the problem affects OS X 10.8 as well.
I encourage you to submit a bug report to Apple at http://bugreport.apple.com, as I already have.
Sadly, handling files, folders, and aliases in AppleScript has always been a mess, with confusion stemming from classes of the same name from different dictionaries (AppleScript itself, System Events, Finder) with subtly different behavior.
A general recommendation: for file-system manipulation, use the tell application "Finder" context.
The "System Events" dictionary, in its Disk-Folder-File Suite, duplicates some of Finder's file-system manipulation functionality, but only some - a curious omission is a file copy command, for instance.

Resources