examples/05-Progress.ps1
|
# 05 - Progress: run work in small steps and show progress. The window only stays responsive between # messages, so long work is split into steps: the page asks for the next step, PowerShell does one and answers. if (-not (Get-Command Show-NativeWebView -ErrorAction Ignore)) { Import-Module NativeWebView -ErrorAction Stop } $Files = @(Get-ChildItem -Path $PSHOME -File -Recurse -ErrorAction Ignore | Select-Object -First 60) $State = @{ Index = 0; Bytes = [long] 0 } $Html = @' <!doctype html> <html><head><style> body { font-family: Verdana, 'Segoe UI', Arial, sans-serif; font-size: 13px; color: #454545; padding: 24px; background: #F9F9F9; } h3 { color: #154363; } .bar { height: 18px; background: #e4e4e4; border-radius: 9px; overflow: hidden; } .fill { height: 100%; width: 0; background: linear-gradient(90deg, #095495, #a2bfd6); transition: width .2s; } button { margin-top: 16px; padding: 8px 18px; background: #095495; color: white; border: 0; border-radius: 4px; font: inherit; } button:hover { background: #154363; } </style></head> <body> <h3 id="title">Measuring files...</h3> <div class="bar"><div class="fill" id="fill"></div></div> <p id="text"></p> <button id="close" hidden>Close</button> <script> kHost.on(function (m) { if (m.action !== "progress") { return; } document.getElementById("fill").style.width = m.percent + "%"; document.getElementById("text").textContent = m.text; if (m.done) { document.getElementById("title").textContent = "Done"; document.getElementById("close").hidden = false; } else { kHost.send({ action: "next" }); } }); document.getElementById("close").onclick = function () { kHost.send({ action: "close" }); }; kHost.send({ action: "next" }); </script> </body></html> '@ Show-NativeWebView -Html $Html -Title "Progress" -Width 460 -Height 260 -OnMessage { param($Message, $Window) $Data = $Message | ConvertFrom-Json if ($Data.action -eq "close") { $Window.Close(); return } if ($State.Index -lt $Files.Count) { $State.Bytes += $Files[$State.Index].Length # one step of "work" $State.Index++ } [int] $Percent = if ($Files.Count -eq 0) { 100 } else { [int] (100 * $State.Index / $Files.Count) } $Window.Send("progress", @{ percent = $Percent; done = ($State.Index -ge $Files.Count) text = ([string] $State.Index + " of " + $Files.Count + " files, " + [math]::Round($State.Bytes / 1MB, 1) + " MB") }) }.GetNewClosure() |