To wait a file to be created, with a timeout, and a error message

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.

Download : PathMonitor

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?

Here is your original script modified…

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."
1 Like

Thanks @all for your explanations et solutions!

@StefanK, I’m not sure to understand how to implement that: how PathMonitor will notify my script?

@robertfern, it seems to work!

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?

:slight_smile:

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.

What method are you using to move the image file?

I would have the script get the size of the file and once it has stopped increasing, then copy it because it probably means it’s done being saved.

or

You can try using this busy status properly

busy status of (info for file SetPNG)

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)

Like so…

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
1 Like

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.

New link: PathMonitor

Thanks @all for your help and suggestions :slightly_smiling_face:

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!

I have questions.

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.