This blog has moved to http://ThePowerShellGuy.com
Greetings /\/\o\/\/
there are some troubles with using the Filewatcher class for monitoring file changes.
in MSH.
Main problem is that the filewatcher is on another Thread, hence you can't (yet) use a delegate .
"Jeff Jones [MSFT]" wrote:
This is a known issue where if the
ScriptBlock gets called on a different thread then it cannot be invoked.
It looks like the plan for V1 is to improve the error message and then possibly
take a fix in V2.
you still can do this :
$fsw = New-object System.IO.FileSystemWatcher
$r = new-object System.IO.WaitForChangedResult
$r = $fsw.WaitForChanged($all)
but then you can't quit no more (only with ctrl-break but that will exit MSH)a workaround a made for this was :
while ($True) {
write-host -noNewLine "."
$fsw = New-object System.IO.FileSystemWatcher
$r = new-object System.IO.WaitForChangedResult
$fsw.path = $args[0]
$r = $fsw.WaitForChanged($all,10000)
if ($r.timedOut -eq $False){
$changed = $True
$r fl out-string
}
}
so you can quit every 10 seconds.
But the looping is not verry elegant, soI did not really like this
The trick with the solution below is to use a form for the Filesystemwatcher to sync with.( a form has an interface for that)
I have got a lot of help with this issue in the newsgroup from Bruce Payette [MSFT]
he made a nice script to make a form with a quit button(some nice lay-out tricks also)
but in this case I didn't want to see the form.
so I made this version that uses a notify-icon,so now you can quit from the notify-icon, hence I was able to hide the form.
nice site-effect of Using the Notify-Icon for this was that I could Use Balloons to.
And I have a Context-menu, so I can add More functions (to add an other watcher / change the dir etc.)
(*TIP if you have the MSHObjectViewer function, from other post. you could do OV($FSW) here ;-)So I think It's a nice base for allot of functions.
enjoy ...
gr /\/\o\/\/
#WatchDir.msh
#
# Watches Directory for changes,
# and you can Quit !!
# (and a balloon as a bonus ;-)
#
# /\/\o\/\/ 2005
# http://mow001.blogspot.com
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
function watch {
$dir = $args[0]
if ($dir -eq $null){$dir=$((gi .).Fullname)}
if ($dir -eq "."){$dir=$((gi .).Fullname)}
if ([system.io.directory]::exists($dir)) {
"watching $dir ... Use systray to quit"
$form = new-object System.Windows.Forms.form
$cm = new-object System.Windows.Forms.ContextMenu
$mi = new-object System.Windows.Forms.MenuItem
$ni = new-object System.Windows.Forms.NotifyIcon
$form.contextMenu = $cm
$form.contextMenu.MenuItems.AddRange($mi)
$form.ShowInTaskbar = $False
$form.WindowState = "minimized"
$mi.Index = 0
$mi.Text = "E&xit"
$mi.add_Click({
#Clean up
$fsw.EnableRaisingEvents = $False;$NI.Visible = $False
$form.close()
})
$ni = $ni
$ni.Icon = New-object System.Drawing.Icon("g:\monad\mow.ico")
$NI.ContextMenu = $cm
$NI.Text = "Watching $dir"
$fsw = new-object System.IO.FileSystemWatcher $dir
$fsw.IncludeSubDirectories = $true
$fsw.SynchronizingObject = $form
$fsw.add_Changed({
$NI.ShowBalloonTip(10,$_.FullPath,"$($_.FullPath)$($_.ChangeType)",[system.windows.forms.ToolTipIcon]"Warning")
write-host "$((get-date).ToShortTimeString()) : $($_.FullPath)$($_.ChangeType)"
})
#Fire it up
$fsw.EnableRaisingEvents = $true;$NI.Visible = $True;$form.showdialog()
}
else {"Directory $dir does not exist"}
}