简体   繁体   中英

How can I run an MSBuild task in Powershell on file changed

I am trying to write something like a CSharp watch task in PowerShell. So, what I want to happen is when a CSharp file changes in a certain directory, it tries to find the csproj file and initiates a build.

Here's what I have currently

    function Watch-CSharp-Files() {
    set-location "D:\path\to\csharp\files\"

    $originalPath = Get-Location

    Write-host "Welcome to The Watcher. It keeps track of changing files in this solution directory (including subdirectories) and triggers a build when something changes..."

    $existingEvents = get-eventsubscriber
    foreach ($item in $existingEvents) {
        Unregister-event -SubscriptionId $item.SubscriptionId
        write-host "Unsubscribed existing event:" $item.Action.Name
    }

    $folder = get-location
    $filter = '*.*'
    $watcher = New-Object IO.FileSystemWatcher $folder, $filter -Property @{IncludeSubdirectories = $true;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'} 

    Register-ObjectEvent $watcher Changed -SourceIdentifier FileChanged -Action {
        $path = $Event.SourceEventArgs.FullPath  

        if ($path -match "(\.cs~|.cs$)") {
            write-host "file changed: $path"
            Invoke-Expression -Command "Find-And-Build-Project '$path'"
        }
    }
}

function Find-And-Build-Project([string]$path) {
    write-host "BUILD PROJECT REPORTING FOR DUTY"

    $pathParts = "$path".Split("\\")
    $end = $pathParts.Count - 2 # skip the file name to the parent directory
    $testPath = $pathParts[0..$end] -join "\"
    write-host "testing path $testPath"
    $csproj = Get-ChildItem -path $testPath *.csproj

    For ($i = 0; $i -le 10; $i++) {    
        $newEnd = $end - $i
        $newPath = $pathParts[0..$newEnd] -join "\"
        $csproj = Get-ChildItem -path $newPath *.csproj
        write-host "$i. trying: $newPath, csproj: $csproj"
        if ($csproj) {
            write-host "found on $i, at $newPath, $csproj"
            break
        }
    }

    write-host "Ready: $newPath\$csproj"
    $msbuild = "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe"
    write-host "trying to MSBUILD"    
    & $msbuild ("$newPath\$csproj", "/target:Build", "/p:configuration=debug", "/verbosity:n")    
}

Watch-CSharp-Files

What I have found is that within the function Find-And-Build-Project , the & $msbuild doesn't get invoked. But, I don't understand why.

Any ideas?

Ok, this helped me: https://stackoverflow.com/a/37724701/1326235 .

This script targets the saved .cs file (or .cs~tmp[0-9].cs as Visual Studio seems to create), then searches back up the directory tree to find a .csproj file and builds it.

I published the module to the PowerShell Gallery, it's called CSharp-Watch

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM