mirror of
https://github.com/Raphire/Win11Debloat.git
synced 2026-10-08 14:36:48 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
386ae0c581 | ||
|
|
1b84f2d6fb | ||
|
|
741f80d0b8 |
@@ -134,12 +134,10 @@
|
||||
"ApplyCompletionTitleSuccess": "Changes Applied",
|
||||
"ApplyCompletionMessageDefault": "Please note that some changes will only take effect after a reboot. Thanks for using Win11Debloat!",
|
||||
"ApplyRebootRequiredHeader": "A reboot is required for these changes to take effect:",
|
||||
"ApplyRebootRequiredWingetDeferred": "Uninstallation of {0}",
|
||||
"ApplyCompletionTitleCancelled": "Cancelled",
|
||||
"ApplyCompletionMessageCancelled": "Script execution was cancelled by the user.",
|
||||
"ApplyCompletionTitleErrors": "Changes Applied with Errors",
|
||||
"ApplyCompletionMessageVerificationUnavailable": "All changes were applied without errors, but Win11Debloat could not confirm that all selected apps were successfully uninstalled.",
|
||||
"WingetUserScopeUninstallDeferred": "WinGet could not uninstall {0} while running as administrator because it is installed for user scope. Restart the PC or sign out and back in as {1} to complete removal.",
|
||||
"ApplyCompletionMessageFailures_one": "{0} change failed. See console for details.",
|
||||
"ApplyCompletionMessageFailures_other": "{0} changes failed. See console for details.",
|
||||
"ApplyCompletionMessageReady": "Your system is ready. Thanks for using Win11Debloat!",
|
||||
|
||||
@@ -202,6 +202,13 @@
|
||||
"UndoLabel": "Enable AI features in Microsoft Edge",
|
||||
"ApplyUndoText": "Enabling AI features in Microsoft Edge"
|
||||
},
|
||||
"DisableChromeAI": {
|
||||
"Label": "Disable AI features in Google Chrome",
|
||||
"ToolTip": "Disables Google Chrome's built-in AI tools and integrations, including Gemini, AI search & suggestions, writing assistance, autofill and more. It also removes local AI models. This feature uses policies, which will lock down certain settings.",
|
||||
"ApplyText": "Disabling AI features in Google Chrome",
|
||||
"UndoLabel": "Enable AI features in Google Chrome",
|
||||
"ApplyUndoText": "Enabling AI features in Google Chrome"
|
||||
},
|
||||
"DisablePaintAI": {
|
||||
"Label": "Disable AI features in Paint",
|
||||
"ToolTip": "This will turn off AI features in Paint, such as the AI-powered image generation and editing tools. This feature uses policies, which will lock down certain settings.",
|
||||
|
||||
@@ -125,12 +125,10 @@
|
||||
"ApplyCompletionTitleSuccess": "Modifiche applicate",
|
||||
"ApplyCompletionMessageDefault": "Nota che alcune modifiche avranno effetto solo dopo il riavvio. Grazie per aver usato Win11Debloat!",
|
||||
"ApplyRebootRequiredHeader": "È necessario riavviare il sistema affinché le seguenti modifiche abbiano effetto:",
|
||||
"ApplyRebootRequiredWingetDeferred": "Disinstallazione di {0}",
|
||||
"ApplyCompletionTitleCancelled": "Annullato",
|
||||
"ApplyCompletionMessageCancelled": "L'esecuzione dello script è stata annullata dall'utente.",
|
||||
"ApplyCompletionTitleErrors": "Modifiche applicate con errori",
|
||||
"ApplyCompletionMessageVerificationUnavailable": "Tutte le modifiche sono state applicate senza errori, ma Win11Debloat non ha potuto confermare che tutte le app selezionate siano state disinstallate correttamente.",
|
||||
"WingetUserScopeUninstallDeferred": "WinGet non ha potuto disinstallare {0} con privilegi di amministratore perché è installata per l'utente. Riavvia il PC oppure esci e accedi di nuovo come {1} per completare la rimozione.",
|
||||
"ApplyCompletionMessageFailures_one": "{0} modifica non riuscita. Consulta la console per i dettagli.",
|
||||
"ApplyCompletionMessageFailures_other": "{0} modifiche non riuscite. Consulta la console per i dettagli.",
|
||||
"ApplyCompletionMessageReady": "Il sistema è pronto. Grazie per aver usato Win11Debloat!",
|
||||
|
||||
@@ -124,13 +124,11 @@
|
||||
"ApplyCreatingRestorePoint": "Systeemherstelpunt maken. Dit kan even duren...",
|
||||
"ApplyCompletionTitleSuccess": "Wijzigingen toegepast",
|
||||
"ApplyCompletionMessageDefault": "Sommige wijzigingen worden pas actief nadat je de computer opnieuw hebt opgestart. Bedankt voor het gebruik van Win11Debloat!",
|
||||
"ApplyRebootRequiredHeader": "De volgende wijzigingen vereisen een herstart:",
|
||||
"ApplyRebootRequiredWingetDeferred": "Verwijderen van {0}",
|
||||
"ApplyRebootRequiredHeader": "Start de computer opnieuw op om de volgende wijzigingen te activeren:",
|
||||
"ApplyCompletionTitleCancelled": "Geannuleerd",
|
||||
"ApplyCompletionMessageCancelled": "Het toepassen van de wijzigingen is geannuleerd.",
|
||||
"ApplyCompletionTitleErrors": "Wijzigingen toegepast met fouten",
|
||||
"ApplyCompletionMessageVerificationUnavailable": "Er zijn geen fouten gemeld, maar Win11Debloat kon niet controleren of alle geselecteerde apps zijn verwijderd.",
|
||||
"WingetUserScopeUninstallDeferred": "WinGet kon {0} niet verwijderen als administrator, omdat de app voor een gebruiker is geïnstalleerd. Start de pc opnieuw op of meld je af en weer aan als {1} om de verwijdering te voltooien.",
|
||||
"ApplyCompletionMessageFailures_one": "{0} wijziging is mislukt. Zie de console voor meer informatie.",
|
||||
"ApplyCompletionMessageFailures_other": "{0} wijzigingen zijn mislukt. Zie de console voor meer informatie.",
|
||||
"ApplyCompletionMessageReady": "Je systeem is gereed. Bedankt voor het gebruik van Win11Debloat!",
|
||||
|
||||
@@ -134,12 +134,10 @@
|
||||
"ApplyCompletionTitleSuccess": "Alterações aplicadas",
|
||||
"ApplyCompletionMessageDefault": "Observe que algumas alterações só terão efeito após uma reinicialização. Obrigado por usar o Win11Debloat!",
|
||||
"ApplyRebootRequiredHeader": "Uma reinicialização é necessária para que estas alterações tenham efeito:",
|
||||
"ApplyRebootRequiredWingetDeferred": "Desinstalação de {0}",
|
||||
"ApplyCompletionTitleCancelled": "Cancelado",
|
||||
"ApplyCompletionMessageCancelled": "A execução do script foi cancelada pelo usuário.",
|
||||
"ApplyCompletionTitleErrors": "Alterações aplicadas com erros",
|
||||
"ApplyCompletionMessageVerificationUnavailable": "Todas as alterações foram aplicadas sem erros, mas o Win11Debloat não conseguiu confirmar que todos os apps selecionados foram desinstalados com sucesso.",
|
||||
"WingetUserScopeUninstallDeferred": "O WinGet não conseguiu desinstalar {0} com privilégios de administrador porque ele está instalado para o usuário. Reinicie o PC ou saia e entre novamente como {1} para concluir a remoção.",
|
||||
"ApplyCompletionMessageFailures_one": "{0} alteração falhou. Veja o console para detalhes.",
|
||||
"ApplyCompletionMessageFailures_other": "{0} alterações falharam. Veja o console para detalhes.",
|
||||
"ApplyCompletionMessageFailures_many": "{0} de alterações falharam. Veja o console para detalhes.",
|
||||
|
||||
+11
-6
@@ -157,18 +157,23 @@
|
||||
<Setter Property="Margin" Value="8,0,8,0"/>
|
||||
</Style>
|
||||
|
||||
<!-- Column widths for the app table rows and header (dot | name | description | id) -->
|
||||
<!-- Column widths for the app table rows and header (indicator | name | description | id) -->
|
||||
<GridLength x:Key="AppTableDotColWidth">16</GridLength>
|
||||
<GridLength x:Key="AppTableNameColWidth">180</GridLength>
|
||||
<GridLength x:Key="AppTableDescColWidth">1*</GridLength>
|
||||
<GridLength x:Key="AppTableIdColWidth">261</GridLength>
|
||||
|
||||
<!-- Recommendation dot shape style for app table rows -->
|
||||
<Style x:Key="AppRecommendationDotStyle" TargetType="Ellipse">
|
||||
<!-- Recommendation indicator style shared by circles, diamonds, and triangles -->
|
||||
<Style x:Key="AppRecommendationIndicatorStyle" TargetType="Shape">
|
||||
<Setter Property="Width" Value="9"/>
|
||||
<Setter Property="Height" Value="9"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="RenderTransform">
|
||||
<Setter.Value>
|
||||
<TranslateTransform Y="1"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Container style for each dynamically-created app table row -->
|
||||
@@ -184,7 +189,7 @@
|
||||
<SolidColorBrush x:Key="ValidationErrorColor" Color="#c42b1c"/>
|
||||
<SolidColorBrush x:Key="ValidationSuccessColor" Color="#28a745"/>
|
||||
|
||||
<!-- App recommendation dot / legend colors -->
|
||||
<!-- App recommendation indicator / legend colors -->
|
||||
<SolidColorBrush x:Key="AppRecommendationSafeColor" Color="#4CAF50"/>
|
||||
<SolidColorBrush x:Key="AppRecommendationOptionalColor" Color="#FFC107"/>
|
||||
<SolidColorBrush x:Key="AppRecommendationUnsafeColor" Color="#F44336"/>
|
||||
@@ -710,12 +715,12 @@
|
||||
</StackPanel>
|
||||
<!-- Optional (default) -->
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,16,0" ToolTip="%LANG:AppLegendOptionalTooltip%">
|
||||
<Ellipse Width="9" Height="9" Fill="{DynamicResource AppRecommendationOptionalColor}" VerticalAlignment="Center" Margin="0,0,6,0"/>
|
||||
<Polygon Points="4.5,0 9,4.5 4.5,9 0,4.5" Stretch="Fill" Width="9" Height="9" Fill="{DynamicResource AppRecommendationOptionalColor}" VerticalAlignment="Center" Margin="0,0,6,0"/>
|
||||
<TextBlock Text="%LANG:AppLegendOptional%" Foreground="{DynamicResource AppFgColor}" FontSize="12" VerticalAlignment="Center" Opacity="0.8"/>
|
||||
</StackPanel>
|
||||
<!-- Not Recommended (unsafe) -->
|
||||
<StackPanel Orientation="Horizontal" ToolTip="%LANG:AppLegendNotRecommendedTooltip%">
|
||||
<Ellipse Width="9" Height="9" Fill="{DynamicResource AppRecommendationUnsafeColor}" VerticalAlignment="Center" Margin="0,0,6,0"/>
|
||||
<Polygon Points="0,9 4.5,0 9,9" Stretch="Fill" Width="9" Height="9" Fill="{DynamicResource AppRecommendationUnsafeColor}" VerticalAlignment="Center" Margin="0,0,6,0"/>
|
||||
<TextBlock Text="%LANG:AppLegendNotRecommended%" Foreground="{DynamicResource AppFgColor}" FontSize="12" VerticalAlignment="Center" Opacity="0.8"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
@@ -43,7 +43,6 @@ function Remove-SelectedApps {
|
||||
$edgeIds = @('Microsoft.Edge', 'XPFFTQ037JWMHS')
|
||||
$wingetRemovedApps = @()
|
||||
$wingetRemovalFailures = @{}
|
||||
if (-not $script:WingetDeferredRemovals) { $script:WingetDeferredRemovals = @{} }
|
||||
|
||||
Foreach ($app in $appsList) {
|
||||
if ($script:CancelRequested) { return $false }
|
||||
@@ -75,10 +74,6 @@ function Remove-SelectedApps {
|
||||
}
|
||||
|
||||
# Check whether any winget-removed apps are still present, and report errors for each one.
|
||||
if ($wingetRemovedApps.Count -gt 0) {
|
||||
$wingetRemovedApps = @($wingetRemovedApps | Where-Object { -not $script:WingetDeferredRemovals.ContainsKey($_) })
|
||||
}
|
||||
|
||||
if ($wingetRemovedApps.Count -gt 0) {
|
||||
$postRemovalList = if ($script:WingetInstalled) { Get-WingetInstalledApps -TimeOut 10 -NonBlocking } else { $null }
|
||||
$edgeForceRemoveRequested = $false
|
||||
@@ -127,10 +122,10 @@ function Remove-SelectedApps {
|
||||
Runs winget uninstall for a single app, with a bounded execution time.
|
||||
WinGet's own exit code/success reporting is unreliable and is only logged
|
||||
for diagnostics; it never causes this function to report failure. Callers
|
||||
verify removal with a post-removal inventory check instead. If WinGet blocks
|
||||
an elevated uninstall of a user-scope package, removal is deferred to the
|
||||
target user's next logon. If the User or Sysprep parameter was passed, this
|
||||
function also schedules removal for future logins.
|
||||
verify removal with a post-removal inventory check instead. This function
|
||||
only reports failure when the winget invocation itself throws a terminating
|
||||
error (e.g. it times out or cannot be started). If the User or Sysprep
|
||||
parameter was passed, also schedules removal for future logins.
|
||||
|
||||
.PARAMETER app
|
||||
The WinGet package ID to uninstall (e.g. 'Microsoft.BingNews').
|
||||
@@ -156,7 +151,6 @@ function Remove-WinGetApp {
|
||||
|
||||
$uninstallCommandSucceeded = $true
|
||||
$exitCode = $null
|
||||
$uninstallDeferred = $false
|
||||
try {
|
||||
$uninstallResult = Invoke-NonBlocking -ScriptBlock {
|
||||
param($appId)
|
||||
@@ -169,25 +163,6 @@ function Remove-WinGetApp {
|
||||
Write-WinGetUninstallOutput -Output $(if ($uninstallResult) { $uninstallResult.Output } else { $null })
|
||||
$exitCode = if ($uninstallResult) { $uninstallResult.ExitCode } else { 'unknown' }
|
||||
Write-Verbose "WinGet uninstall for $app returned exit code $exitCode."
|
||||
|
||||
# WinGet reports APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_ACTION_PROHIBITED (0x8A15007D).
|
||||
# Keep the English message check as a fallback for clients that don't return the specific code.
|
||||
$userScopeBlocked = ([string]$exitCode -eq '-1978335107') -or ([string]$exitCode -match '^0x0?8A15007D$')
|
||||
if (-not $userScopeBlocked) {
|
||||
$userScopeBlocked = @($uninstallResult.Output | Where-Object {
|
||||
$null -ne $_ -and $_.ToString() -match 'package installed for user scope cannot be uninstalled when running with administrator privileges'
|
||||
}).Count -gt 0
|
||||
}
|
||||
if ($userScopeBlocked) {
|
||||
$targetUserName = Get-RunOnceWingetTargetUserName
|
||||
|
||||
$uninstallDeferred = Set-RunOnceWingetTask -appId $app
|
||||
if ($uninstallDeferred) {
|
||||
if (-not $script:WingetDeferredRemovals) { $script:WingetDeferredRemovals = @{} }
|
||||
$script:WingetDeferredRemovals[$app] = $targetUserName
|
||||
Write-Host (Get-Translation -Key 'WingetUserScopeUninstallDeferred' -FormatArgs @($app, $targetUserName)) -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$uninstallCommandSucceeded = $false
|
||||
@@ -200,11 +175,11 @@ function Remove-WinGetApp {
|
||||
}
|
||||
|
||||
$scheduleSucceeded = $true
|
||||
if (-not $uninstallDeferred -and $script:Params.ContainsKey("User")) {
|
||||
if ($script:Params.ContainsKey("User")) {
|
||||
Write-Host "Adding scheduled task to uninstall $app for user $(Get-UserName)..."
|
||||
$scheduleSucceeded = Set-RunOnceWingetTask -appId $app
|
||||
}
|
||||
elseif (-not $uninstallDeferred -and $script:Params.ContainsKey("Sysprep")) {
|
||||
elseif ($script:Params.ContainsKey("Sysprep")) {
|
||||
Write-Host "Adding scheduled task to uninstall $app for new users..."
|
||||
$scheduleSucceeded = Set-RunOnceWingetTask -appId $app
|
||||
}
|
||||
@@ -368,11 +343,6 @@ function Request-EdgeForceRemove {
|
||||
return $false
|
||||
}
|
||||
|
||||
function Get-RunOnceWingetTargetUserName {
|
||||
if ($script:Params.ContainsKey("Sysprep")) { return "Default" }
|
||||
return Get-UserName
|
||||
}
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Dynamically sets a RunOnce registry key to schedule a winget uninstall.
|
||||
@@ -394,7 +364,7 @@ function Get-RunOnceWingetTargetUserName {
|
||||
function Set-RunOnceWingetTask {
|
||||
param([string]$appId)
|
||||
|
||||
$targetUserName = Get-RunOnceWingetTargetUserName
|
||||
$targetUserName = if ($script:Params.ContainsKey("Sysprep")) { "Default" } else { $script:Params.Item("User") }
|
||||
|
||||
# Sanitize appId for use in registry value names (backslashes are path separators)
|
||||
$safeAppId = $appId.Replace('\', '_')
|
||||
|
||||
@@ -351,7 +351,6 @@ function Invoke-AllChanges {
|
||||
$script:AppRemovalFailures = 0
|
||||
$script:FeatureFailures = 0
|
||||
$script:AppRemovalVerificationUnavailable = $false
|
||||
$script:WingetDeferredRemovals = @{}
|
||||
|
||||
# ---- Gather work items ----
|
||||
$applyIds = @()
|
||||
|
||||
@@ -431,7 +431,7 @@ function Add-AppsToMainWindow {
|
||||
$checkbox.IsChecked = $app.IsChecked
|
||||
$checkbox.Style = $Window.Resources['AppsPanelCheckBoxStyle']
|
||||
|
||||
# Build table row: Recommendation dot | Name | Description | App ID
|
||||
# Build table row: Recommendation indicator | Name | Description | App ID
|
||||
$row = New-Object System.Windows.Controls.Grid
|
||||
$row.Style = $Window.Resources['AppTableRowStyle']
|
||||
$c0 = New-Object System.Windows.Controls.ColumnDefinition; $c0.Width = $Window.Resources['AppTableDotColWidth']
|
||||
@@ -441,16 +441,30 @@ function Add-AppsToMainWindow {
|
||||
$row.ColumnDefinitions.Add($c0); $row.ColumnDefinitions.Add($c1)
|
||||
$row.ColumnDefinitions.Add($c2); $row.ColumnDefinitions.Add($c3)
|
||||
|
||||
$dot = New-Object System.Windows.Shapes.Ellipse
|
||||
$dot.Style = $Window.Resources['AppRecommendationDotStyle']
|
||||
$dot.Fill = switch ($app.Recommendation) { 'safe' { $brushSafe } 'unsafe' { $brushUnsafe } default { $brushDefault } }
|
||||
$indicator = switch ($app.Recommendation) {
|
||||
'safe' { New-Object System.Windows.Shapes.Ellipse }
|
||||
'unsafe' {
|
||||
$triangle = New-Object System.Windows.Shapes.Polygon
|
||||
$triangle.Points = [System.Windows.Media.PointCollection]::Parse('0,9 4.5,0 9,9')
|
||||
$triangle.Stretch = 'Fill'
|
||||
$triangle
|
||||
}
|
||||
default {
|
||||
$diamond = New-Object System.Windows.Shapes.Polygon
|
||||
$diamond.Points = [System.Windows.Media.PointCollection]::Parse('4.5,0 9,4.5 4.5,9 0,4.5')
|
||||
$diamond.Stretch = 'Fill'
|
||||
$diamond
|
||||
}
|
||||
}
|
||||
$indicator.Style = $Window.Resources['AppRecommendationIndicatorStyle']
|
||||
$indicator.Fill = switch ($app.Recommendation) { 'safe' { $brushSafe } 'unsafe' { $brushUnsafe } default { $brushDefault } }
|
||||
$recommendationKey = switch ($app.Recommendation) {
|
||||
'safe' { 'AppLegendRecommendedTooltip' }
|
||||
'unsafe' { 'AppLegendNotRecommendedTooltip' }
|
||||
default { 'AppLegendOptionalTooltip' }
|
||||
}
|
||||
$dot.SetResourceReference([System.Windows.FrameworkElement]::ToolTipProperty, "Language_$recommendationKey")
|
||||
[System.Windows.Controls.Grid]::SetColumn($dot, 0)
|
||||
$indicator.SetResourceReference([System.Windows.FrameworkElement]::ToolTipProperty, "Language_$recommendationKey")
|
||||
[System.Windows.Controls.Grid]::SetColumn($indicator, 0)
|
||||
|
||||
$tbName = New-Object System.Windows.Controls.TextBlock
|
||||
$tbName.Text = $app.FriendlyName
|
||||
@@ -469,7 +483,7 @@ function Add-AppsToMainWindow {
|
||||
$tbId.ToolTip = $app.AppIdDisplay
|
||||
[System.Windows.Controls.Grid]::SetColumn($tbId, 3)
|
||||
|
||||
$row.Children.Add($dot) | Out-Null
|
||||
$row.Children.Add($indicator) | Out-Null
|
||||
$row.Children.Add($tbName) | Out-Null
|
||||
$row.Children.Add($tbDesc) | Out-Null
|
||||
$row.Children.Add($tbId) | Out-Null
|
||||
|
||||
@@ -184,21 +184,6 @@ function Show-ApplyModal {
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($script:WingetDeferredRemovals -and $script:WingetDeferredRemovals.Count -gt 0) {
|
||||
foreach ($appId in @($script:WingetDeferredRemovals.Keys | Sort-Object)) {
|
||||
$tb = [System.Windows.Controls.TextBlock]::new()
|
||||
$appName = Get-Translation -Key $appId -Field 'FriendlyName' -Section 'Apps'
|
||||
$label = Get-Translation -Key 'ApplyRebootRequiredWingetDeferred' -FormatArgs @($appName)
|
||||
$tb.Text = "$([char]0x2022) $label"
|
||||
$tb.FontSize = 12
|
||||
$tb.SetResourceReference([System.Windows.Controls.TextBlock]::ForegroundProperty, "AppFgColor")
|
||||
$tb.Opacity = 0.85
|
||||
$tb.Margin = [System.Windows.Thickness]::new(0, 2, 0, 0)
|
||||
$applyRebootList.Children.Add($tb) | Out-Null
|
||||
}
|
||||
$applyRebootPanel.Visibility = 'Visible'
|
||||
}
|
||||
|
||||
$applyWindow.Dispatcher.Invoke([System.Windows.Threading.DispatcherPriority]::Render, [action]{})
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -89,4 +89,19 @@ Describe 'FeatureId parameter contracts' {
|
||||
|
||||
$missing | Should -HaveCount 0 -Because ($missing -join '; ')
|
||||
}
|
||||
|
||||
It 'has an en-US Features translation with a Label for every FeatureId' {
|
||||
$enUsPath = Join-Path $script:RepoRoot 'Config\Languages\en-US\Features.json'
|
||||
$translations = (Get-Content -LiteralPath $enUsPath -Raw | ConvertFrom-Json).Features
|
||||
$missing = @(
|
||||
foreach ($feature in $script:Features) {
|
||||
$entry = $translations.PSObject.Properties[$feature.FeatureId]
|
||||
if ($null -eq $entry -or [string]::IsNullOrWhiteSpace($entry.Value.Label)) {
|
||||
$feature.FeatureId
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
$missing | Should -HaveCount 0 -Because ($missing -join ', ')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ BeforeAll {
|
||||
function Test-AppInWingetList { param($appId, $InstalledList) $false }
|
||||
function Invoke-NonBlocking { param($ScriptBlock, $ArgumentList, $TimeoutSeconds) }
|
||||
function Get-UserName { 'Alice' }
|
||||
function Get-Translation { param($Key, $FormatArgs) if ($FormatArgs) { return "$Key $($FormatArgs -join ' ')" }; return $Key }
|
||||
function Invoke-ForceRemoveEdge {}
|
||||
function Show-MessageBox { 'No' }
|
||||
function Invoke-WithTargetUserHive { param($TargetUserName, $ScriptBlock, $ArgumentObject) }
|
||||
@@ -21,7 +20,6 @@ Describe 'Remove-SelectedApps' {
|
||||
$script:CancelRequested = $false
|
||||
$script:ApplySubStepCallback = $null
|
||||
$script:WingetInstalled = $true
|
||||
$script:WingetDeferredRemovals = @{}
|
||||
$script:AppRemovalFailures = 0
|
||||
$script:AppRemovalVerificationUnavailable = $false
|
||||
Mock Get-TargetUserForAppRemoval { 'AllUsers' }
|
||||
@@ -56,18 +54,6 @@ Describe 'Remove-SelectedApps' {
|
||||
Should -Invoke Test-AppInWingetList -Times 1 -Exactly -ParameterFilter { $appId -eq 'Winget.App' -and $InstalledList[0].Id -eq 'Other.App' }
|
||||
}
|
||||
|
||||
It 'skips immediate inventory verification for a deferred WinGet uninstall' {
|
||||
Mock Get-AppRemovalMethod { 'WinGet' }
|
||||
Mock Remove-WinGetApp {
|
||||
$script:WingetDeferredRemovals[$app] = 'Alice'
|
||||
return $true
|
||||
}
|
||||
|
||||
Remove-SelectedApps -appsList @('Winget.App') | Should -BeTrue
|
||||
|
||||
Should -Invoke Get-WingetInstalledApps -Times 0 -Exactly
|
||||
}
|
||||
|
||||
It 'stops before the first removal when cancellation is requested' {
|
||||
$script:CancelRequested = $true
|
||||
Remove-SelectedApps -appsList @('One.App')
|
||||
@@ -171,7 +157,6 @@ Describe 'Remove-WinGetApp' {
|
||||
BeforeEach {
|
||||
$script:Params = @{}
|
||||
$script:WingetInstalled = $true
|
||||
$script:WingetDeferredRemovals = @{}
|
||||
Mock Invoke-NonBlocking { [PSCustomObject]@{ Success = $true; ExitCode = 0; Output = @() } }
|
||||
Mock Set-RunOnceWingetTask { $true }
|
||||
Mock Get-UserName { 'Alice' }
|
||||
@@ -211,17 +196,6 @@ Describe 'Remove-WinGetApp' {
|
||||
}
|
||||
}
|
||||
|
||||
It 'defers a user-scope uninstall when WinGet returns the administrator-context error code' {
|
||||
Mock Invoke-NonBlocking { [PSCustomObject]@{ ExitCode = -1978335107; Output = @('localized WinGet error') } }
|
||||
|
||||
Remove-WinGetApp -app 'One.App' | Should -BeTrue
|
||||
|
||||
Should -Invoke Set-RunOnceWingetTask -Times 1 -Exactly -ParameterFilter {
|
||||
$appId -eq 'One.App'
|
||||
}
|
||||
$script:WingetDeferredRemovals['One.App'] | Should -Be 'Alice'
|
||||
}
|
||||
|
||||
It 'reports a timed-out winget uninstall and continues' {
|
||||
$script:Params = @{ User = 'Alice' }
|
||||
Mock Invoke-NonBlocking { throw 'Operation timed out after 120 seconds' }
|
||||
|
||||
@@ -9,6 +9,11 @@ BeforeAll {
|
||||
}
|
||||
|
||||
Describe 'Get-StartMenuUserNameFromPath' {
|
||||
BeforeEach {
|
||||
# Restore copies are named to the second; clear them so tests sharing $TestDrive cannot see each other's copy
|
||||
Get-ChildItem -LiteralPath $TestDrive -Filter 'Win11Debloat-StartRestore-*.bak' | Remove-Item -Force
|
||||
}
|
||||
|
||||
It 'extracts a user name from a start-menu path and falls back for unknown paths' {
|
||||
Get-StartMenuUserNameFromPath -StartMenuBinFile 'C:\Users\Alice\AppData\Local\Packages\Start\start2.bin' | Should -Be 'Alice'
|
||||
Get-StartMenuUserNameFromPath -StartMenuBinFile 'C:\Temp\start2.bin' | Should -Be 'unknown'
|
||||
|
||||
Reference in New Issue
Block a user