mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-08-09 17:41:14 +10:00
Fix Show Installed Apps reliability and selection (#4850)
* Fix Windows PowerShell runspace cleanup callback * Fix installed app package ID matching * Synchronize installed app selection UI * Streamline installed app detection * Avoid installed app UI runspace deadlock
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
function Invoke-WPFGetInstalled {
|
||||
<#
|
||||
TODO: Add the Option to use Chocolatey as Engine
|
||||
.SYNOPSIS
|
||||
Invokes the function that gets the checkboxes to check in a new runspace
|
||||
|
||||
@@ -19,35 +18,72 @@ function Invoke-WPFGetInstalled {
|
||||
return
|
||||
}
|
||||
$managerPreference = $sync.preferences.packagemanager
|
||||
|
||||
Invoke-WPFRunspace -ParameterList @(("managerPreference", $managerPreference),("checkbox", $checkbox)) -ScriptBlock {
|
||||
param (
|
||||
[string]$checkbox,
|
||||
[string]$managerPreference
|
||||
$operation = [Hashtable]::Synchronized(@{
|
||||
Checkboxes = @()
|
||||
Error = $null
|
||||
})
|
||||
$completeAction = [Action[hashtable, string]]{
|
||||
param(
|
||||
[hashtable]$completedOperation,
|
||||
[string]$completedCheckbox
|
||||
)
|
||||
$sync.ProcessRunning = $true
|
||||
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" }
|
||||
try {
|
||||
if ($completedOperation.Error) {
|
||||
Write-WinUtilLog -Level "ERROR" -Component "Install" -Message "Get installed state failed: $($completedOperation.Error)"
|
||||
Write-Warning "Unable to get installed state: $($completedOperation.Error)"
|
||||
return
|
||||
}
|
||||
|
||||
if ($checkbox -eq "winget") {
|
||||
Write-Host "Getting Installed Programs..."
|
||||
switch ($managerPreference) {
|
||||
"Choco"{$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox "choco"; break}
|
||||
"Winget"{$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox; break}
|
||||
if ($completedCheckbox -eq "winget") {
|
||||
foreach ($checkboxName in $completedOperation.Checkboxes) {
|
||||
if (-not $sync.selectedApps.Contains($checkboxName)) {
|
||||
$sync.selectedApps.Add($checkboxName)
|
||||
}
|
||||
}
|
||||
Reset-WPFCheckBoxes -checkboxfilterpattern "WPFInstall*"
|
||||
} else {
|
||||
foreach ($checkboxName in $completedOperation.Checkboxes) {
|
||||
$sync.$checkboxName.ischecked = $True
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
$sync.ProcessRunning = $false
|
||||
Set-WinUtilTaskbaritem -state "None"
|
||||
}
|
||||
}
|
||||
|
||||
$sync.ProcessRunning = $true
|
||||
Set-WinUtilTaskbaritem -state "Indeterminate"
|
||||
try {
|
||||
Invoke-WPFRunspace -ParameterList @(
|
||||
("managerPreference", $managerPreference),
|
||||
("checkbox", $checkbox),
|
||||
("operation", $operation),
|
||||
("completeAction", $completeAction)
|
||||
) -ScriptBlock {
|
||||
param (
|
||||
[string]$checkbox,
|
||||
[string]$managerPreference,
|
||||
[hashtable]$operation,
|
||||
[Action[hashtable, string]]$completeAction
|
||||
)
|
||||
try {
|
||||
if ($checkbox -eq "winget") {
|
||||
switch ($managerPreference) {
|
||||
"Choco" { $operation.Checkboxes = @(Invoke-WinUtilCurrentSystem -CheckBox "choco"); break }
|
||||
"Winget" { $operation.Checkboxes = @(Invoke-WinUtilCurrentSystem -CheckBox $checkbox); break }
|
||||
}
|
||||
} elseif ($checkbox -eq "tweaks") {
|
||||
$operation.Checkboxes = @(Invoke-WinUtilCurrentSystem -CheckBox $checkbox)
|
||||
}
|
||||
} catch {
|
||||
$operation.Error = $_.Exception.Message
|
||||
} finally {
|
||||
$sync.Form.Dispatcher.BeginInvoke($completeAction, [object[]]@($operation, $checkbox)) | Out-Null
|
||||
}
|
||||
}
|
||||
elseif ($checkbox -eq "tweaks") {
|
||||
Write-Host "Getting Installed Tweaks..."
|
||||
$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox
|
||||
}
|
||||
|
||||
$sync.form.Dispatcher.invoke({
|
||||
foreach ($checkbox in $Checkboxes) {
|
||||
$sync.$checkbox.ischecked = $True
|
||||
}
|
||||
})
|
||||
|
||||
Write-Host "Done..."
|
||||
$sync.ProcessRunning = $false
|
||||
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" }
|
||||
} catch {
|
||||
$operation.Error = $_.Exception.Message
|
||||
$completeAction.Invoke($operation, $checkbox)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ public sealed class WinUtilRunspaceCleanupState
|
||||
|
||||
public static class WinUtilRunspaceCleanup
|
||||
{
|
||||
public static readonly System.Threading.WaitOrTimerCallback Callback = Cleanup;
|
||||
|
||||
public static void Cleanup(object state, bool timedOut)
|
||||
{
|
||||
var cleanupState = state as WinUtilRunspaceCleanupState;
|
||||
@@ -89,8 +91,7 @@ public static class WinUtilRunspaceCleanup
|
||||
$cleanupState = [WinUtilRunspaceCleanupState]::new()
|
||||
$cleanupState.PowerShell = $powershell
|
||||
$cleanupState.Handle = $handle
|
||||
$cleanupCallback = [System.Threading.WaitOrTimerCallback][WinUtilRunspaceCleanup]::Cleanup
|
||||
[System.Threading.ThreadPool]::RegisterWaitForSingleObject($handle.AsyncWaitHandle, $cleanupCallback, $cleanupState, -1, $true) | Out-Null
|
||||
[System.Threading.ThreadPool]::RegisterWaitForSingleObject($handle.AsyncWaitHandle, [WinUtilRunspaceCleanup]::Callback, $cleanupState, -1, $true) | Out-Null
|
||||
|
||||
# Return the handle
|
||||
return $handle
|
||||
|
||||
@@ -7,11 +7,21 @@ function Invoke-WPFSelectedCheckboxesUpdate ($type, $checkboxName) {
|
||||
'^WPFAppx' { 'selectedAppx' }
|
||||
}
|
||||
|
||||
$selectionChanged = $false
|
||||
if ($type -eq "Add") {
|
||||
if (-not $sync.$listName.Contains($checkboxName)) {
|
||||
$sync.$listName.Add($checkboxName)
|
||||
$selectionChanged = $true
|
||||
}
|
||||
} else {
|
||||
$sync.$listName.Remove($checkboxName)
|
||||
$selectionChanged = $sync.$listName.Remove($checkboxName)
|
||||
}
|
||||
|
||||
if ($listName -eq "selectedApps" -and $selectionChanged) {
|
||||
$sync.WPFselectedAppsButton.Content = "Selected Apps: $($sync.selectedApps.Count)"
|
||||
$sync.selectedAppsstackPanel.Children.Clear()
|
||||
$sync.selectedApps | Sort-Object | ForEach-Object {
|
||||
Add-SelectedAppsMenuItem -name $sync.configs.applicationsHashtable.$_.Content -key $_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user