2012-05-03 9 views
5

Nella mia app, mi piace che il Finder OSX copi un file o una cartella.Copia gli elementi tramite Finder e Applescript: come ottenere "l'elemento esiste - sostituire?" dialogo in Finder?

(. Nota: Ho buone ragioni per usare il Finder invece di utilizzare cmds shell, NSWorkspace o altri mezzi, quindi non c'è alcun bisogno di suggerimenti in questa direzione)

Attualmente sto contando su Applescript per chiedendo al Finder di eseguire l'operazione di copia. Ecco un esempio di script per il test:

tell application "Finder" 
    try 
     copy file POSIX file "/etc/bashrc" to folder POSIX file "/private/tmp" 
     -- alternative with same behavior: 
     --duplicate POSIX file "/etc/bashrc" to POSIX file "/private/tmp" 
    on error errmesg number errn 
     display dialog "Error thrown: " & errmesg 
    end try 
end tell 

Ora il problema è questo: Se l'elemento di destinazione esiste già, lo script genera un errore e annulla l'operazione di copia.

Tuttavia, avrei preferito visualizzare il Finder del "elemento esiste" dialogo che mostra quando si fa una tale operazione di copia nel Finder in modo interattivo, come questo:

Finder "item already exists" warning

Ora , ecco il punto: Se eseguo questo script dall'app di terze parti Script Debugger, viene visualizzata questa finestra di dialogo!

Quindi, ovviamente, c'è un modo per far sì che il Finder visualizzi la finestra di dialogo anziché lanciare un'eccezione. Ma come? Chi conosce il segreto di questo?

+0

È possibile verificare se il file di destinazione esiste prima e gestire questo caso da soli? –

+0

Paul - Certo che potrei, ma non è rilevante per questa domanda o per la situazione che devo risolvere. –

+0

Scusa - Ho pensato che potrebbe essere una soluzione pragmatica se non c'è modo di ottenere il comportamento richiesto dal Finder. –

risposta

0

Sembra che in realtà non sia possibile ottenere che Finder mostri la finestra di dialogo quando si utilizza AppleScript, almeno quando lo script viene eseguito nel suo ambiente normale. Nel mio test, sia di file Finder 's e eventi di sistema' move comanda costantemente errore fuori quando il bersaglio è già presente - con l'unica differenza, oltre la semantica, che Finder offre un interruttore replacing per sopprimere questo comportamento con true il che significa che il file di destinazione verrà sovrascritto senza chiedere conferma, ma non è possibile impostarlo su ask (vedere this MacScripter thread per una discussione della stessa identica domanda).

Senza la conoscenza duro dei suoi meccanismi interni, posso azzardare solo l'ipotesi il fatto Script Debugger gestisce in modo diverso è più probabile a causa di essa non l'esecuzione di script in ambiente normale. È difficile immaginare come si possa collegare al funzionamento interno di uno script per svolgere il proprio lavoro come debugger senza creare il proprio livello di esecuzione dello script. Un tale livello intermedio potrebbe spiegare perché i comandi vengono inoltrati in modo diverso alle applicazioni - nel caso di Finder e move, alle routine di copia Finder di basso livello, che mostreranno la finestra di dialogo.

Che ti lascia re-implementando questa funzionalità da solo, as suggested by Paul R, o passando a AppleScript-ObjectiveC (non la mia area di competenza, temo).

+0

Ho anche inviato una domanda a Latenightsw su questo. Forse possono dirmi cosa sta succedendo. Ancora in attesa di un anwser, però. Qualche tempo fa ho anche pubblicato una domanda in cui SD ha fatto qualcosa di molto più intelligente rispetto al resto, e la gente ha suggerito che SD ha fatto qualcosa di non rilevato. Si è scoperto che era conforme alle API ufficiali, alla fine. Quindi mi fido che SD in questo caso giochi anche secondo le regole. Dovrei anche sottolineare che sto eseguendo il test in SD in modalità non-debug. Vedremo ... –

+0

BTW, ho anche guardato gli Eventi di AE - sembrano essere gli stessi tra SD e l'editor di Apple. Forse è un ambiente ambientale che non riesco a vedere in questo momento, come quella SD è stata costruita contro un SDK più recente, abilitando questa funzionalità in modo automatico (ho visto cose del genere prima su OSX). –

+0

@ThomasTempelmann: oh, non vorrei suggerire che SD faccia qualcosa di non documentato - solo che il fatto che si interpone tra lo script e il sistema degli eventi potrebbe causare il fatto che alcune chiamate vengano tradotte in modo diverso (anche se sembra improbabile se si ottiene lo stesso AES). Ad ogni modo, mi piacerebbe sentire la loro risposta se ne prendi una - sarebbe bello avere un modo per ottenere il comportamento che cerchi. – kopischke

-1

Questo può essere in ritardo, ma se si elimina il file prima di copiare questo è lo stesso di sostituzione:

tell application "System Events" 
    if exists file ("NewFilePath") then 
     delete file ("NewFilePath") 
      -- NewFilePath Is where the file will end up or already is 
    end if 
end tell 
tell application "Finder" 
    try 
     copy file POSIX file "FilePath" to folder POSIX file "FolderPath" 
     -- FilePath is where it is now 
     -- FolderPath is the path of the folder you want the file in 
    on error errmesg number errn 
     display dialog "Error thrown: " & errmesg 
    end try 
end tell 

e dal momento che non c'è nessun scelta tra sostituire o interrompere Finder non dovrebbe portare un tale finestra

+0

Ma io _want_ la finestra di dialogo "sei sicuro" apparirà quando necessario, in modo che l'utente possa scegliere se sostituire l'elemento esistente. E aggiungere il mio assegno personale e quindi mostrare il mio dialogo personale non è fattibile per altri motivi che non posso spiegare in poche parole. –

1

Bene, per le mie esigenze ho trovato una soluzione: invece di utilizzare un AppleScript, ho bisogno di utilizzare direttamente l'API AppleEvents.

Lì, posso fornire i valori kAEAlwaysInteract | kAECanSwitchLayer al parametro SendMode di AESend. Questo fa apparire le finestre di dialogo nel Finder (e anche in questo caso deve portare in primo piano il Finder).

Per qualcuno che fa affidamento su AppleScript, tuttavia, questa non è una soluzione, sfortunatamente.