Automatisches Mounten eines Netzlaufwerks und Kopieren einer Datei in einen Netzwerkordner (AppleScript)

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:

  1. Stellen Sie eine Verbindung zu einem Netzlaufwerk her ( 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).
  2. Navigieren Sie zu einem Ordner auf dem Netzlaufwerk (jeder Benutzer hat einen anderen Ordner auf dem Netzlaufwerk).
  3. Kopieren Sie eine bestimmte Datei vom Desktop des Benutzers in den geöffneten Ordner auf dem Netzlaufwerk.

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()
Ich habe mit einem Moderator von SO gesprochen und wir würden das beide gerne noch ein bisschen hier lassen, um zu sehen, ob wir dir eine Antwort geben können. Ich werde die Frage vorziehen, damit sie ganz oben in unserer Warteschlange steht. Mal sehen, wie die Dinge laufen, und Sie können dies gerne noch einmal melden, wenn Sie wirklich der Meinung sind, dass es verschoben werden sollte.
Nun, du hast eine Antwort … stimmt etwas nicht damit, dass du das Bedürfnis nach SO verspürst? Ich frage nur, ich würde mich freuen, es zu verbessern :):

Antworten (1)

Das Kopieren von Dateien in Applescript erfolgt am besten entweder über Systemereignisse oder Finder mit dem duplicate … toBefehl, dh

tell application "System Events" to duplicate sourceFile to targetFolder

wobei sowohl sourceFileals auch targetFolderder 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:

  • Es besteht keine Notwendigkeit, Globals zu verwenden, wenn Sie sie bereits als Eigenschaften definiert haben. AppleScript-Eigenschaften sind skriptbezogen und bleiben während der Ausführung bestehen – sie werden nur zurückgesetzt, wenn das Skript neu kompiliert wird. Wenn Sie diejenigen zuweisen, die beim Deklarieren eine Benutzereinstellung benötigen 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 timeOutIntervalerreicht ist (vorausgesetzt, diese Werte sind deklariert. Als Eigenschaften, am besten – siehe oben).

  • Möglicherweise möchten Sie Ihrem Benutzer auch eine bequemere Möglichkeit bieten, den Zielordner auszuwählen, als einen Ordnernamen aus dem Gedächtnis einzugeben. Sehen Sie sich das AppleScript-Wörterbuch von Standard Additionschoose folder für den Befehl an.
  • Schließlich, aber das ist hauptsächlich eine Frage des Geschmacks und des Programmierstils, würde ich den display dialogBefehl lieber in einen eigenen Handler verschieben und diesen bei Bedarf wiederholt aus dem Skriptkörper aufrufen, als einen mainLoopHandler 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.
Danke für die Antwort. Irgendwelche Ratschläge, wie man ein Timeout einstellt? Wie oft sollte ich prüfen, ob das Netzlaufwerk gemountet ist? Ich nehme an, delayMaßnahmen in Sekunden.
@szantaii: ja, delaymisst 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.