I use dotnet-watch a bunch and have used a version via grunt/gulp a little in the past as well.
In front of me, I had some TypeScript, tsc
and an app.ts
file. I wanted to watch it and trigger tsc
automatically. But there was no csproj, no NuGet, and no npm in sight.
I went searching far and wide for solutions, and some clever people have some insight to add to the quest:
- https://www.reddit.com/r/usefulscripts/comments/4y46kl/powershell_since_theres_no_native_watch_command/
- https://stackoverflow.com/questions/29066742/watch-file-for-changes-and-run-command-with-powershell
- https://nightroman.wordpress.com/2006/09/26/watch-command-ps1-watch-commands-output-repeatedly/
From these, I cobbled together what is now in my Microsoft.PowerShell_profile.ps1
file:
# Watch in Powershell
function Invoke-Watch {
param(
[string]$Folder,
[string]$Filter = "*.*",
[scriptblock]$Action,
[Switch]$IncludeSubdirectories = $true
)
$watcher = New-Object IO.FileSystemWatcher $folder, $filter -Property @{
IncludeSubdirectories = $IncludeSubdirectories
EnableRaisingEvents = $true
}
Write-Host "Now Watching (ctrl+c to stop)"
$global:PSWatchFileChanged = $false
$onChange = Register-ObjectEvent $Watcher Changed -Action {$global:PSWatchFileChanged = $true}
try{
while($true) {
& $Action
while($global:PSWatchFileChanged -eq $false) {
Start-Sleep -Milliseconds 100
}
$global:PSWatchFileChanged = $false
}
}
finally{
Unregister-Event -SubscriptionId $onChange.Id
}
}
New-Alias -Name watch -Value Invoke-Watch
To use it, You pass a few parameters to the script:
# Watch tsc compile my ts files
watch -Folder "${PWD}" =Filter "*.ts" -Action { tsc }
At some point, the parameters will change, and I might make it prettier, or more intuitive. (There is also a nasty global in there, so running more than one at a time is either a feature or a bug, depending on how you use it…)
I will probably gist this at some point and keep it up to date with those changes.