I've a rather complex task to solve. I don't use OS X, but now I have to provide some colleagues with a simple application that automatically copies a certain file to a network folder. Normally I'd use a shell script, but some minimal GUI is a must-have thing in this case. So I thought I could use AppleScript.
I'd have to perform these steps:
- Connect to a network drive (
smb://myserver/public
, where every user has different login names and passwords, so wiring the usernames and passwords in the code is not an option). - Navigate to a folder on the network drive (every user has a different folder on the network drive).
- Copy a certain file from the user's desktop to the opened folder on the network drive.
So when running the script the user has to enter his or her username and password for connecting the network drive, and the user has to enter the name of the folder they should copy the file to.
Can the name of the folder be stored permanently somehow? So the user won't have to enter the folder name each time when he or she runs this script. But from time-to-time these folders may change, so there has to be an option to change the folder before copying.
Also how can I check if the network drive is already mounted, so the user won't be asked for username and password each time he or she runs this script?
Here is how far I've been able to go in assembling a script to accomplish this task:
I'm struggling to understand how AppleScript likes to store a path to a file/folder on a mounted network drive.
So here is what I have now:
property userName : "myfolder"
property folderName : "myusername"
property serverName : "public"
property serverAddress : "smb://myserver/public"
property serverStatus : 0
on connectToServer()
global userName
global folderName
global serverName
global serverAddress
global serverStatus
set mountedDisks to list disks
if mountedDisks does not contain serverName then
mount volume serverAddress as user name userName with password (display dialog "Enter password for" & quoted form of serverName with title "" default answer "" giving up after 3 with hidden answer)
end if
set mountedDisks to list disks
if mountedDisks contains serverName then
set serverStatus to 1
else
connectToServer()
end if
end connectToServer
on mainLoop()
global userName
global folderName
global serverName
global serverAddress
global serverStatus
if serverStatus is equal to 0 then
connectToServer()
end if
set mainDialog to display dialog ¬
"Your username: " & userName & "
Your folder's name: " & folderName buttons {"Quit", "Settings", "Copy file"} with title "File Copier" default button 1
set mainDialogAnswer to button returned of mainDialog
if mainDialogAnswer is equal to "Quit" then
quit
end if
if mainDialogAnswer is equal to "Settings" then
display dialog "Enter your username" with title "Step 1 of 2" default answer userName
set userName to {text returned of result}
display dialog "Enter your folder's name" with title "Step 2 of 2" default answer folderName
set folderName to {text returned of result}
mainLoop()
end if
if mainDialogAnswer is equal to "Copy" then
-- copy the file
end if
end mainLoop
mainLoop()
Best Answer
Copying of files in Applescript is best done either through System Events or Finder, using the
duplicate … to
command, i.e.where both
sourceFile
andtargetFolder
need to be the correct object type for the application used – meaning disk item or finder item (both objects can be created from AppleScript alias objects, or textual path values with a bit of type coercion – I’d add the details, but you have not stated how the paths to both are stored / acquired in your script).A few notes on your code:
missing value
when declaring, you can even check if they are already set and skip re-prompting the user (there would be an even more comfortable and secure solution if Apple hadn’t deprecated Keychain Access Scripting).There is no need for the repeated assignments and recursive call in your
connectToServer()
handler. The following codewill try to connect in the interval defined by
someInterval
, until the mount is available ortimeOutInterval
is reached (assuming these values are declared. As properties, best – see above).choose folder
command.display dialog
command into its own handler and call that, if needed repeatedly, from the script body, than use a C stylemainLoop
handler. I’ve found that, generally speaking, AppleScript runs out of Stack space easily when recursing and can get very confused about variable assignments, so it is a good idea to avoid recursive constructs where they are not necessary.