mirror of
https://github.com/Micke-K/IntuneManagement.git
synced 2026-09-28 19:05:38 +02:00
IntuneManagement 4.0.0-beta1
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# 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 }
|
||||
}
|
||||
Reference in New Issue
Block a user