Watch file for changes and run command with powershell

前端 未结 7 876
终归单人心
终归单人心 2020-11-28 07:01

Is there any simple way(i.e., script) to watch file in Powershell and run commands if file changes. I have been googling but can\'t find simple solution. Basically I run scr

7条回答
  •  孤街浪徒
    2020-11-28 07:48

    Here is the solution I ended up with based on several of the previous answers here. I specifically wanted:

    1. My code to be code, not a string
    2. My code to be run on the I/O thread so I can see the console output
    3. My code to be called every time there was a change, not once

    Side note: I've left in the details of what I wanted to run due to the irony of using a global variable to communicate between threads so I can compile Erlang code.

    Function RunMyStuff {
        # this is the bit we want to happen when the file changes
        Clear-Host # remove previous console output
        & 'C:\Program Files\erl7.3\bin\erlc.exe' 'program.erl' # compile some erlang
        erl -noshell -s program start -s init stop # run the compiled erlang program:start()
    }
    
    Function Watch {    
        $global:FileChanged = $false # dirty... any better suggestions?
        $folder = "M:\dev\Erlang"
        $filter = "*.erl"
        $watcher = New-Object IO.FileSystemWatcher $folder, $filter -Property @{ 
            IncludeSubdirectories = $false 
            EnableRaisingEvents = $true
        }
    
        Register-ObjectEvent $Watcher "Changed" -Action {$global:FileChanged = $true} > $null
    
        while ($true){
            while ($global:FileChanged -eq $false){
                # We need this to block the IO thread until there is something to run 
                # so the script doesn't finish. If we call the action directly from 
                # the event it won't be able to write to the console
                Start-Sleep -Milliseconds 100
            }
    
            # a file has changed, run our stuff on the I/O thread so we can see the output
            RunMyStuff
    
            # reset and go again
            $global:FileChanged = $false
        }
    }
    
    RunMyStuff # run the action at the start so I can see the current output
    Watch
    

    You could pass in folder/filter/action into watch if you want something more generic. Hopefully this is a helpful starting point for someone else.

提交回复
热议问题