Home > Net >  VSCode & Powershell: How to stop script and unregister object?
VSCode & Powershell: How to stop script and unregister object?

Time:12-28

I have a snippet that works fine. It registers an objectevent as follows (snippet):

Register-ObjectEvent $Watcher -EventName Created -SourceIdentifier FileCreated -Action {

It works fine, but I can't seem to get the script to fully stop and unregister. When I use "normal" methods to stop code (listed below), when I rerun the code (via F5) I get error:

Register-ObjectEvent : Cannot subscribe to the specified event. A subscriber with the source identifier 'FileCreated' already exists.

The only way I can unregister it (so far) is to terminate the powershell.exe process, which also kills the powershell run time within VSCode (throwing errors, forcing a manual restart).

I start the code by hitting F5

To stop the code, I have tried:

  • Shift-F5
  • Ctrl-C (in the powershell terminal area)

Nothing works except as described above.

What am I missing?

CodePudding user response:

For debugging purposes only, where you often force-stop your script, there are 2 options. Either run the unregister-Event line manually so the event is unregistered or do add something like that near the top f your script. (at least before the Register-ObjectEvent )

Unregister-Event -SourceIdentifier FileCreated -EA 0

-EA 0 is the same as -ErrorAction SilentlyContinue and will prevent the script from throwing an error when you are on a new session and the event was never registered yet.

Note: This should not be in your production script and is only meant as a debugging help. (If you want to keep it on hand, I'd say comment it out at least on the prod. version of the script)

Your production version of the script should implement Unregister-Event properly though, something more akin to:

$FileWatcherReg = @{
    InputObject      = $Watcher
    EventName        = 'Created'
    SourceIdentifier = 'FileCreated'
    MessageData      = @{WatchQueue = $WatchQueue; Timer = $WatchTimer }
    Action           = {
        if ($null -ne $event) {
            Write-Host "Path: $($Event.SourceArgs.FullPath) - ($($Event.Timegenerated))"
        }
    }
   
}

Register-ObjectEvent @FileWatcherReg 

while ($true) {
    Start-Sleep -Milliseconds 100

    # Logic to exit the loop at some point.
}

# Exit script logic ...
Unregister-Event -SourceIdentifier FileCreated

CodePudding user response:

Similar to Sage's example above, is this larger example. It structures the event clearly, and shows how by keeping the script running, you can then cancel the script, which will trigger the cleanup block.

So there is something to be said for this approach. (However, I continue to see the whole Register-ObjectEvent as kind of a TSR... your code stays resident... forever... waiting for the relevant event....)

The example: https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/using-filesystemwatcher-correctly-part-2#

  • Related