mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2025-07-01 10:32:35 -05:00
Compare commits
7 Commits
25.03.03
...
27a97e4650
Author | SHA1 | Date | |
---|---|---|---|
27a97e4650 | |||
dc236b9865 | |||
f9878a3472 | |||
8fabebedf4 | |||
a9675fc91b | |||
e830ff03b1 | |||
eea96f596e |
@ -1,6 +1,5 @@
|
||||
# Import the function (adjust the path according to your setup)
|
||||
. "./functions/private/Install-WinUtilWinget.ps1"
|
||||
. "./functions/private/Test-WinUtilPackageManager.ps1"
|
||||
. "./functions/private/Get-WinUtilWingetLatest.ps1"
|
||||
|
||||
# Set up Information stream to be visible
|
||||
$InformationPreference = "Continue"
|
||||
@ -8,7 +7,20 @@ $InformationPreference = "Continue"
|
||||
Write-Host "Starting Winget installation test..." -ForegroundColor Cyan
|
||||
|
||||
try {
|
||||
Install-WinUtilWinget
|
||||
# Test the function with verbose output
|
||||
Write-Host "Attempting to run Get-WinUtilWingetLatest..." -ForegroundColor Cyan
|
||||
Get-WinUtilWingetLatest -Verbose
|
||||
|
||||
# Verify Winget is working
|
||||
if (Get-Command winget -ErrorAction SilentlyContinue) {
|
||||
Write-Host "Success! Winget is installed and accessible." -ForegroundColor Green
|
||||
|
||||
# Display Winget version
|
||||
Write-Host "`nWinget version:" -ForegroundColor Cyan
|
||||
winget --version
|
||||
} else {
|
||||
Write-Host "Warning: Winget is installed but not accessible in the current session. You may need to restart your terminal." -ForegroundColor Yellow
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Error occurred during testing: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Write-Host "Stack Trace:" -ForegroundColor Red
|
||||
|
@ -423,6 +423,26 @@
|
||||
"StartupType": "Automatic",
|
||||
"OriginalType": "Automatic"
|
||||
},
|
||||
{
|
||||
"Name": "DoSvc",
|
||||
"StartupType": "AutomaticDelayedStart",
|
||||
"OriginalType": "Automatic"
|
||||
},
|
||||
{
|
||||
"Name": "DsSvc",
|
||||
"StartupType": "Manual",
|
||||
"OriginalType": "Manual"
|
||||
},
|
||||
{
|
||||
"Name": "DsmSvc",
|
||||
"StartupType": "Manual",
|
||||
"OriginalType": "Manual"
|
||||
},
|
||||
{
|
||||
"Name": "DusmSvc",
|
||||
"StartupType": "Automatic",
|
||||
"OriginalType": "Automatic"
|
||||
},
|
||||
{
|
||||
"Name": "EFS",
|
||||
"StartupType": "Manual",
|
||||
@ -878,6 +898,11 @@
|
||||
"StartupType": "Manual",
|
||||
"OriginalType": "Manual"
|
||||
},
|
||||
{
|
||||
"Name": "SgrmBroker",
|
||||
"StartupType": "Automatic",
|
||||
"OriginalType": "Automatic"
|
||||
},
|
||||
{
|
||||
"Name": "SharedAccess",
|
||||
"StartupType": "Manual",
|
||||
@ -908,6 +933,11 @@
|
||||
"StartupType": "Manual",
|
||||
"OriginalType": "Manual"
|
||||
},
|
||||
{
|
||||
"Name": "StateRepository",
|
||||
"StartupType": "Manual",
|
||||
"OriginalType": "Automatic"
|
||||
},
|
||||
{
|
||||
"Name": "StiSvc",
|
||||
"StartupType": "Manual",
|
||||
@ -943,6 +973,11 @@
|
||||
"StartupType": "Automatic",
|
||||
"OriginalType": "Automatic"
|
||||
},
|
||||
{
|
||||
"Name": "TextInputManagementService",
|
||||
"StartupType": "Manual",
|
||||
"OriginalType": "Automatic"
|
||||
},
|
||||
{
|
||||
"Name": "Themes",
|
||||
"StartupType": "Automatic",
|
||||
|
104
functions/private/Get-WinUtilWingetLatest.ps1
Normal file
104
functions/private/Get-WinUtilWingetLatest.ps1
Normal file
@ -0,0 +1,104 @@
|
||||
function Get-WinUtilWingetLatest {
|
||||
[CmdletBinding()]
|
||||
param()
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Uses GitHub API to check for the latest release of Winget.
|
||||
.DESCRIPTION
|
||||
This function first attempts to update WinGet using winget itself, then falls back to manual installation if needed.
|
||||
#>
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
$InformationPreference = 'Continue'
|
||||
|
||||
try {
|
||||
$wingetCmd = Get-Command winget -ErrorAction Stop
|
||||
Write-Information "Attempting to update WinGet using WinGet..."
|
||||
$result = Start-Process -FilePath "`"$($wingetCmd.Source)`"" -ArgumentList "install -e --accept-source-agreements --accept-package-agreements Microsoft.AppInstaller" -Wait -NoNewWindow -PassThru
|
||||
if ($result.ExitCode -ne 0) {
|
||||
throw "WinGet update failed with exit code: $($result.ExitCode)"
|
||||
}
|
||||
return $true
|
||||
}
|
||||
catch {
|
||||
Write-Information "WinGet not found or update failed. Attempting to install from Microsoft Store..."
|
||||
try {
|
||||
# Try to close any running WinGet processes
|
||||
Get-Process -Name "DesktopAppInstaller", "winget" -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
Write-Information "Stopping running WinGet process..."
|
||||
$_.Kill()
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
# Try to load Windows Runtime assemblies more reliably
|
||||
$null = [System.Runtime.WindowsRuntime.WindowsRuntimeSystemExtensions]
|
||||
Add-Type -AssemblyName System.Runtime.WindowsRuntime
|
||||
|
||||
# Load required assemblies from Windows SDK
|
||||
$null = @(
|
||||
[Windows.Management.Deployment.PackageManager, Windows.Management.Deployment, ContentType = WindowsRuntime]
|
||||
[Windows.Foundation.Uri, Windows.Foundation, ContentType = WindowsRuntime]
|
||||
[Windows.Management.Deployment.DeploymentOptions, Windows.Management.Deployment, ContentType = WindowsRuntime]
|
||||
)
|
||||
|
||||
# Initialize PackageManager
|
||||
$packageManager = New-Object Windows.Management.Deployment.PackageManager
|
||||
|
||||
# Rest of the Microsoft Store installation logic
|
||||
$appxPackage = "https://aka.ms/getwinget"
|
||||
$uri = New-Object Windows.Foundation.Uri($appxPackage)
|
||||
$deploymentOperation = $packageManager.AddPackageAsync($uri, $null, "Add")
|
||||
|
||||
# Add timeout check for deployment operation
|
||||
$timeout = 300
|
||||
$timer = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
|
||||
while ($deploymentOperation.Status -eq 0) {
|
||||
if ($timer.Elapsed.TotalSeconds -gt $timeout) {
|
||||
throw "Installation timed out after $timeout seconds"
|
||||
}
|
||||
Start-Sleep -Milliseconds 100
|
||||
}
|
||||
|
||||
if ($deploymentOperation.Status -eq 1) {
|
||||
Write-Information "Successfully installed WinGet from Microsoft Store"
|
||||
return $true
|
||||
} else {
|
||||
throw "Installation failed with status: $($deploymentOperation.Status)"
|
||||
}
|
||||
}
|
||||
catch [System.Management.Automation.RuntimeException] {
|
||||
Write-Information "Windows Runtime components not available. Attempting manual download..."
|
||||
try {
|
||||
# Try to close any running WinGet processes
|
||||
Get-Process -Name "DesktopAppInstaller", "winget" -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
Write-Information "Stopping running WinGet process..."
|
||||
$_.Kill()
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
# Fallback to direct download from GitHub
|
||||
$apiUrl = "https://api.github.com/repos/microsoft/winget-cli/releases/latest"
|
||||
$release = Invoke-RestMethod -Uri $apiUrl
|
||||
$msixBundleUrl = ($release.assets | Where-Object { $_.name -like "*.msixbundle" }).browser_download_url
|
||||
|
||||
$tempFile = Join-Path $env:TEMP "Microsoft.DesktopAppInstaller.msixbundle"
|
||||
Invoke-WebRequest -Uri $msixBundleUrl -OutFile $tempFile
|
||||
|
||||
Add-AppxPackage -Path $tempFile -ErrorAction Stop
|
||||
Remove-Item $tempFile -Force
|
||||
|
||||
Write-Information "Successfully installed WinGet from GitHub release"
|
||||
return $true
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to install WinGet: $_"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to install WinGet: $_"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
}
|
@ -33,118 +33,18 @@ function Install-WinUtilWinget {
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "Attempting to install/update Winget`r"
|
||||
try {
|
||||
$wingetCmd = Get-Command winget -ErrorAction Stop
|
||||
Write-Information "Attempting to update WinGet using WinGet..."
|
||||
$result = Start-Process -FilePath "`"$($wingetCmd.Source)`"" -ArgumentList "install -e --accept-source-agreements --accept-package-agreements Microsoft.AppInstaller" -Wait -NoNewWindow -PassThru
|
||||
if ($result.ExitCode -ne 0) {
|
||||
throw "WinGet update failed with exit code: $($result.ExitCode)"
|
||||
}
|
||||
Write-Output "Refreshing Environment Variables...`n"
|
||||
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||
return
|
||||
} catch {
|
||||
Write-Information "WinGet not found or update failed. Attempting to install from Microsoft Store..."
|
||||
}
|
||||
try {
|
||||
# Try to close any running WinGet processes
|
||||
Get-Process -Name "DesktopAppInstaller", "winget" -ErrorAction SilentlyContinue | ForEach-Object {
|
||||
Write-Information "Stopping running WinGet process..."
|
||||
$_.Kill()
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
# Try to load Windows Runtime assemblies more reliably
|
||||
$null = [System.Runtime.WindowsRuntime.WindowsRuntimeSystemExtensions]
|
||||
Add-Type -AssemblyName System.Runtime.WindowsRuntime
|
||||
|
||||
# Load required assemblies from Windows SDK
|
||||
$null = @(
|
||||
[Windows.Management.Deployment.PackageManager, Windows.Management.Deployment, ContentType = WindowsRuntime]
|
||||
[Windows.Foundation.Uri, Windows.Foundation, ContentType = WindowsRuntime]
|
||||
[Windows.Management.Deployment.DeploymentOptions, Windows.Management.Deployment, ContentType = WindowsRuntime]
|
||||
)
|
||||
|
||||
# Initialize PackageManager
|
||||
$packageManager = New-Object Windows.Management.Deployment.PackageManager
|
||||
|
||||
# Rest of the Microsoft Store installation logic
|
||||
$appxPackage = "https://aka.ms/getwinget"
|
||||
$uri = New-Object Windows.Foundation.Uri($appxPackage)
|
||||
$deploymentOperation = $packageManager.AddPackageAsync($uri, $null, "Add")
|
||||
|
||||
# Add timeout check for deployment operation
|
||||
$timeout = 300
|
||||
$timer = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
|
||||
while ($deploymentOperation.Status -eq 0) {
|
||||
if ($timer.Elapsed.TotalSeconds -gt $timeout) {
|
||||
throw "Installation timed out after $timeout seconds"
|
||||
}
|
||||
Start-Sleep -Milliseconds 100
|
||||
}
|
||||
|
||||
if ($deploymentOperation.Status -eq 1) {
|
||||
Write-Information "Successfully installed WinGet from Microsoft Store"
|
||||
Write-Output "Refreshing Environment Variables...`n"
|
||||
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||
return
|
||||
} else {
|
||||
throw "Installation failed with status: $($deploymentOperation.Status)"
|
||||
}
|
||||
} catch {
|
||||
Write-Information "Microsoft Store installation failed. Attempting to install from Nuget..."
|
||||
}
|
||||
try {
|
||||
## Nuget Method
|
||||
Write-Host "Enabling NuGet and Module..."
|
||||
# Enable TLS 1.2 for the PowerShell session
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
# Try to register the NuGet package source if not present
|
||||
if (-not (Get-PackageSource -Name "NuGet" -ErrorAction SilentlyContinue)) {
|
||||
Register-PackageSource -Name "NuGet" -Location "https://www.nuget.org/api/v2" -ProviderName NuGet -Force
|
||||
}
|
||||
|
||||
# Install NuGet provider with error handling
|
||||
try {
|
||||
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Confirm:$false -ErrorAction Stop
|
||||
} catch {
|
||||
Write-Warning "Failed to install NuGet provider through standard method. Trying alternative approach..."
|
||||
Install-PackageProvider -Name NuGet -Source "https://www.powershellgallery.com/api/v2" -Force -Confirm:$false
|
||||
}
|
||||
Install-Module -Name Microsoft.WinGet.Client -Confirm:$false -Force
|
||||
|
||||
# Check if WinGet was installed successfully through NuGet
|
||||
$wingetCmd = Get-Command winget -ErrorAction Stop
|
||||
Write-Information "Successfully installed WinGet through NuGet"
|
||||
Write-Output "Refreshing Environment Variables...`n"
|
||||
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||
return
|
||||
} catch {
|
||||
Write-Warning "NuGet installation failed. Attempting to install from GitHub..."
|
||||
}
|
||||
# GitHub fallback installation method
|
||||
$releases_url = "https://api.github.com/repos/microsoft/winget-cli/releases/latest"
|
||||
$asset = (Invoke-RestMethod -Uri $releases_url).assets |
|
||||
Where-Object { $_.name -match "\.msixbundle$" } |
|
||||
Select-Object -First 1
|
||||
|
||||
$download_url = $asset.browser_download_url
|
||||
$output_path = Join-Path $env:TEMP $asset.name
|
||||
|
||||
Invoke-WebRequest -Uri $download_url -OutFile $output_path
|
||||
Add-AppxPackage -Path $output_path -ErrorAction Stop
|
||||
|
||||
# Verify installation
|
||||
$wingetCmd = Get-Command winget -ErrorAction Stop
|
||||
Write-Information "Successfully installed WinGet through GitHub"
|
||||
# Install Winget via GitHub method.
|
||||
# Used part of my own script with some modification: ruxunderscore/windows-initialization
|
||||
Write-Host "Downloading Winget and License File`r"
|
||||
Get-WinUtilWingetLatest
|
||||
Write-Host "Enabling NuGet and Module..."
|
||||
Install-PackageProvider -Name NuGet -Force
|
||||
Install-Module -Name Microsoft.WinGet.Client -Force
|
||||
# Winget only needs a refresh of the environment variables to be used.
|
||||
Write-Output "Refreshing Environment Variables...`n"
|
||||
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||
return
|
||||
} catch {
|
||||
Write-Error "All installation methods failed. Unable to install WinGet."
|
||||
throw
|
||||
Write-Error "Failed to install Winget: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -61,5 +61,10 @@ function Invoke-WPFButton {
|
||||
"WPFWinUtilInstallPSProfile" {Invoke-WinUtilInstallPSProfile}
|
||||
"WPFWinUtilUninstallPSProfile" {Invoke-WinUtilUninstallPSProfile}
|
||||
"WPFWinUtilSSHServer" {Invoke-WPFSSHServer}
|
||||
"WPFScanUpdates" {Invoke-WPFUpdatesScan}
|
||||
"WPFShowUpdateHistory" { Invoke-WPFUpdateHistoryToggle }
|
||||
"WPFUpdateSelectedInstall" {Invoke-WPFUpdateMGMT -Selected}
|
||||
"WPFUpdateAllInstall" {Invoke-WPFUpdateMGMT -All}
|
||||
"WPFUpdateScanHistory" {Invoke-WPFUpdateScanHistory}
|
||||
}
|
||||
}
|
||||
|
11
functions/public/Invoke-WPFUpdateHistoryToggle.ps1
Normal file
11
functions/public/Invoke-WPFUpdateHistoryToggle.ps1
Normal file
@ -0,0 +1,11 @@
|
||||
function Invoke-WPFUpdateHistoryToggle {
|
||||
if ($sync["WPFShowUpdateHistory"].Content -eq "Show History") {
|
||||
$sync["WPFShowUpdateHistory"].Content = "Show available Updates"
|
||||
$sync["HistoryGrid"].Visibility = "Visible"
|
||||
$sync["UpdatesGrid"].Visibility = "Collapsed"
|
||||
} else {
|
||||
$sync["WPFShowUpdateHistory"].Content = "Show History"
|
||||
$sync["HistoryGrid"].Visibility = "Collapsed"
|
||||
$sync["UpdatesGrid"].Visibility = "Visible"
|
||||
}
|
||||
}
|
63
functions/public/Invoke-WPFUpdateMGMGT.ps1
Normal file
63
functions/public/Invoke-WPFUpdateMGMGT.ps1
Normal file
@ -0,0 +1,63 @@
|
||||
function Invoke-WPFUpdateMGMT {
|
||||
param (
|
||||
[switch]$Selected,
|
||||
[switch]$All
|
||||
)
|
||||
|
||||
if ((-not $Selected -and -not $All) -or ($Selected -and $All)) {
|
||||
Write-Host "[Invoke-WPFUpdateMGMT] Use either 'Selected' or 'All' switches, used switches are: 'Selected' is $Selected, 'All' is $All" -ForegroundColor Red
|
||||
return
|
||||
}
|
||||
|
||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
|
||||
|
||||
if ($All) {
|
||||
Write-Host "Installing all available updates ..."
|
||||
Invoke-WPFRunspace -ArgumentList $sync["WPFUpdateVerbose"].IsChecked -DebugPreference $DebugPreference -ScriptBlock {
|
||||
param ($WPFUpdateVerbose)
|
||||
if ($WPFUpdateVerbose) {
|
||||
Install-WindowsUpdate -Verbose -Confirm:$false -IgnoreReboot:$true -IgnoreRebootRequired:$true
|
||||
} else {
|
||||
Install-WindowsUpdate -Confirm:$false -IgnoreReboot:$true -IgnoreRebootRequired:$true
|
||||
}
|
||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
|
||||
Write-Host "All Update Processes Completed"
|
||||
#catch $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" })
|
||||
}
|
||||
} elseif (($Selected) -and ($sync["WPFUpdatesList"].SelectedItems.Count -gt 0)) {
|
||||
write-host "Installing selected updates..."
|
||||
$selectedUpdates = $sync["WPFUpdatesList"].SelectedItems | ForEach-Object {
|
||||
[PSCustomObject]@{
|
||||
ComputerName = $_.ComputerName
|
||||
Title = $_.LongTitle
|
||||
KB = $_.KB
|
||||
Size = $_.Size
|
||||
}
|
||||
}
|
||||
Invoke-WPFRunspace -ParameterList @(("selectedUpdates", $selectedUpdates), ("WPFUpdateVerbose", $sync["WPFUpdateVerbose"].IsChecked)) -DebugPreference $DebugPreference -ScriptBlock {
|
||||
param ($selectedUpdates, $WPFUpdateVerbose)
|
||||
foreach ($update in $selectedUpdates) {
|
||||
Write-Host "Installing update $($update.Title) on $($update.ComputerName)"
|
||||
if ($update.KB -ne "") {
|
||||
if ($WPFUpdateVerbose) {
|
||||
Get-WindowsUpdate -ComputerName $update.ComputerName -KBArticleID $update.KB -Install -Confirm:$false -Verbose -IgnoreReboot:$true -IgnoreRebootRequired:$true
|
||||
} else {
|
||||
Get-WindowsUpdate -ComputerName $update.ComputerName -KBArticleID $update.KB -Install -Confirm:$false -IgnoreReboot:$true -IgnoreRebootRequired:$true
|
||||
}
|
||||
} else {
|
||||
if ($WPFUpdateVerbose) {
|
||||
Get-WindowsUpdate -ComputerName $update.ComputerName -Title "$($update.Title)" -Install -Confirm:$false -Verbose -IgnoreReboot:$true -IgnoreRebootRequired:$true
|
||||
} else {
|
||||
Get-WindowsUpdate -ComputerName $update.ComputerName -Title "$($update.Title)" -Install -Confirm:$false -IgnoreReboot:$true -IgnoreRebootRequired:$true
|
||||
}
|
||||
}
|
||||
}
|
||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
|
||||
Write-Host "Selected Update Processes Completed"
|
||||
#catch $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" })
|
||||
}
|
||||
} else {
|
||||
Write-Host "No updates selected"
|
||||
return
|
||||
}
|
||||
}
|
49
functions/public/Invoke-WPFUpdateScanHistory.ps1
Normal file
49
functions/public/Invoke-WPFUpdateScanHistory.ps1
Normal file
@ -0,0 +1,49 @@
|
||||
function Invoke-WPFUpdateScanHistory {
|
||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
|
||||
$sync["WPFUpdateHistory"].Items.Clear()
|
||||
Invoke-WPFRunspace -DebugPreference $DebugPreference -ScriptBlock {
|
||||
write-host "Scanning for Windows update history..."
|
||||
$UpdateHistory = Get-WUHistory -Last 50 -ErrorAction SilentlyContinue
|
||||
if ($UpdateHistory) {
|
||||
foreach ($update in $UpdateHistory) {
|
||||
$item = New-Object PSObject -Property @{
|
||||
ComputerName = $update.ComputerName
|
||||
Result = $update.Result
|
||||
Title = $update.Title -replace '\s*\(KB\d+\)', '' -replace '\s*KB\d+\b', '' # Remove KB number from title, first in parentheses, then standalone
|
||||
KB = $update.KB
|
||||
Date = $update.Date
|
||||
}
|
||||
$Computers = $item | Select-Object -ExpandProperty ComputerName -Unique
|
||||
$sync.form.Dispatcher.Invoke([action] {
|
||||
$sync["WPFUpdateHistory"].Items.Add($item)
|
||||
if ($item.Result -eq "Succeeded") {
|
||||
# does not work : $sync["WPFUpdateHistory"].Items[$sync["WPFUpdateHistory"].Items.Count - 1].Foreground = "Green"
|
||||
#write-host "$($item.Title) was successful"
|
||||
}
|
||||
elseif ($item.Result -eq "Failed") {
|
||||
# does not work : $sync["WPFUpdateHistory"].Items[$sync["WPFUpdateHistory"].Items.Count - 1].Foreground = "Red"
|
||||
#write-host "$($item.Title) failed"
|
||||
}
|
||||
})
|
||||
}
|
||||
write-host "Found $($UpdateHistory.Count) updates."
|
||||
$sync.form.Dispatcher.Invoke([action] {
|
||||
if ($Computers.Count -gt 1) {
|
||||
$sync["WPFUpdateHistory"].Columns[0].Visibility = "Visible"
|
||||
}
|
||||
else {
|
||||
Write-Debug "Hiding ComputerName column, only $item.ComputerName"
|
||||
$sync["WPFUpdateHistory"].Columns[0].Visibility = "Collapsed"
|
||||
}
|
||||
})
|
||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
|
||||
#catch $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" })
|
||||
}
|
||||
else {
|
||||
$sync.form.Dispatcher.Invoke([action] {
|
||||
$sync["WPFUpdateHistory"].Items.Clear()
|
||||
})
|
||||
Write-Host "No update history available."
|
||||
}
|
||||
}
|
||||
}
|
67
functions/public/Invoke-WPFUpdatesScan.ps1
Normal file
67
functions/public/Invoke-WPFUpdatesScan.ps1
Normal file
@ -0,0 +1,67 @@
|
||||
function Invoke-WPFUpdatesScan {
|
||||
$sync["WPFScanUpdates"].IsEnabled = $false
|
||||
$sync["WPFUpdateSelectedInstall"].IsEnabled = $false
|
||||
$sync["WPFUpdateAllInstall"].IsEnabled = $false
|
||||
Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo"
|
||||
Invoke-WPFRunspace -DebugPreference $DebugPreference -ScriptBlock {
|
||||
# Check if the PSWindowsUpdate module is installed
|
||||
if (-not (Get-Module -ListAvailable -Name PSWindowsUpdate)) {
|
||||
try {
|
||||
Write-Host "PSWindowsUpdate module not found. Attempting to install..."
|
||||
Install-Module -Name PSWindowsUpdate -Force -Scope CurrentUser
|
||||
Write-Host "PSWindowsUpdate module installed successfully."
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to install PSWindowsUpdate module: $_"
|
||||
$sync.form.Dispatcher.Invoke([action] { $sync["WPFScanUpdates"].IsEnabled = $true })
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
# Import the module
|
||||
try {
|
||||
Import-Module PSWindowsUpdate -ErrorAction Stop
|
||||
Write-Host "PSWindowsUpdate module imported successfully."
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to import PSWindowsUpdate module: $_"
|
||||
$sync.form.Dispatcher.Invoke([action] { $sync["WPFScanUpdates"].IsEnabled = $true })
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
$sync.form.Dispatcher.Invoke([action] { $sync["WPFUpdatesList"].Items.Clear() })
|
||||
Write-Host "Scanning for Windows updates..."
|
||||
$updates = Get-WindowsUpdate -ErrorAction Stop
|
||||
Write-Host "Found $($updates.Count) updates."
|
||||
|
||||
$sync.form.Dispatcher.Invoke([action] {
|
||||
foreach ($update in $updates) {
|
||||
$item = New-Object PSObject -Property @{
|
||||
LongTitle = $update.Title
|
||||
ComputerName = $update.ComputerName
|
||||
KB = $update.KB
|
||||
Size = $update.Size
|
||||
Title = $update.Title -replace '\s*\(KB\d+\)', '' -replace '\s*KB\d+\b', '' # Remove KB number from title, first in parentheses, then standalone
|
||||
Status = "Not Installed"
|
||||
}
|
||||
$Computers = $item | Select-Object -ExpandProperty ComputerName -Unique
|
||||
$sync["WPFUpdatesList"].Items.Add($item)
|
||||
}
|
||||
if ($Computers.Count -gt 1) {
|
||||
$sync["WPFUpdatesList"].Columns[0].Visibility = "Visible"
|
||||
} else {
|
||||
Write-Debug "Hiding ComputerName column, only $item.ComputerName"
|
||||
$sync["WPFUpdatesList"].Columns[0].Visibility = "Collapsed"
|
||||
}
|
||||
})
|
||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
|
||||
} catch {
|
||||
Write-Error "Error scanning for updates: $_"
|
||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" })
|
||||
}
|
||||
}
|
||||
$sync["WPFScanUpdates"].IsEnabled = $false
|
||||
$sync["WPFUpdateSelectedInstall"].IsEnabled = $false
|
||||
$sync["WPFUpdateAllInstall"].IsEnabled = $false
|
||||
}
|
@ -842,6 +842,182 @@
|
||||
</MultiDataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style TargetType="DataGrid">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource MainForegroundColor}" />
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource BorderColor}" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="FontSize" Value="{DynamicResource FontSize}" />
|
||||
<Setter Property="FontFamily" Value="{DynamicResource FontFamily}" />
|
||||
<Setter Property="RowBackground" Value="Transparent" />
|
||||
<Setter Property="AlternatingRowBackground" Value="{DynamicResource AlternatingRowBackgroundColor}" />
|
||||
<Setter Property="GridLinesVisibility" Value="None" />
|
||||
<Setter Property="HeadersVisibility" Value="Column" />
|
||||
<Setter Property="HorizontalScrollBarVisibility" Value="Auto" />
|
||||
<Setter Property="VerticalScrollBarVisibility" Value="Auto" />
|
||||
<Setter Property="SelectionMode" Value="Extended" />
|
||||
<Setter Property="SelectionUnit" Value="FullRow" />
|
||||
<Setter Property="CanUserAddRows" Value="False" />
|
||||
<Setter Property="CanUserDeleteRows" Value="False" />
|
||||
<Setter Property="CanUserReorderColumns" Value="False" />
|
||||
<Setter Property="CanUserResizeRows" Value="True" />
|
||||
<Setter Property="CanUserSortColumns" Value="True" />
|
||||
<Setter Property="AutoGenerateColumns" Value="False" />
|
||||
<Setter Property="Margin" Value="0,10,0,10" />
|
||||
<Setter Property="CellStyle">
|
||||
<Setter.Value>
|
||||
<Style TargetType="DataGridCell">
|
||||
<Setter Property="Padding" Value="10,6" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="DataGridCell">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="4"
|
||||
Margin="2,1"
|
||||
Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter VerticalAlignment="Center" />
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundMouseoverColor}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource MainForegroundColor}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundSelectedColor}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource MainForegroundColor}" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="RowStyle">
|
||||
<Setter.Value>
|
||||
<Style TargetType="DataGridRow">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource MainForegroundColor}" />
|
||||
<Setter Property="MinHeight" Value="35" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Setter Property="Margin" Value="0,1" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="DataGridRow">
|
||||
<Border x:Name="RowBorder"
|
||||
BorderThickness="0"
|
||||
BorderBrush="{DynamicResource BorderColor}"
|
||||
Background="{TemplateBinding Background}"
|
||||
CornerRadius="6"
|
||||
Margin="4,2"
|
||||
SnapsToDevicePixels="True">
|
||||
<SelectiveScrollingGrid>
|
||||
<SelectiveScrollingGrid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</SelectiveScrollingGrid.ColumnDefinitions>
|
||||
<SelectiveScrollingGrid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</SelectiveScrollingGrid.RowDefinitions>
|
||||
<DataGridCellsPresenter Grid.Column="1"
|
||||
ItemsPanel="{TemplateBinding ItemsPanel}"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
|
||||
<DataGridDetailsPresenter Grid.Column="1" Grid.Row="1"
|
||||
Visibility="{TemplateBinding DetailsVisibility}"
|
||||
SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding AreRowDetailsFrozen,
|
||||
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
|
||||
Converter={x:Static DataGrid.RowDetailsScrollingConverter},
|
||||
ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}}"/>
|
||||
<DataGridRowHeader Grid.RowSpan="2"
|
||||
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
|
||||
Visibility="{Binding HeadersVisibility,
|
||||
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
|
||||
Converter={x:Static DataGrid.HeadersVisibilityConverter},
|
||||
ConverterParameter={x:Static DataGridHeadersVisibility.Row}}"/>
|
||||
</SelectiveScrollingGrid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundMouseoverColor}" />
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect ShadowDepth="0" BlurRadius="5" Opacity="0.2" Color="#000000" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Trigger>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundSelectedColor}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource MainForegroundColor}" />
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect ShadowDepth="1" BlurRadius="7" Opacity="0.3" Color="#000000" />
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Setter Property="ColumnHeaderStyle">
|
||||
<Setter.Value>
|
||||
<Style TargetType="DataGridColumnHeader">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundColor}" />
|
||||
<Setter Property="FontSize" Value="{DynamicResource FontSize}" />
|
||||
<Setter Property="FontFamily" Value="{DynamicResource FontFamily}" />
|
||||
<Setter Property="FontWeight" Value="SemiBold" />
|
||||
<Setter Property="Padding" Value="10,8" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Left" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Setter Property="Margin" Value="2,0" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="DataGridColumnHeader">
|
||||
<Grid>
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderBrush="{DynamicResource BorderColor}"
|
||||
BorderThickness="0,0,0,1"
|
||||
Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
SnapsToDevicePixels="True" />
|
||||
</Border>
|
||||
<Path x:Name="SortArrow" Visibility="Collapsed"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="0,0,5,0" Fill="{DynamicResource ButtonForegroundColor}"
|
||||
Width="8" Height="6" Stretch="Fill" />
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="SortDirection" Value="Ascending">
|
||||
<Setter TargetName="SortArrow" Property="Visibility" Value="Visible"/>
|
||||
<Setter TargetName="SortArrow" Property="Data" Value="M 0,5 L 8,5 L 4,0 Z"/>
|
||||
</Trigger>
|
||||
<Trigger Property="SortDirection" Value="Descending">
|
||||
<Setter TargetName="SortArrow" Property="Visibility" Value="Visible"/>
|
||||
<Setter TargetName="SortArrow" Property="Data" Value="M 0,0 L 8,0 L 4,5 Z"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Foreground" Value="{DynamicResource LinkHoverForegroundColor}" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
<Grid Background="{DynamicResource MainBackgroundColor}" ShowGridLines="False" Name="WPFMainGrid" Width="Auto" Height="Auto" HorizontalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
@ -1132,100 +1308,232 @@
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
<TabItem Header="Updates" Visibility="Collapsed" Name="WPFTab4">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" Margin="{DynamicResource TabContentMargin}">
|
||||
<!-- <ScrollViewer VerticalScrollBarVisibility="Auto" Margin="{DynamicResource TabContentMargin}"> -->
|
||||
<Grid Background="Transparent">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/> <!-- Row for the 3 columns -->
|
||||
<RowDefinition Height="Auto"/> <!-- Row for Windows Version -->
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Three columns container -->
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="200"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Default Settings -->
|
||||
<Border Grid.Column="0" Style="{StaticResource BorderStyle}">
|
||||
<StackPanel>
|
||||
<!-- Left Column - Update Options -->
|
||||
<Border Grid.Column="0" Style="{StaticResource BorderStyle}" VerticalAlignment="Stretch">
|
||||
<StackPanel Margin="5">
|
||||
<TextBlock Text="Update Presets" Margin="0,0,0,5"/>
|
||||
<Button Name="WPFFixesUpdate"
|
||||
FontSize="{DynamicResource ConfigTabButtonFontSize}"
|
||||
Content="Default Settings"
|
||||
Margin="10,5"
|
||||
Padding="10"/>
|
||||
<TextBlock Margin="10"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource MainForegroundColor}">
|
||||
<Run FontWeight="Bold">Default Windows Update Configuration</Run>
|
||||
<LineBreak/>
|
||||
- No modifications to Windows defaults
|
||||
<LineBreak/>
|
||||
- Removes any custom update settings
|
||||
<LineBreak/><LineBreak/>
|
||||
<Run FontStyle="Italic" FontSize="11">Note: This resets your Windows Update settings to default out of the box settings. It removes ANY policy or customization that has been done to Windows Update.</Run>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
Content="Default"
|
||||
Width="Auto"
|
||||
Margin="0,2"
|
||||
ToolTip="Default Windows Update Configuration
- No modifications to Windows defaults
- Removes any custom update settings

Note: This resets your Windows Update settings to default out of the box settings. It removes ANY policy or customization that has been done to Windows Update."/>
|
||||
|
||||
<!-- Security Settings -->
|
||||
<Border Grid.Column="1" Style="{StaticResource BorderStyle}">
|
||||
<StackPanel>
|
||||
<Button Name="WPFUpdatessecurity"
|
||||
FontSize="{DynamicResource ConfigTabButtonFontSize}"
|
||||
Content="Security Settings"
|
||||
Margin="10,5"
|
||||
Padding="10"/>
|
||||
<TextBlock Margin="10"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource MainForegroundColor}">
|
||||
<Run FontWeight="Bold">Balanced Security Configuration</Run>
|
||||
<LineBreak/>
|
||||
- Feature updates delayed by 2 years
|
||||
<LineBreak/>
|
||||
- Security updates installed after 4 days
|
||||
<LineBreak/><LineBreak/>
|
||||
<Run FontWeight="SemiBold">Feature Updates:</Run> New features and potential bugs
|
||||
<LineBreak/>
|
||||
<Run FontWeight="SemiBold">Security Updates:</Run> Critical security patches
|
||||
<LineBreak/><LineBreak/>
|
||||
<Run FontStyle="Italic" FontSize="11">Note: This only applies to Pro systems that can use group policy.</Run>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
Content="Security"
|
||||
Width="Auto"
|
||||
Margin="0,2"
|
||||
ToolTip="Balanced Security Configuration
- Feature updates delayed by 2 years
- Security updates installed after 4 days

Feature Updates: New features and potential bugs
Security Updates: Critical security patches

Note: This only applies to Pro systems that can use group policy."/>
|
||||
|
||||
<!-- Disable Updates -->
|
||||
<Border Grid.Column="2" Style="{StaticResource BorderStyle}">
|
||||
<StackPanel>
|
||||
<Button Name="WPFUpdatesdisable"
|
||||
FontSize="{DynamicResource ConfigTabButtonFontSize}"
|
||||
Content="Disable All Updates"
|
||||
Content="Disable"
|
||||
Width="Auto"
|
||||
Foreground="Red"
|
||||
Margin="10,5"
|
||||
Padding="10"/>
|
||||
<TextBlock Margin="10"
|
||||
TextWrapping="Wrap"
|
||||
Foreground="{DynamicResource MainForegroundColor}">
|
||||
<Run FontWeight="Bold" Foreground="Red">!! Not Recommended !!</Run>
|
||||
<LineBreak/>
|
||||
- Disables ALL Windows Updates
|
||||
<LineBreak/>
|
||||
- Increases security risks
|
||||
<LineBreak/>
|
||||
- Only use for isolated systems
|
||||
<LineBreak/><LineBreak/>
|
||||
<Run FontStyle="Italic" FontSize="11">Warning: Your system will be vulnerable without security updates.</Run>
|
||||
</TextBlock>
|
||||
Margin="0,2"
|
||||
ToolTip="!! Not Recommended !!
- Disables ALL Windows Updates
- Increases security risks
- Only use for isolated systems

Warning: Your system will be vulnerable without security updates."/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Right Column - Updates List -->
|
||||
<Border Grid.Column="1" Style="{StaticResource BorderStyle}" VerticalAlignment="Stretch">
|
||||
<Grid Margin="5,0,0,0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Toggle button at the top -->
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Right" Margin="5">
|
||||
<ToggleButton Name="WPFShowUpdateHistory"
|
||||
Content="Show History"
|
||||
Style="{StaticResource ToggleButtonStyle}"
|
||||
Margin="5"
|
||||
Padding="10,5"
|
||||
ToolTip="Toggle between pending updates and update history"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Updates Grid - Visible by default -->
|
||||
<Grid Grid.Row="1" Name="UpdatesGrid" Visibility="Visible">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Button Name="WPFScanUpdates"
|
||||
Content="Scan for Updates"
|
||||
Grid.Row="0"
|
||||
Margin="5"
|
||||
HorizontalAlignment="Left"
|
||||
Padding="10,5"/>
|
||||
|
||||
<DataGrid Name="WPFUpdatesList"
|
||||
Grid.Row="1"
|
||||
Margin="5"
|
||||
AutoGenerateColumns="False"
|
||||
Background="Transparent"
|
||||
IsReadOnly="True"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="LongTitle"
|
||||
Binding="{Binding LongTitle}"
|
||||
Width="Auto"
|
||||
Visibility="Collapsed"/>
|
||||
<DataGridTextColumn Header="ComputerName"
|
||||
Binding="{Binding ComputerName}"
|
||||
Width="Auto"
|
||||
Visibility="Collapsed"/>
|
||||
<DataGridTextColumn Header="Title"
|
||||
Binding="{Binding Title}"
|
||||
Width="*"
|
||||
MinWidth="100"/>
|
||||
<DataGridTextColumn Header="KB"
|
||||
Binding="{Binding KB}"
|
||||
Width="Auto"
|
||||
MinWidth="100">
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="TextAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Header="Size"
|
||||
Binding="{Binding Size}"
|
||||
Width="Auto"
|
||||
MinWidth="80">
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="TextAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Header="Status"
|
||||
Binding="{Binding Status}"
|
||||
Width="Auto"
|
||||
MinWidth="100">
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="TextAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<StackPanel Grid.Row="2"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="5">
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<CheckBox x:Name="WPFUpdateVerbose"
|
||||
Content="Verbose Output"
|
||||
Margin="5"
|
||||
Padding="10,5"
|
||||
ToolTip="Verbose output for update installation"
|
||||
IsChecked="True"/>
|
||||
</StackPanel>
|
||||
<Button Name="WPFUpdateSelectedInstall"
|
||||
Content="Install Selected"
|
||||
Margin="5"
|
||||
Padding="10,5"/>
|
||||
<Button Name="WPFUpdateAllInstall"
|
||||
Content="Install All"
|
||||
Margin="5"
|
||||
Padding="10,5"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- History Grid - Collapsed by default -->
|
||||
<Grid Grid.Row="1" Name="HistoryGrid" Visibility="Collapsed">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Button Name="WPFUpdateScanHistory"
|
||||
Content="Scan History"
|
||||
Grid.Row="0"
|
||||
Margin="5"
|
||||
HorizontalAlignment="Left"
|
||||
Padding="10,5"/>
|
||||
|
||||
<DataGrid Name="WPFUpdateHistory"
|
||||
Grid.Row="1"
|
||||
Margin="5"
|
||||
AutoGenerateColumns="False"
|
||||
Background="Transparent"
|
||||
IsReadOnly="True"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="ComputerName"
|
||||
Binding="{Binding ComputerName}"
|
||||
Width="Auto"
|
||||
Visibility="Collapsed"/>
|
||||
|
||||
<DataGridTextColumn Header="Result"
|
||||
Binding="{Binding Result}"
|
||||
Width="Auto"
|
||||
MinWidth="100">
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="TextAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
|
||||
<DataGridTextColumn Header="Title"
|
||||
Binding="{Binding Title}"
|
||||
Width="*"/>
|
||||
|
||||
<DataGridTextColumn Header="KB"
|
||||
Binding="{Binding KB}"
|
||||
Width="Auto"
|
||||
MinWidth="100">
|
||||
<DataGridTextColumn.ElementStyle>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="TextAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.ElementStyle>
|
||||
</DataGridTextColumn>
|
||||
|
||||
<DataGridTextColumn Header="Date"
|
||||
Binding="{Binding Date}"
|
||||
Width="Auto"
|
||||
MinWidth="160">
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!-- Future Implementation: Add Windows Version to updates panel -->
|
||||
<Grid Name="updatespanel" Grid.Row="1" Background="Transparent">
|
||||
</Grid>
|
||||
<Border Grid.Row="1" Style="{StaticResource BorderStyle}">
|
||||
<StackPanel Background="{DynamicResource MainBackgroundColor}" Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Padding="10">
|
||||
Note: Updates may require a system restart to complete installation. Make sure to save any work before proceeding.
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
<!-- </ScrollViewer> -->
|
||||
</TabItem>
|
||||
<TabItem Header="MicroWin" Visibility="Collapsed" Name="WPFTab5">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" Margin="{DynamicResource TabContentMargin}">
|
||||
|
Reference in New Issue
Block a user