0% found this document useful (0 votes)
58 views

Use PowerShell & System - IO.FileSystemWatcher To Detect When A Download To A Specific Folder Is Complete - Super User

The user is trying to monitor a download folder to trigger an action when a download is complete using PowerShell and FileSystemWatcher. However, the output is confusing as Chrome creates temporary files during downloads that cause extra events. The user provides a log showing the multiple creation, change and deletion events from Chrome downloads. The user is looking for suggestions on how to reliably detect when a download is truly finished through this process.

Uploaded by

TCaller true
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
58 views

Use PowerShell & System - IO.FileSystemWatcher To Detect When A Download To A Specific Folder Is Complete - Super User

The user is trying to monitor a download folder to trigger an action when a download is complete using PowerShell and FileSystemWatcher. However, the output is confusing as Chrome creates temporary files during downloads that cause extra events. The user provides a log showing the multiple creation, change and deletion events from Chrome downloads. The user is looking for suggestions on how to reliably detect when a download is truly finished through this process.

Uploaded by

TCaller true
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

10/12/2021 17:27 google chrome - Use PowerShell & System.IO.

FileSystemWatcher to detect when a download to a specific folder is complet…

 
Super User is a question and answer site
for computer enthusiasts and power
users. It only takes a minute to sign up.

Sign up to join this community

Anybody can ask a question

Anybody can answer

The best answers are voted


up and rise to the top

SPONSORED BY

Use PowerShell & System.IO.FileSystemWatcher to detect when a


download to a specific folder is complete
Asked
2 years, 11 months ago Active
1 month ago Viewed
4k times

I'm attempting to monitor my download folder and trigger a command-line action when a
download is completed. This is very similar to another question, How to monitor a folder and
1 trigger a command-line action when a file is created or edited?

I've implemented the PowerShell script described in the most upvoted answer, but when I run
it, I'm finding that the output is confusing.
1
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO

$watcher = New-Object System.IO.FileSystemWatcher

$watcher.Path = "Z:\UnprocessedDownloads"

$watcher.Filter = "*.*"

$watcher.IncludeSubdirectories = $true

$watcher.EnableRaisingEvents = $true

### DEFINE ACTIONS AFTER AN EVENT IS DETECTED

$action = { $path = $Event.SourceEventArgs.FullPath

$changeType = $Event.SourceEventArgs.ChangeType

$logline = "$(Get-Date -f o), $changeType, $path"

Your privacy Add-content "Z:\log.txt" -value $logline

}
you agree Stack Exchange can store cookies on your device and disclose
By clicking “Accept all cookies”,
### DECIDE WHICH EVENTS SHOULD BE WATCHED

information in accordance with our Cookie Policy.


Register-ObjectEvent $watcher "Created" -Action $action

Register-ObjectEvent $watcher "Changed" -Action $action

Accept all Register-ObjectEvent


cookies $watcher "Deleted" -Action $action

Customize settings
Register-ObjectEvent $watcher "Renamed" -Action $action

while ($true) {sleep 5}

https://superuser.com/questions/1390030/use-powershell-system-io-filesystemwatcher-to-detect-when-a-download-to-a-spec 1/5
10/12/2021 17:27 google chrome - Use PowerShell & System.IO.FileSystemWatcher to detect when a download to a specific folder is complet…

I should note that the downloads in question are being created by Chrome, which may or may
not explain what's going on. As best I can tell, the series of events is as follows:

1. A file with the intended filename is created.

2. The previously created file is promptly deleted.


3. A file with the intended filename, and .crdownload appended, is created.

4. This file registers between two and three changes (of the files I tested, if it was a few KB it
showed two, but files 100MB to 10GB registered three).
5. This file is renamed, removing the .crdownload.

6. This file then registers an additional two to three changes (I couldn't find any rhyme or
reason to how many occurred).

7. It's done, nothing else registers without manual intervention.

So, that's that. I'm at a loss as to how I can tell a file is truly "done", short of perhaps watching
for a rename event, and subsequently waiting for an arbitrary number of seconds

(occasionally, the last recorded change took about 5 seconds to occur - I just realized this is
likely due to the sleep 5 in the script), perhaps 10.

Can anyone explain what's going on here? Are there any suggestions or alternatives? I'm not
beholden to PowerShell, it just seemed like it and the File System Watcher would be well
suited to the task. I'd prefer something with as little overhead as possible while retaining
automation.

FWIW, an excerpt from my tests (hardly extensive; note - I did adjust the log to show
milliseconds):

2019-01-02T22:03:03.6712039-05:00, Created, Z:\Unprocessed\test (1).jpg

2019-01-02T22:03:03.7242040-05:00, Deleted, Z:\Unprocessed\test (1).jpg

2019-01-02T22:03:03.7252054-05:00, Created, Z:\Unprocessed\test (1).jpg.crdownload


2019-01-02T22:03:03.7252054-05:00, Changed, Z:\Unprocessed\test (1).jpg.crdownload
2019-01-02T22:03:08.7265875-05:00, Changed, Z:\Unprocessed\test (1).jpg.crdownload
2019-01-02T22:03:08.7305994-05:00, Renamed, Z:\Unprocessed\test (1).jpg

2019-01-02T22:03:08.7315887-05:00, Changed, Z:\Unprocessed\test (1).jpg

2019-01-02T22:03:08.7315887-05:00, Changed, Z:\Unprocessed\test (1).jpg

2019-01-02T22:03:13.7348367-05:00, Changed, Z:\Unprocessed\test (1).jpg

2019-01-02T22:09:28.7729475-05:00, Deleted, Z:\Unprocessed\10GB.bin

2019-01-02T22:09:33.7742846-05:00, Created, Z:\Unprocessed\1GB.bin

2019-01-02T22:09:33.7762852-05:00, Deleted, Z:\Unprocessed\1GB.bin

2019-01-02T22:09:33.7772866-05:00, Created, Z:\Unprocessed\1GB.bin.crdownload

2019-01-02T22:09:33.7782853-05:00, Changed, Z:\Unprocessed\1GB.bin.crdownload

2019-01-02T22:09:33.7792825-05:00, Changed, Z:\Unprocessed\1GB.bin.crdownload

Your privacy
2019-01-02T22:10:28.7850646-05:00, Changed, Z:\Unprocessed\1GB.bin.crdownload

By clicking “Accept all cookies”, you agree StackRenamed,


2019-01-02T22:10:28.7860648-05:00, ExchangeZ:\Unprocessed\1GB.bin
can store cookies on your

device and disclose
2019-01-02T22:10:28.7870652-05:00,
information in accordance with our Cookie Policy.Changed, Z:\Unprocessed\1GB.bin

2019-01-02T22:10:28.7870652-05:00, Changed, Z:\Unprocessed\1GB.bin

2019-01-02T22:10:28.7880654-05:00, Changed, Z:\Unprocessed\1GB.bin

Accept all cookies Customize settings


2019-01-02T22:11:13.7928495-05:00, Created, Z:\Unprocessed\test (2).jpg

2019-01-02T22:11:13.7938482-05:00, Deleted, Z:\Unprocessed\test (2).jpg

2019-01-02T22:11:13.7938482-05:00, Created, Z:\Unprocessed\test (2).jpg.crdownload


2019-01-02T22:11:13.7948490-05:00, Changed, Z:\Unprocessed\test (2).jpg.crdownload
https://superuser.com/questions/1390030/use-powershell-system-io-filesystemwatcher-to-detect-when-a-download-to-a-spec 2/5
10/12/2021 17:27 google chrome - Use PowerShell & System.IO.FileSystemWatcher to detect when a download to a specific folder is complet…
2019 01 02T22:11:13.7948490 05:00, Changed, Z:\Unprocessed\test (2).jpg.crdownload
2019-01-02T22:11:18.7972830-05:00, Changed, Z:\Unprocessed\test (2).jpg.crdownload
2019-01-02T22:11:18.7982945-05:00, Renamed, Z:\Unprocessed\test (2).jpg

2019-01-02T22:11:18.7992839-05:00, Changed, Z:\Unprocessed\test (2).jpg

2019-01-02T22:11:18.8002947-05:00, Changed, Z:\Unprocessed\test (2).jpg

2019-01-02T22:11:23.8011169-05:00, Changed, Z:\Unprocessed\test (2).jpg

google-chrome powershell automation scheduled-tasks download-manager

Share Improve this question edited Jan 3 '19 at 21:24 asked Jan 3 '19 at 3:37
Follow Malcalevak
11 1 3

This code notwithstanding, when a file download should only be one of course, but as a download is
executing, a stub is created until it is done, just like a .tmp file is created when you open Word and doe
into go away until you save and close Word. If you think the other things are a side affect of Chrome
(which means you have Chrome as your default), then try another browser by setting it as the default.
This sounds to me like something is affecting the download and you are getting start overs, thus the
extra files.
– postanote
Jan 3 '19 at 7:49

Thanks for the feedback; I realized the .crdownload was a temporary file stud. There aren't any extra

files, just extra changes. I'm baffled by the "false file" at the start, and then all the changes after the
rename, I'd expect the rename to be the last step.
–  Malcalevak
Jan 3 '19 at 7:57

I'd expect rename if needed after the file download was complete, or named before the download
begins. It makes little sense to rename part way thru. See the other options I've suggested to try to see
if they are better for you.
– postanote
Jan 3 '19 at 8:02

I'd expect the rename on completion as well, that's why I'm confused by the ongoing changes
afterwards. Why/what is changing at that point? And I'd be less confused if the originally created file,
with the final filename, was renamed to append .crdownload, but deleting it and creating a new file
makes no sense to me!
–  Malcalevak
Jan 3 '19 at 21:16

1 Answer Active Oldest Votes

Give this a shot. I modified the original to include additional logic. Not sure how bullet proof
this will be. Let me know how it holds up.
0
# create an array that tracks each file

$global:files = @()

# where we will move the file once it is free

$destination = "C:\destination"

$watcher = New-Object System.IO.FileSystemWatcher

$watcher.Path = "C:\source"

Your privacy
$watcher.Filter = "*.*"

$watcher
By clicking .IncludeSubdirectories
“Accept all cookies”, you agree =Stack
$true

Exchange can store cookies on your device and disclose


$watcher .EnableRaisingEvents = $true
information in accordance with our Cookie Policy.

$action = {

Accept all $path


cookies= $Event.SourceEventArgs.FullPath

Customize settings
$changeType = $Event.SourceEventArgs.ChangeType

$logline = "$(Get-Date -f o), $changeType, $path"

Add-content "C:\log.txt" -value $logline

https://superuser.com/questions/1390030/use-powershell-system-io-filesystemwatcher-to-detect-when-a-download-to-a-spec 3/5
10/12/2021 17:27 google chrome - Use PowerShell & System.IO.FileSystemWatcher to detect when a download to a specific folder is complet…
\ g $ g
Write-Host $logline

if($changeType -eq "Renamed" -and $path.Split(".")[-1] -ne "crdownload") {

Write-Host -ForegroundColor Green "Found the file we need! $path"

Add-content "C:\log.txt" -value "Found the file we need! $path"

$global:files += $path

Register-ObjectEvent $watcher "Created" -Action $action

Register-ObjectEvent $watcher "Changed" -Action $action

Register-ObjectEvent $watcher "Deleted" -Action $action

Register-ObjectEvent $watcher "Renamed" -Action $action

while ($true) {

# if there are any files to process, check if they are locked

if($global:files) {

$global:files | % {

$file = $_

# assume the file is locked

$fileFree = $false

Write-Host -ForegroundColor Yellow "Checking if the file is locked...


($file)"

Add-content "C:\log.txt" -value "Checking if the file is locked... ($_)"

# true = file is free

# false = file is locked

try {

[IO.File]::OpenWrite($file).close();Write-Host -ForegroundColor Green


"File is free! ($file)"

Add-content "C:\log.txt" -value "File is free! ($file)"

$fileFree = $true

catch {

Write-Host -ForegroundColor Red "File is Locked ($file)"

Add-content "C:\log.txt" -value "File is Locked ($file)"

if($fileFree) {

# do what we want with the file, since it is free

Move-Item $file $destination

Write-Host -ForegroundColor Green "Moving file ($file)"

Add-content "C:\log.txt" -value "Moving file ($file)"

# make sure we don't progress until the file has finished moving

while(Test-Path $file) {

Sleep 1

# remove the current file from the array

Write-Host -ForegroundColor Green "Done processing this file. ($file)"

Add-content "C:\log.txt" -value "Done processing this file. ($file)"

Your privacy $global:files = $global:files | ? { $_ -ne $file }

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose
information in accordance
}
with our Cookie Policy.
}

Accept all cookies Customize settings


sleep 2

https://superuser.com/questions/1390030/use-powershell-system-io-filesystemwatcher-to-detect-when-a-download-to-a-spec 4/5
10/12/2021 17:27 google chrome - Use PowerShell & System.IO.FileSystemWatcher to detect when a download to a specific folder is complet…

This will listen for a Renamed event where the file extension is not "crdownload", helping
us get the actual path/file/extension and not the temporary file's information. When a
match is found, it is stored in an array, allowing us to work with multiple files at once.

Once the array contains one or more file names, each file is checked to see if it is currently
locked or if it is free. If it is free, it is moved to $destination . You can change the desired
action from a Move-Item to whatever you'd like.
Once a file has moved successfully, it is removed from the array.

Know that the multiple Changed events you are seeing are to be expected (and also occur for
me when downloading from Chrome):

Common file system operations might raise more than one event. For
example, when
a file is moved from one directory to another, several
OnChanged and some
OnCreated and OnDeleted events might be raised.
Moving a file is a complex
operation that consists of multiple simple
operations, therefore raising multiple
events. Likewise, some
applications (for example, antivirus software) might cause
additional
file system events that are detected by FileSystemWatcher.

You may want to remove the added Write-Host lines. You may also want to add the following
in a termination catch to gracefully terminate the registered events:

Get-EventSubscriber | ? { $_.EventName -in "Created","Changed","Deleted","Renamed" } |


Unregister-Event

Inspiration.

Checking if a file is locked.

Share Improve this answer Follow answered Jan 4 '19 at 18:03


root
3,322 7 25 44

Thanks for this! I especially appreciate the excerpt about how common file system operations might raise
more than one event as I'd suspected everything was technically "expected", but seeing the
documentation about it is definitely reassuring. I'd even been speculating that my anti-virus software
might have been responsible for the occasionally lagging "Changed" event. While I've got a workable
solution in place, this looks like it might be more elegant, along with handling multiple files, so I'll
attempt to adjust it to my needs accordingly and get back to you (and give credit).
–  Malcalevak
Jan 5
'19 at 1:18

Your privacy
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose
information in accordance with our Cookie Policy.

Accept all cookies Customize settings

https://superuser.com/questions/1390030/use-powershell-system-io-filesystemwatcher-to-detect-when-a-download-to-a-spec 5/5

You might also like