|
|
@@ -67,6 +67,7 @@ $DaemonTaskName = 'Softwarekatalog - Daemon'
|
|
|
|
$RequestTaskName = 'Softwarekatalog - Requests'
|
|
|
|
$RequestTaskName = 'Softwarekatalog - Requests'
|
|
|
|
$QueueTaskName = 'Softwarekatalog - Queue'
|
|
|
|
$QueueTaskName = 'Softwarekatalog - Queue'
|
|
|
|
$UpgradeTaskName = 'Softwarekatalog - Winget Upgrade'
|
|
|
|
$UpgradeTaskName = 'Softwarekatalog - Winget Upgrade'
|
|
|
|
|
|
|
|
$WingetSourceName = 'winget'
|
|
|
|
$WingetMutexName = 'Global\Softwarekatalog-Winget'
|
|
|
|
$WingetMutexName = 'Global\Softwarekatalog-Winget'
|
|
|
|
$QueueStateMutexName = 'Global\Softwarekatalog-QueueState'
|
|
|
|
$QueueStateMutexName = 'Global\Softwarekatalog-QueueState'
|
|
|
|
$PowerShellExe = Join-Path $env:SystemRoot 'System32\WindowsPowerShell\v1.0\powershell.exe'
|
|
|
|
$PowerShellExe = Join-Path $env:SystemRoot 'System32\WindowsPowerShell\v1.0\powershell.exe'
|
|
|
@@ -926,13 +927,82 @@ function Get-ProgressPercentFromLine {
|
|
|
|
param([string]$Line)
|
|
|
|
param([string]$Line)
|
|
|
|
|
|
|
|
|
|
|
|
if ([string]::IsNullOrWhiteSpace($Line)) { return $null }
|
|
|
|
if ([string]::IsNullOrWhiteSpace($Line)) { return $null }
|
|
|
|
|
|
|
|
|
|
|
|
$match = [regex]::Match($Line, '(?<!\d)(100|[1-9]?\d)(?:[\.,]\d+)?\s*%')
|
|
|
|
$match = [regex]::Match($Line, '(?<!\d)(100|[1-9]?\d)(?:[\.,]\d+)?\s*%')
|
|
|
|
if (-not $match.Success) { return $null }
|
|
|
|
if ($match.Success) {
|
|
|
|
$raw = $match.Groups[1].Value
|
|
|
|
$value = [int]$match.Groups[1].Value
|
|
|
|
$value = [int]$raw
|
|
|
|
|
|
|
|
if ($value -lt 0) { return 0 }
|
|
|
|
if ($value -lt 0) { return 0 }
|
|
|
|
if ($value -gt 100) { return 100 }
|
|
|
|
if ($value -gt 100) { return 100 }
|
|
|
|
return $value
|
|
|
|
return $value
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$transferMatch = [regex]::Match(
|
|
|
|
|
|
|
|
$Line,
|
|
|
|
|
|
|
|
'(?<current>\d+(?:[\.,]\d+)?)\s*(?<currentUnit>TB|GB|MB|KB|B)\s*/\s*(?<total>\d+(?:[\.,]\d+)?)\s*(?<totalUnit>TB|GB|MB|KB|B)',
|
|
|
|
|
|
|
|
[System.Text.RegularExpressions.RegexOptions]::IgnoreCase
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
if (-not $transferMatch.Success) { return $null }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
$culture = [System.Globalization.CultureInfo]::InvariantCulture
|
|
|
|
|
|
|
|
$current = [double]::Parse($transferMatch.Groups['current'].Value.Replace(',', '.'), $culture)
|
|
|
|
|
|
|
|
$total = [double]::Parse($transferMatch.Groups['total'].Value.Replace(',', '.'), $culture)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch ($transferMatch.Groups['currentUnit'].Value.ToUpperInvariant()) {
|
|
|
|
|
|
|
|
'TB' { $current *= 1099511627776 }
|
|
|
|
|
|
|
|
'GB' { $current *= 1073741824 }
|
|
|
|
|
|
|
|
'MB' { $current *= 1048576 }
|
|
|
|
|
|
|
|
'KB' { $current *= 1024 }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ($transferMatch.Groups['totalUnit'].Value.ToUpperInvariant()) {
|
|
|
|
|
|
|
|
'TB' { $total *= 1099511627776 }
|
|
|
|
|
|
|
|
'GB' { $total *= 1073741824 }
|
|
|
|
|
|
|
|
'MB' { $total *= 1048576 }
|
|
|
|
|
|
|
|
'KB' { $total *= 1024 }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ($total -le 0) { return $null }
|
|
|
|
|
|
|
|
$value = [int][Math]::Round(($current / $total) * 100)
|
|
|
|
|
|
|
|
if ($value -lt 0) { return 0 }
|
|
|
|
|
|
|
|
if ($value -gt 100) { return 100 }
|
|
|
|
|
|
|
|
return $value
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch {
|
|
|
|
|
|
|
|
return $null
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function ConvertTo-WingetOutputLine {
|
|
|
|
|
|
|
|
param([string]$Line)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ([string]::IsNullOrWhiteSpace($Line)) { return $null }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$text = [regex]::Replace($Line, '\x1B\[[0-?]*[ -/]*[@-~]', '').Trim()
|
|
|
|
|
|
|
|
if ([string]::IsNullOrWhiteSpace($text)) { return $null }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$transferMatch = [regex]::Match(
|
|
|
|
|
|
|
|
$text,
|
|
|
|
|
|
|
|
'\d+(?:[\.,]\d+)?\s*(?:TB|GB|MB|KB|B)\s*/\s*\d+(?:[\.,]\d+)?\s*(?:TB|GB|MB|KB|B)',
|
|
|
|
|
|
|
|
[System.Text.RegularExpressions.RegexOptions]::IgnoreCase
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
if ($transferMatch.Success) {
|
|
|
|
|
|
|
|
return $transferMatch.Value
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Older winget versions emit spinner and block-bar frames even when stdout is
|
|
|
|
|
|
|
|
# redirected. Ignore lines that contain no useful ASCII text; this also drops
|
|
|
|
|
|
|
|
# progress glyphs decoded through an OEM code page (for example, "Ôûê").
|
|
|
|
|
|
|
|
if ($text -notmatch '[A-Za-z0-9]') { return $null }
|
|
|
|
|
|
|
|
return $text
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function Set-WingetOutputEncoding {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch {
|
|
|
|
|
|
|
|
# Some non-interactive hosts do not expose a mutable console encoding.
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function Update-QueueItemProgress {
|
|
|
|
function Update-QueueItemProgress {
|
|
|
@@ -1099,8 +1169,15 @@ function Invoke-WithWingetLock {
|
|
|
|
$mutex = New-Object System.Threading.Mutex($false, $WingetMutexName)
|
|
|
|
$mutex = New-Object System.Threading.Mutex($false, $WingetMutexName)
|
|
|
|
$hasLock = $false
|
|
|
|
$hasLock = $false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
$hasLock = $mutex.WaitOne([TimeSpan]::FromSeconds($TimeoutSeconds))
|
|
|
|
$hasLock = $mutex.WaitOne([TimeSpan]::FromSeconds($TimeoutSeconds))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch [System.Threading.AbandonedMutexException] {
|
|
|
|
|
|
|
|
$hasLock = $true
|
|
|
|
|
|
|
|
Write-Log "Recovered abandoned winget lock '$WingetMutexName'." 'WARN'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (-not $hasLock) {
|
|
|
|
if (-not $hasLock) {
|
|
|
|
throw "Timed out waiting for winget lock '$WingetMutexName'."
|
|
|
|
throw "Timed out waiting for winget lock '$WingetMutexName'."
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -1119,8 +1196,15 @@ function Test-WingetLockAvailable {
|
|
|
|
$mutex = New-Object System.Threading.Mutex($false, $WingetMutexName)
|
|
|
|
$mutex = New-Object System.Threading.Mutex($false, $WingetMutexName)
|
|
|
|
$hasLock = $false
|
|
|
|
$hasLock = $false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
$hasLock = $mutex.WaitOne(0)
|
|
|
|
$hasLock = $mutex.WaitOne(0)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch [System.Threading.AbandonedMutexException] {
|
|
|
|
|
|
|
|
$hasLock = $true
|
|
|
|
|
|
|
|
Write-Log "Recovered abandoned winget lock '$WingetMutexName' while checking availability." 'WARN'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return $hasLock
|
|
|
|
return $hasLock
|
|
|
|
}
|
|
|
|
}
|
|
|
|
finally {
|
|
|
|
finally {
|
|
|
@@ -2216,12 +2300,31 @@ function Load-AppList {
|
|
|
|
`$btnClose.Anchor = 'Right, Bottom'
|
|
|
|
`$btnClose.Anchor = 'Right, Bottom'
|
|
|
|
`$btnClose.Text = 'Schließen'
|
|
|
|
`$btnClose.Text = 'Schließen'
|
|
|
|
|
|
|
|
|
|
|
|
`$script:StateWatcher = `$null
|
|
|
|
function Get-CatalogFileStamp {
|
|
|
|
`$script:SnapshotWatcher = `$null
|
|
|
|
param([Parameter(Mandatory=`$true)][string]`$Path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
if (-not (Test-Path -LiteralPath `$Path -PathType Leaf)) {
|
|
|
|
|
|
|
|
return 'missing'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`$file = Get-Item -LiteralPath `$Path -Force -ErrorAction Stop
|
|
|
|
|
|
|
|
return '{0}:{1}:{2}' -f `$file.CreationTimeUtc.Ticks, `$file.LastWriteTimeUtc.Ticks, `$file.Length
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch {
|
|
|
|
|
|
|
|
return 'unavailable'
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Keep change detection on the WinForms UI thread. Direct PowerShell handlers on
|
|
|
|
|
|
|
|
# FileSystemWatcher events run on worker threads and can terminate the host when
|
|
|
|
|
|
|
|
# no PowerShell runspace is available on the callback thread.
|
|
|
|
`$stateRefreshTimer = New-Object System.Windows.Forms.Timer
|
|
|
|
`$stateRefreshTimer = New-Object System.Windows.Forms.Timer
|
|
|
|
`$stateRefreshTimer.Interval = 500
|
|
|
|
`$stateRefreshTimer.Interval = 500
|
|
|
|
`$script:StateRefreshPending = `$false
|
|
|
|
`$script:StateRefreshPending = `$false
|
|
|
|
`$script:RequestWorkerBusy = `$false
|
|
|
|
`$script:RequestWorkerBusy = `$false
|
|
|
|
|
|
|
|
`$script:LastQueueStateStamp = Get-CatalogFileStamp -Path `$QueueStatePath
|
|
|
|
|
|
|
|
`$script:LastSnapshotStamp = Get-CatalogFileStamp -Path `$InstalledPackagesPath
|
|
|
|
|
|
|
|
|
|
|
|
function Start-AppRequestAsync {
|
|
|
|
function Start-AppRequestAsync {
|
|
|
|
param(
|
|
|
|
param(
|
|
|
@@ -2391,11 +2494,22 @@ function Start-RefreshStatusAsync {
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
`$stateRefreshTimer.Add_Tick({
|
|
|
|
`$stateRefreshTimer.Add_Tick({
|
|
|
|
|
|
|
|
`$queueStateStamp = Get-CatalogFileStamp -Path `$QueueStatePath
|
|
|
|
|
|
|
|
`$snapshotStamp = Get-CatalogFileStamp -Path `$InstalledPackagesPath
|
|
|
|
|
|
|
|
if (`$queueStateStamp -ne `$script:LastQueueStateStamp -or `$snapshotStamp -ne `$script:LastSnapshotStamp) {
|
|
|
|
|
|
|
|
`$script:LastQueueStateStamp = `$queueStateStamp
|
|
|
|
|
|
|
|
`$script:LastSnapshotStamp = `$snapshotStamp
|
|
|
|
|
|
|
|
`$script:StateRefreshPending = `$true
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (-not `$script:StateRefreshPending) { return }
|
|
|
|
if (-not `$script:StateRefreshPending) { return }
|
|
|
|
if (`$script:RequestWorkerBusy) { return }
|
|
|
|
if (`$script:RequestWorkerBusy) { return }
|
|
|
|
`$script:StateRefreshPending = `$false
|
|
|
|
`$script:StateRefreshPending = `$false
|
|
|
|
try { Load-AppList }
|
|
|
|
try { Load-AppList }
|
|
|
|
catch { `$status.Text = "Fehler bei automatischer Aktualisierung: " + `$_.Exception.Message }
|
|
|
|
catch {
|
|
|
|
|
|
|
|
`$script:StateRefreshPending = `$true
|
|
|
|
|
|
|
|
`$status.Text = "Fehler bei automatischer Aktualisierung: " + `$_.Exception.Message
|
|
|
|
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
`$btnOpenLog.Add_Click({
|
|
|
|
`$btnOpenLog.Add_Click({
|
|
|
@@ -2429,44 +2543,13 @@ function Start-RefreshStatusAsync {
|
|
|
|
`$btnClose.Add_Click({ `$form.Close() })
|
|
|
|
`$btnClose.Add_Click({ `$form.Close() })
|
|
|
|
|
|
|
|
|
|
|
|
`$form.Add_Shown({
|
|
|
|
`$form.Add_Shown({
|
|
|
|
try {
|
|
|
|
`$script:LastQueueStateStamp = Get-CatalogFileStamp -Path `$QueueStatePath
|
|
|
|
`$stateDir = Split-Path -Path `$QueueStatePath -Parent
|
|
|
|
`$script:LastSnapshotStamp = Get-CatalogFileStamp -Path `$InstalledPackagesPath
|
|
|
|
`$stateFile = Split-Path -Path `$QueueStatePath -Leaf
|
|
|
|
|
|
|
|
if (Test-Path -LiteralPath `$stateDir) {
|
|
|
|
|
|
|
|
`$script:StateWatcher = New-Object System.IO.FileSystemWatcher(`$stateDir, `$stateFile)
|
|
|
|
|
|
|
|
`$script:StateWatcher.NotifyFilter = [System.IO.NotifyFilters]'LastWrite, FileName, Size'
|
|
|
|
|
|
|
|
`$script:StateWatcher.Add_Changed({ `$script:StateRefreshPending = `$true })
|
|
|
|
|
|
|
|
`$script:StateWatcher.Add_Created({ `$script:StateRefreshPending = `$true })
|
|
|
|
|
|
|
|
`$script:StateWatcher.Add_Renamed({ `$script:StateRefreshPending = `$true })
|
|
|
|
|
|
|
|
`$script:StateWatcher.EnableRaisingEvents = `$true
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch {
|
|
|
|
|
|
|
|
`$status.Text = "Statusueberwachung konnte nicht gestartet werden: " + `$_.Exception.Message
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
`$snapshotDir = Split-Path -Path `$InstalledPackagesPath -Parent
|
|
|
|
|
|
|
|
`$snapshotFile = Split-Path -Path `$InstalledPackagesPath -Leaf
|
|
|
|
|
|
|
|
if (Test-Path -LiteralPath `$snapshotDir) {
|
|
|
|
|
|
|
|
`$script:SnapshotWatcher = New-Object System.IO.FileSystemWatcher(`$snapshotDir, `$snapshotFile)
|
|
|
|
|
|
|
|
`$script:SnapshotWatcher.NotifyFilter = [System.IO.NotifyFilters]'LastWrite, FileName, Size'
|
|
|
|
|
|
|
|
`$script:SnapshotWatcher.Add_Changed({ `$script:StateRefreshPending = `$true })
|
|
|
|
|
|
|
|
`$script:SnapshotWatcher.Add_Created({ `$script:StateRefreshPending = `$true })
|
|
|
|
|
|
|
|
`$script:SnapshotWatcher.Add_Renamed({ `$script:StateRefreshPending = `$true })
|
|
|
|
|
|
|
|
`$script:SnapshotWatcher.EnableRaisingEvents = `$true
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
catch {
|
|
|
|
|
|
|
|
`$status.Text = "Snapshotueberwachung konnte nicht gestartet werden: " + `$_.Exception.Message
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
`$stateRefreshTimer.Start()
|
|
|
|
`$stateRefreshTimer.Start()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
`$form.Add_FormClosing({
|
|
|
|
`$form.Add_FormClosing({
|
|
|
|
`$stateRefreshTimer.Stop()
|
|
|
|
`$stateRefreshTimer.Stop()
|
|
|
|
`$stateRefreshTimer.Dispose()
|
|
|
|
`$stateRefreshTimer.Dispose()
|
|
|
|
if (`$null -ne `$script:StateWatcher) { `$script:StateWatcher.Dispose() }
|
|
|
|
|
|
|
|
if (`$null -ne `$script:SnapshotWatcher) { `$script:SnapshotWatcher.Dispose() }
|
|
|
|
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
`$list.Add_SelectedIndexChanged({ Update-InstallButtonState })
|
|
|
|
`$list.Add_SelectedIndexChanged({ Update-InstallButtonState })
|
|
|
@@ -2718,6 +2801,7 @@ function Invoke-WingetInstall {
|
|
|
|
$arguments = @(
|
|
|
|
$arguments = @(
|
|
|
|
'install'
|
|
|
|
'install'
|
|
|
|
'--id', $PackageId
|
|
|
|
'--id', $PackageId
|
|
|
|
|
|
|
|
'--source', $WingetSourceName
|
|
|
|
'--exact'
|
|
|
|
'--exact'
|
|
|
|
'--scope', 'machine'
|
|
|
|
'--scope', 'machine'
|
|
|
|
'--silent'
|
|
|
|
'--silent'
|
|
|
@@ -2731,12 +2815,12 @@ function Invoke-WingetInstall {
|
|
|
|
Update-QueueItemProgress -Id $QueueItemId -Stage 'Install' -StageText 'Installation läuft...' -IsIndeterminate:$true
|
|
|
|
Update-QueueItemProgress -Id $QueueItemId -Stage 'Install' -StageText 'Installation läuft...' -IsIndeterminate:$true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$outputLines = New-Object 'System.Collections.Generic.List[string]'
|
|
|
|
Set-WingetOutputEncoding
|
|
|
|
& $WingetPath @arguments 2>&1 | ForEach-Object {
|
|
|
|
& $WingetPath @arguments 2>&1 | ForEach-Object {
|
|
|
|
$line = [string]$_
|
|
|
|
$line = [string]$_
|
|
|
|
[void]$outputLines.Add($line)
|
|
|
|
$displayLine = ConvertTo-WingetOutputLine -Line $line
|
|
|
|
if ($line.Trim()) {
|
|
|
|
if ($displayLine) { Write-Log "winget: $displayLine" }
|
|
|
|
Write-Log "winget: $line"
|
|
|
|
|
|
|
|
if ($QueueItemId) {
|
|
|
|
if ($QueueItemId) {
|
|
|
|
$percent = Get-ProgressPercentFromLine -Line $line
|
|
|
|
$percent = Get-ProgressPercentFromLine -Line $line
|
|
|
|
if ($null -ne $percent) {
|
|
|
|
if ($null -ne $percent) {
|
|
|
@@ -2744,7 +2828,6 @@ function Invoke-WingetInstall {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$exitCode = $LASTEXITCODE
|
|
|
|
$exitCode = $LASTEXITCODE
|
|
|
|
|
|
|
|
|
|
|
|
return $exitCode
|
|
|
|
return $exitCode
|
|
|
@@ -2760,6 +2843,7 @@ function Invoke-WingetUninstall {
|
|
|
|
$arguments = @(
|
|
|
|
$arguments = @(
|
|
|
|
'uninstall'
|
|
|
|
'uninstall'
|
|
|
|
'--id', $PackageId
|
|
|
|
'--id', $PackageId
|
|
|
|
|
|
|
|
'--source', $WingetSourceName
|
|
|
|
'--exact'
|
|
|
|
'--exact'
|
|
|
|
'--scope', 'machine'
|
|
|
|
'--scope', 'machine'
|
|
|
|
'--silent'
|
|
|
|
'--silent'
|
|
|
@@ -2772,12 +2856,12 @@ function Invoke-WingetUninstall {
|
|
|
|
Update-QueueItemProgress -Id $QueueItemId -Stage 'Uninstall' -StageText 'Deinstallation läuft...' -IsIndeterminate:$true
|
|
|
|
Update-QueueItemProgress -Id $QueueItemId -Stage 'Uninstall' -StageText 'Deinstallation läuft...' -IsIndeterminate:$true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$outputLines = New-Object 'System.Collections.Generic.List[string]'
|
|
|
|
Set-WingetOutputEncoding
|
|
|
|
& $WingetPath @arguments 2>&1 | ForEach-Object {
|
|
|
|
& $WingetPath @arguments 2>&1 | ForEach-Object {
|
|
|
|
$line = [string]$_
|
|
|
|
$line = [string]$_
|
|
|
|
[void]$outputLines.Add($line)
|
|
|
|
$displayLine = ConvertTo-WingetOutputLine -Line $line
|
|
|
|
if ($line.Trim()) {
|
|
|
|
if ($displayLine) { Write-Log "winget: $displayLine" }
|
|
|
|
Write-Log "winget: $line"
|
|
|
|
|
|
|
|
if ($QueueItemId) {
|
|
|
|
if ($QueueItemId) {
|
|
|
|
$percent = Get-ProgressPercentFromLine -Line $line
|
|
|
|
$percent = Get-ProgressPercentFromLine -Line $line
|
|
|
|
if ($null -ne $percent) {
|
|
|
|
if ($null -ne $percent) {
|
|
|
@@ -2785,7 +2869,6 @@ function Invoke-WingetUninstall {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$exitCode = $LASTEXITCODE
|
|
|
|
$exitCode = $LASTEXITCODE
|
|
|
|
|
|
|
|
|
|
|
|
return $exitCode
|
|
|
|
return $exitCode
|
|
|
@@ -2800,6 +2883,7 @@ function Invoke-WingetUpgradeAll {
|
|
|
|
$arguments = @(
|
|
|
|
$arguments = @(
|
|
|
|
'upgrade'
|
|
|
|
'upgrade'
|
|
|
|
'--all'
|
|
|
|
'--all'
|
|
|
|
|
|
|
|
'--source', $WingetSourceName
|
|
|
|
'--scope', 'machine'
|
|
|
|
'--scope', 'machine'
|
|
|
|
'--silent'
|
|
|
|
'--silent'
|
|
|
|
'--accept-package-agreements'
|
|
|
|
'--accept-package-agreements'
|
|
|
@@ -2812,12 +2896,12 @@ function Invoke-WingetUpgradeAll {
|
|
|
|
Update-QueueItemProgress -Id $QueueItemId -Stage 'Upgrade' -StageText 'Updates laufen...' -IsIndeterminate:$true
|
|
|
|
Update-QueueItemProgress -Id $QueueItemId -Stage 'Upgrade' -StageText 'Updates laufen...' -IsIndeterminate:$true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$outputLines = New-Object 'System.Collections.Generic.List[string]'
|
|
|
|
Set-WingetOutputEncoding
|
|
|
|
& $WingetPath @arguments 2>&1 | ForEach-Object {
|
|
|
|
& $WingetPath @arguments 2>&1 | ForEach-Object {
|
|
|
|
$line = [string]$_
|
|
|
|
$line = [string]$_
|
|
|
|
[void]$outputLines.Add($line)
|
|
|
|
$displayLine = ConvertTo-WingetOutputLine -Line $line
|
|
|
|
if ($line.Trim()) {
|
|
|
|
if ($displayLine) { Write-Log "winget upgrade: $displayLine" }
|
|
|
|
Write-Log "winget upgrade: $line"
|
|
|
|
|
|
|
|
if ($QueueItemId) {
|
|
|
|
if ($QueueItemId) {
|
|
|
|
$percent = Get-ProgressPercentFromLine -Line $line
|
|
|
|
$percent = Get-ProgressPercentFromLine -Line $line
|
|
|
|
if ($null -ne $percent) {
|
|
|
|
if ($null -ne $percent) {
|
|
|
@@ -2825,7 +2909,6 @@ function Invoke-WingetUpgradeAll {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$exitCode = $LASTEXITCODE
|
|
|
|
$exitCode = $LASTEXITCODE
|
|
|
|
|
|
|
|
|
|
|
|
return $exitCode
|
|
|
|
return $exitCode
|
|
|
@@ -2846,6 +2929,7 @@ function Update-InstalledPackagesSnapshot {
|
|
|
|
$arguments = @(
|
|
|
|
$arguments = @(
|
|
|
|
'export'
|
|
|
|
'export'
|
|
|
|
'--output', $tempFile
|
|
|
|
'--output', $tempFile
|
|
|
|
|
|
|
|
'--source', $WingetSourceName
|
|
|
|
'--accept-source-agreements'
|
|
|
|
'--accept-source-agreements'
|
|
|
|
'--disable-interactivity'
|
|
|
|
'--disable-interactivity'
|
|
|
|
)
|
|
|
|
)
|
|
|
@@ -2854,15 +2938,26 @@ function Update-InstalledPackagesSnapshot {
|
|
|
|
if ($QueueItemId) {
|
|
|
|
if ($QueueItemId) {
|
|
|
|
Update-QueueItemProgress -Id $QueueItemId -Stage 'Snapshot' -StageText 'Installationsdaten werden aktualisiert...' -IsIndeterminate:$true
|
|
|
|
Update-QueueItemProgress -Id $QueueItemId -Stage 'Snapshot' -StageText 'Installationsdaten werden aktualisiert...' -IsIndeterminate:$true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Set-WingetOutputEncoding
|
|
|
|
$output = & $WingetPath @arguments 2>&1 | Out-String
|
|
|
|
$output = & $WingetPath @arguments 2>&1 | Out-String
|
|
|
|
$exitCode = $LASTEXITCODE
|
|
|
|
$exitCode = $LASTEXITCODE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$unmatchedPackageCount = 0
|
|
|
|
if ($output) {
|
|
|
|
if ($output) {
|
|
|
|
foreach ($line in ($output -split "`r?`n")) {
|
|
|
|
foreach ($line in ($output -split "`r?`n")) {
|
|
|
|
if ($line.Trim()) {
|
|
|
|
$displayLine = ConvertTo-WingetOutputLine -Line $line
|
|
|
|
Write-Log "winget export: $line"
|
|
|
|
if (-not $displayLine) { continue }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ($displayLine -match '^Installed package is not available from (?:any )?source:') {
|
|
|
|
|
|
|
|
$unmatchedPackageCount++
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Write-Log "winget export: $displayLine"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($unmatchedPackageCount -gt 0) {
|
|
|
|
|
|
|
|
Write-Log "winget export ignored $unmatchedPackageCount installed packages that are not represented in source '$WingetSourceName'."
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ($exitCode -ne 0) {
|
|
|
|
if ($exitCode -ne 0) {
|
|
|
|