Wait for external file to finish writing to disk

Let’s assume I download a file from the browser called “foo.exe” which is 1GB in size,
how can I make powershell wait untill the entire file has been completely downloaded?

I can’t use:

Start-Process -FilePath $foo -Wait

and I can’t use:

While (!(Test-Path $foo -ErrorAction SilentlyContinue)) {
}

and I can’t use:

Start-Sleep 60

(Because the time is a variable and is not consistent)

I may not be understanding so I want to clarify your desired outcome:

You are engaging in a download of a file via a web browser, but then are using PS to launch it? You’re wanting to figure out how to tell whether or not the file is fully downloaded until you run it? If so I have a couple thoughts:

  1. At least with chromium based browsers. The file isn’t saved as that name until its fully downloaded. . I think with other browsers you may have to play around with it, but you might just check the ‘length’ property. I feel like in Firefox it has the file as a placeholder but the actual bits are with a .bin.part extension until the download finishes You may just have to toy around with that, based on your browser perhaps. Of course mileage may vary.
  2. What about just using PS to download it (like you were doing in your previous post with qbitorrent). Since PS doesn’t start the next line of code until the previous one completes in most cases (things like jobs are different), this would take care of itself simply by order of operations.

If i’m misunderstanding, you may have to provide additional clarification.

Exactly.

Exactly.

Yes, but there are two files, one .exe file which is not complete yet and a .part file.

Tried it, but unfortunately it is not possible, there are a few programs that don’t have direct URL from which you can download from, meaning that instead of google.com/download (example) it’s google.com/randomnumberdownload, some websites have some sort of “protection” against bots, the only way I can possibly download that specific program is by browser, so what I did was to use PowerShell to open the browser and send a javascript command to that specific classname (see previous thread) using the browser console, so that’s how it downloads the file, I just need to make PowerShell wait untill it finishes somehow.

So it sounds like you are using Firefox.

Did you look at the length property of the exe file like I mentioned? I think the length is 0 until it finishes downloading on the exe file.

Uh, you are right, just tested it and it’s 0 in size,
uhmmm, ok, so now to figure out how to make powershell wait if it’s 0…
how do I do that?

I think I got it

While (!(Test-Path $foo -ErrorAction SilentlyContinue)) {
}
do {
    $dirStats = Get-Item $foo| Measure-Object -Sum Length
    $dirStats.Sum
} 
until( ($dirStats.Sum -ne 0) )

I only tested it with Firefox, not chrome, I don’t know if chrome behaves the same way (makes the .exe size 0 untill download completed)
What do you think?

Chrome is different, in that the file won’t exist at all, instead they do partial (crdownload) files, so it’s kinda tricky to deal with IMO, because depending on the browser you initiate, changes your logic, and PS isn’t going to necessarily know that. You either have to add logic and when you run your code, pass that in, or just assume you’re always going to use a certain browser for this process.

A note about loops that can run forever (infinite loops), it’s often a good idea to have a ‘timeout’ or some sort of way to cancel out of it, if you feel too much time is passed. for something like this it might be hard. For example, if the download failed for whatever reason, this script would never satisfy, resulting in an endless loop.

One way is to set a max retry or some kind, and add a start-sleep. I know you don’t want to do that but this is more as a last ditch thing - ok we waited 40 minutes for some software to download that’s way too long, we need to exit this loop. It might not be necessary in this case if you’re just messing around, but wanted to mention it.

I’ll see if timeout is even needed, but I agree it’s a good idea, need to figure out if it’s needed for my use case