Ich habe eine ziemlich komplexe Aufgabe zu lösen. Ich benutze kein OS X, aber jetzt muss ich einigen Kollegen eine einfache Anwendung zur Verfügung stellen, die automatisch eine bestimmte Datei in einen Netzwerkordner kopiert. Normalerweise würde ich ein Shell-Skript verwenden, aber eine minimale GUI ist in diesem Fall ein Muss. Also dachte ich, ich könnte AppleScript verwenden.
Ich müsste diese Schritte ausführen:
smb://myserver/public
, wo jeder Benutzer unterschiedliche Anmeldenamen und Kennwörter hat, sodass die Verknüpfung der Benutzernamen und Kennwörter im Code keine Option ist).Beim Ausführen des Skripts muss der Benutzer also seinen Benutzernamen und sein Passwort eingeben, um sich mit dem Netzlaufwerk zu verbinden, und der Benutzer muss den Namen des Ordners eingeben, in den er die Datei kopieren soll. Kann der Name des Ordners irgendwie dauerhaft gespeichert werden? Der Benutzer muss also nicht jedes Mal den Ordnernamen eingeben, wenn er oder sie dieses Skript ausführt. Aber von Zeit zu Zeit können sich diese Ordner ändern, daher muss es eine Option geben, den Ordner vor dem Kopieren zu ändern. Wie kann ich auch überprüfen, ob das Netzlaufwerk bereits gemountet ist, damit der Benutzer nicht jedes Mal nach Benutzername und Passwort gefragt wird, wenn er oder sie dieses Skript ausführt?
Hier ist, wie weit ich beim Zusammenstellen eines Skripts gehen konnte, um diese Aufgabe zu erfüllen:
Ich habe Mühe zu verstehen, wie AppleScript einen Pfad zu einer Datei/einem Ordner auf einem bereitgestellten Netzlaufwerk speichern möchte.
Also hier ist was ich jetzt habe:
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()
Das Kopieren von Dateien in Applescript erfolgt am besten entweder über Systemereignisse oder Finder mit dem duplicate … to
Befehl, dh
tell application "System Events" to duplicate sourceFile to targetFolder
wobei sowohl sourceFile
als auch targetFolder
der richtige Objekttyp für die verwendete Anwendung sein müssen – also Disk-Element oder Finder-Element (beide Objekte können aus AppleScript- Alias- Objekten oder Textpfadwerten mit etwas Typzwang erstellt werden – würde ich die Details hinzufügen, aber Sie haben nicht angegeben, wie die Pfade zu beiden in Ihrem Skript gespeichert / erfasst werden).
Ein paar Anmerkungen zu deinem Code:
missing value
, können Sie sogar überprüfen, ob sie bereits festgelegt sind, und die erneute Aufforderung des Benutzers überspringen (es gäbe eine noch bequemere und sicherere Lösung, wenn Apple das Schlüsselbundzugriffs-Skripting nicht als veraltet markiert hätte).Die wiederholten Zuweisungen und rekursiven Aufrufe in Ihrem Handler sind nicht erforderlich connectToServer()
. Der folgende Code
set timeOutCounter to 0
repeat while (list disks) does not contain serverName and timeOutCounter is less than timeOutInterval
-- mount drive
delay someInterval -- recommended, so you don’t hectically loop
set timeOutCounter to timeOutCounter + someInterval -- time out loop
end repeat
wird versuchen, sich in dem durch definierten Intervall zu verbinden someInterval
, bis der Mount verfügbar oder timeOutInterval
erreicht ist (vorausgesetzt, diese Werte sind deklariert. Als Eigenschaften, am besten – siehe oben).
choose folder
für den Befehl an.display dialog
Befehl lieber in einen eigenen Handler verschieben und diesen bei Bedarf wiederholt aus dem Skriptkörper aufrufen, als einen mainLoop
Handler im C-Stil zu verwenden. Ich habe festgestellt, dass AppleScript im Allgemeinen bei Rekursion leicht den Stapelplatz ausgeht und sehr verwirrt über Variablenzuweisungen werden kann. Daher ist es eine gute Idee, rekursive Konstrukte zu vermeiden, wenn sie nicht erforderlich sind.delay
Maßnahmen in Sekunden.delay
misst in Sekunden. Sie müssen ein wenig auf verschiedenen Systemen testen – ich würde empfehlen, Ihr Timeout auf das Eineinhalbfache bis Zweifache der langsamsten Verbindungszeit einzustellen, die Ihnen begegnet, und Ihre Verzögerung auf etwa die schnellste Verbindungszeit, die Ihnen begegnet.
Fahrrad
kopischke