in my AppleScript app, I have to wait for a file to be created by an another app, with a timeout (to not waiting for ever), and with an error message if the timeout is over.
I’ve tried that, but without success:
testing if the file exists is working well
the timeout doesn’t work : it repeat forever
the last try is the only way I found to show the message and quit. Better solution ?
set SetPNG to (DossierDeBase & "pdf-lightroom:set copie.png")
with timeout of 5 seconds
repeat
try
SetPNG as alias -- test if the file exist
exit repeat
on error
end try
end repeat
end timeout
try
SetPNG as alias
on error
display alert "The file has not been generated."
quit
end try
I wrote a tiny command line interface called PathMonitor which monitors a directory asynchronously.
The benefit is that you get notified rather than waiting for the result.
Put the executable somewhere for example into /usr/local/bin and use it
set setPNG to POSIX path of (DossierDeBase & "pdf-lightroom:set copie.png")
set theResult to do shell script "/usr/local/bin/PathMonitor" & space & quoted form of setPNG & space & 5
if theResult = "The request timed out" then
display alert "The file has not been generated."
quit
end if
You can omit the timeout value – the second parameter, the default value is 10.
If the executable is located somewhere else you have to adjust the path in the do shell script line.
The way timeouts work is a little different than you expect.
AppleScript by default waits two minutes from sending an AppleEvent to an application to get a reply. If the reply does not come within the default timeout of 2 minutes a timeout error is generated.
When you create a “With timeout of x seconds” block that means that every appleScript command that is sent from within that block (and that expects a reply) will time out if the reply does not come in x seconds. In your case the one command that’s being sent is the alias coersion. Since that usually takes less than 5 seconds and would error immediately, the timeout block is basically having no effect.
Perhaps you want to delay 5 seconds and try again?
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
set SetPNG to (DossierDeBase & "pdf-lightroom:set copie.png")
set startTime to current date
set noFile to true
repeat until ((current date) - startTime) > 5
try
SetPNG as alias -- test if the file exist
set noFile to false
exit repeat
end try
delay 1
end repeat
if noFile then display alert "The file has not been generated."
But now, I have a small additional problem: In fact, my script asks photoshop to generate images, one after the other: Every time an image is generated (file detected), the script copy it to another folder, then it ask to Photoshop to generate the next one. And so on.
But I have a problem with this file detection: the script detects the file, and copies it, even before photoshop has finished writing the file! So he often copies an incomplete and illegible file.
The first solution would be in the @robertfern script to put a longer delay, like 10 seconds. But it will dramatically slow down the process: some images are generated in 0.5 seconds, and others in 5 seconds. Do you have an idea to detect as soon as the file is finished being generated?
The script waits for theResult but without polling. The script continues immediately right after the file has been created (or the timeout value has been reached).
Have you tried using folder actions? My own (limited) experience with them suggests that the action waits for a file to be completed before beginning the move. For example, when zipping a large folder that takes multiple seconds to complete, the move occurs about a second after the zipping has finished.
If busy status from info doesn’t work (and that depends on the app that’s writing to the file, you can also do a repeat loop checking he size of the file, and consider it done if it remains unchanged for 3 seconds (more or less, depending on the app an whether it’s local or network)
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
set SetPNG to "Ventura SSD:Users:robert:Desktop:HSB.pdf"
try
SetPNG as alias -- test if the file exist
set noFile to false
--exit repeat
end try
set startTime to current date
set noFile to true
repeat until ((current date) - startTime) > 5
try
SetPNG as alias -- test if the file exist
set noFile to false
exit repeat
end try
delay 1
end repeat
if noFile then
display alert "The file has not been generated."
else
set prevSize to size of (info for file SetPNG)
set c to 0
repeat until c = 3
delay 1
set currSize to size of (info for file SetPNG)
if prevSize = currSize then
set c to c + 1
else
set prevSize to currSize
set c to 0
end if
end repeat
end if
Update: I modified the PathMonitor command line tool a bit. Now it returns a message on success and throws an error on failure.
It became also a full fledged command line tool with a man page. Further it checks if the file already exists, and the timeout value is now an option which must be specified with the -t switch
set setPNG to POSIX path of (DossierDeBase & "pdf-lightroom:set copie.png")
try
set theResult to do shell script "/usr/local/bin/PathMonitor" & space & quoted form of setPNG & space & "-t 5"
on error e
display alert e buttons {"Cancel"} default button 1
end try
To clearify the difference between a repeat loop (polling) and this command line tool:
The command line tool uses an event handler, a callback, which is called by the framework when a file is added or modified in the parent directory of the passed path.
Urgently, and before I could read and test your suggestions, I asked photoshop to write an additional small file at the end of all these operations. And it’s this small file that I’m testing. As soon as I have time, I will optimize my code by trying PathMonitor. Thank you!
What version of Photoshop are you using? Are you automating Photoshop with actions or with another script?
Here, Photoshop 2024 is saving temp files the the same location as the original and, if successful, deleting the original and renaming the temp to the original name. This is easy to test for. Does this not happen for you?
I’m using the Photoshop 2024 (25.11.0). Yes, I’m automating it with actions. More specifically, I’ve created droplets based on actions, and launching those droplets using Applescript.
And when using “Save a copy”, here, it seems to write directly the final file.