mirror of
https://github.com/Micke-K/IntuneManagement.git
synced 2026-09-28 19:05:38 +02:00
96 lines
3.7 KiB
PowerShell
96 lines
3.7 KiB
PowerShell
# Cancel affordance for the status overlay.
|
|
#
|
|
# The app is effectively single-threaded: a long wait (device-code sign-in, a
|
|
# browser round trip) runs a loop on the UI thread and keeps the window alive by
|
|
# pumping messages (Invoke-UIPump). Because that pump already runs inside both
|
|
# login wait loops, a button on the status overlay DOES get its click dispatched -
|
|
# which is what makes a Cancel button possible at all without a threading rewrite.
|
|
#
|
|
# This file owns only the state and the contract. It deliberately holds no UI
|
|
# types (R12): the button lives in each backend, and its click handler calls
|
|
# Request-StatusCancel by NAME - which also satisfies the Avalonia rule that an
|
|
# event handler may not rely on captured locals.
|
|
#
|
|
# Two separate things are recorded:
|
|
#
|
|
# the ACTION what actually stops the pending operation (cancel a
|
|
# CancellationTokenSource, stop an HttpListener). Supplied by the
|
|
# caller that knows how, via Write-Status -OnCancel.
|
|
# the REQUEST a sticky flag the waiting loop polls, so it can break out
|
|
# promptly instead of running to its timeout.
|
|
#
|
|
# Both matter. Without the action the operation keeps running invisibly to its
|
|
# timeout; without the flag the loop would not notice for up to its poll interval
|
|
# (or at all, if the underlying wait is not cancellable).
|
|
|
|
$script:StatusCancelAction = $null
|
|
$script:StatusCancelRequested = $false
|
|
|
|
# Arm the overlay's cancel button. Called from Write-Status -OnCancel; also
|
|
# callable directly by code that wants the action armed without touching the
|
|
# status text.
|
|
function Set-StatusCancelAction
|
|
{
|
|
param([scriptblock]$Action)
|
|
|
|
$script:StatusCancelAction = $Action
|
|
# Arming starts a NEW cancellable operation, so a request left over from a
|
|
# previous one must not immediately cancel it.
|
|
$script:StatusCancelRequested = $false
|
|
}
|
|
|
|
# Disarm. Called when the status overlay is cleared, and from the finally block of
|
|
# whatever armed it, so a stale action can never fire against a finished operation.
|
|
function Clear-StatusCancelAction
|
|
{
|
|
$script:StatusCancelAction = $null
|
|
$script:StatusCancelRequested = $false
|
|
}
|
|
|
|
# True once the user has asked to cancel. Waiting loops poll this.
|
|
function Test-StatusCancelRequested
|
|
{
|
|
return ($script:StatusCancelRequested -eq $true)
|
|
}
|
|
|
|
# Sleep for up to -Seconds, in slices, pumping the UI between them so the overlay's
|
|
# Cancel button stays clickable, and return as soon as cancel is requested.
|
|
# Returns $true when the wait ended because of a cancel.
|
|
#
|
|
# A plain Start-Sleep of several seconds blocks the single UI thread outright: no
|
|
# repaint, no click dispatch, so a Cancel button would be dead for the whole nap.
|
|
# Any polling loop that wants to be cancellable has to wait THIS way.
|
|
function Wait-StatusCancel
|
|
{
|
|
param([int]$Seconds = 1, [int]$SliceMilliseconds = 100)
|
|
|
|
if($Seconds -le 0) { return (Test-StatusCancelRequested) }
|
|
|
|
$deadline = [DateTime]::UtcNow.AddSeconds($Seconds)
|
|
while([DateTime]::UtcNow -lt $deadline)
|
|
{
|
|
if(Test-StatusCancelRequested) { return $true }
|
|
Invoke-UIPump
|
|
Start-Sleep -Milliseconds $SliceMilliseconds
|
|
}
|
|
return (Test-StatusCancelRequested)
|
|
}
|
|
|
|
# Invoked by the overlay's Cancel button. Sets the flag first so the flag is
|
|
# observable even if the action throws, then runs the action.
|
|
function Request-StatusCancel
|
|
{
|
|
$script:StatusCancelRequested = $true
|
|
|
|
$action = $script:StatusCancelAction
|
|
if(-not $action) { return }
|
|
|
|
# One shot: a second click must not run the action again (stopping an already
|
|
# stopped listener throws).
|
|
$script:StatusCancelAction = $null
|
|
|
|
Write-Log "Cancel requested from the status window"
|
|
try { & $action }
|
|
catch { Write-LogError "Status cancel action failed" $_.Exception }
|
|
}
|