Compare commits

...

7 Commits

Author SHA1 Message Date
8ae328c4b5 Compile Winutil 2024-07-25 21:20:12 +00:00
1032d3d5aa Taskbaritem > Progressbar / Overlay icon / description / asset mgmt (#2309)
* Add Progress bar to some stuff

https://learn.microsoft.com/en-us/dotnet/api/system.windows.shell.taskbariteminfo?view=windowsdesktop-8.0

* add function to manage taskbar item

changed from manually setting the taskbar overlay, progressvalue and progress state to setting them through a function

* add description feature

* use Dispatcher.Invoke

* restructure, fix, additions

* fix merge conflicts

* add check to progresses

* remove progress from wiget & choco install

* fix

* polish

* fix

* Update functions/private/Set-WinUtilTaskbarItem.ps1

Co-authored-by: Mr.k <mineshtine28546271@gmail.com>

* fix syntax

* Update functions/private/Set-WinUtilTaskbarItem.ps1

Co-authored-by: Mr.k <mineshtine28546271@gmail.com>

* rework

- add overlay presets
- rework image saving & converting
- removed popup after uninstalling applications

* fix description of function

* undo winutil

* remove check.png

* Update functions/private/Set-WinUtilTaskbarItem.ps1

Co-authored-by: Mr.k <mineshtine28546271@gmail.com>

* Update functions/private/Set-WinUtilTaskbarItem.ps1

Co-authored-by: Mr.k <mineshtine28546271@gmail.com>

* rework assets directory & its usage

* fixes

- ability to set no overlay added
- added relative path to winutildir

* hotfix

* last fixes

* add comment

* remove trailing whitespaces

THX to Mr.K :)

* renamed checkmark & added warning

* last fixes

remove bitmap
remove unneeded "| out-null"

* hotfix for new commit

---------

Co-authored-by: Mr.k <mineshtine28546271@gmail.com>
2024-07-25 16:19:45 -05:00
84a84fd34d Compile Winutil 2024-07-25 21:10:23 +00:00
b23c685580 Updated DNS box (#2354) 2024-07-25 16:10:01 -05:00
214eb1d332 Compile Winutil 2024-07-25 21:09:37 +00:00
5083b84233 Added Try-Catch blocks for remaining removal tasks (#2365)
* Added Try-Catch blocks for remaining removal tasks

* Delete winutil.ps1 from tracking list

* Revert "Delete winutil.ps1 from tracking list"

This reverts commit 97044425ea.
2024-07-25 16:09:00 -05:00
4553f3e758 Added undoing tweak in FAQ (#2381)
* Added undoing tweak in FAQ

* fixed grammar

* fixed grammar... again

* Update docs/faq.md

Co-authored-by: Mr.k <mineshtine28546271@gmail.com>

---------

Co-authored-by: Mr.k <mineshtine28546271@gmail.com>
Co-authored-by: Chris Titus <contact@christitus.com>
2024-07-25 16:06:56 -05:00
20 changed files with 632 additions and 254 deletions

View File

@ -3165,7 +3165,7 @@
"panel": "1",
"Order": "a040_",
"Type": "Combobox",
"ComboItems": "Default DHCP Google Cloudflare Cloudflare_Malware Cloudflare_Malware_Adult Level3 Open_DNS Quad9"
"ComboItems": "Default DHCP Google Cloudflare Cloudflare_Malware Cloudflare_Malware_Adult Open_DNS Quad9 AdGuard_Ads_Trackers AdGuard_Ads_Trackers_Malware_Adult"
},
"WPFTweaksbutton": {
"Content": "Run Tweaks",

View File

@ -1,4 +1,7 @@
# FAQ's
## How do I uninstall WinUtil?
* You do not have to uninstall WinUtil. As it is a script you run from PowerShell, it only loads into your RAM. This means that as soon as you close WinUtil, it will be deleted from your system.
* You do not have to uninstall WinUtil. As it is a script you run from Powershell it only loads into your RAM. This means as soon as you close WinUtil it will be deleted off your system.
## I applied a tweak and now something doesn't work, what do I do?
* If you applied a tweak and it breaks something, you can always revert the tweak by selecting the tweak and clicking "Undo Selected Tweaks".

View File

@ -54,12 +54,18 @@ function Install-WinUtilProgramChoco {
}
if(($chocoInstallStatus -eq 0) -AND ($tryUpgrade -eq $false)){
Write-Host "$($Program.choco) installed successfully using Chocolatey."
$X++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value ($x/$count) })
continue
} else {
Write-Host "Failed to install $($Program.choco) using Chocolatey, Chocolatey output:`n`n$(Get-Content -Path $installOutputFilePath)."
$X++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
}
} catch {
Write-Host "Failed to install $($Program.choco) due to an error: $_"
$X++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
}
}
@ -71,15 +77,20 @@ function Install-WinUtilProgramChoco {
$chocoUninstallStatus = $(Start-Process -FilePath "choco" -ArgumentList "uninstall $($Program.choco) -y" -Wait -PassThru).ExitCode
if($chocoUninstallStatus -eq 0){
Write-Host "$($Program.choco) uninstalled successfully using Chocolatey."
$x++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value ($x/$count) })
continue
} else {
Write-Host "Failed to uninstall $($Program.choco) using Chocolatey, Chocolatey output:`n`n$(Get-Content -Path $uninstallOutputFilePath)."
$x++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
}
} catch {
Write-Host "Failed to uninstall $($Program.choco) due to an error: $_"
$x++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
}
}
$x++
}
Write-Progress -Activity "$manage Applications" -Status "Finished" -Completed

View File

@ -43,20 +43,24 @@ Function Install-WinUtilProgramWinget {
$status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode
if($status -eq 0) {
Write-Host "$($Program.winget) installed successfully."
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
continue
}
if ($status -eq -1978335189) {
Write-Host "$($Program.winget) No applicable update found"
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
continue
}
Write-Host "Attempt with User scope"
$status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --scope user --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode
if($status -eq 0) {
Write-Host "$($Program.winget) installed successfully with User scope."
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
continue
}
if ($status -eq -1978335189) {
Write-Host "$($Program.winget) No applicable update found"
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
continue
}
Write-Host "Attempt with User prompt"
@ -71,15 +75,18 @@ Function Install-WinUtilProgramWinget {
}
if($status -eq 0) {
Write-Host "$($Program.winget) installed successfully with User prompt."
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
continue
}
if ($status -eq -1978335189) {
Write-Host "$($Program.winget) No applicable update found"
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
continue
}
} catch {
Write-Host "Failed to install $($Program.winget). With winget"
$failedPackages += $Program
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
}
}
elseif($manage -eq "Uninstalling") {
@ -88,6 +95,7 @@ Function Install-WinUtilProgramWinget {
$status = $(Start-Process -FilePath "winget" -ArgumentList "uninstall --id $($Program.winget) --silent" -Wait -PassThru -NoNewWindow).ExitCode
if($status -ne 0) {
Write-Host "Failed to uninstall $($Program.winget)."
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
} else {
Write-Host "$($Program.winget) uninstalled successfully."
$failedPackages += $Program
@ -95,7 +103,9 @@ Function Install-WinUtilProgramWinget {
} catch {
Write-Host "Failed to uninstall $($Program.winget) due to an error: $_"
$failedPackages += $Program
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
}
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
}
else {
throw "[Install-WinUtilProgramWinget] Invalid Value for Parameter 'manage', Provided Value is: $manage"

View File

@ -19,6 +19,7 @@ function Install-WinUtilWinget {
Write-Host "`nWinget is not Installed. Continuing with install.`r" -ForegroundColor Red
}
# Gets the computer's information
if ($null -eq $sync.ComputerInfo){
$ComputerInfo = Get-ComputerInfo -ErrorAction Stop
@ -63,4 +64,5 @@ function Install-WinUtilWinget {
throw [WingetFailedInstall]::new('Failed to install!')
}
}
}

View File

@ -38,90 +38,104 @@ function Remove-Features([switch] $dumpFeatures = $false, [switch] $keepDefender
Remove-Features -keepDefender:$false
#>
$featlist = (Get-WindowsOptionalFeature -Path $scratchDir).FeatureName
if ($dumpFeatures)
try
{
$featlist > allfeaturesdump.txt
$featlist = (Get-WindowsOptionalFeature -Path $scratchDir).FeatureName
if ($dumpFeatures)
{
$featlist > allfeaturesdump.txt
}
$featlist = $featlist | Where-Object {
$_ -NotLike "*Printing*" -AND
$_ -NotLike "*TelnetClient*" -AND
$_ -NotLike "*PowerShell*" -AND
$_ -NotLike "*NetFx*" -AND
$_ -NotLike "*Media*" -AND
$_ -NotLike "*NFS*"
}
if ($keepDefender) { $featlist = $featlist | Where-Object { $_ -NotLike "*Defender*" }}
foreach($feature in $featlist)
{
$status = "Removing feature $feature"
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
Write-Debug "Removing feature $feature"
Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $feature -Remove -ErrorAction SilentlyContinue -NoRestart
}
Write-Progress -Activity "Removing features" -Status "Ready" -Completed
Write-Host "You can re-enable the disabled features at any time, using either Windows Update or the SxS folder in <installation media>\Sources."
}
$featlist = $featlist | Where-Object {
$_ -NotLike "*Printing*" -AND
$_ -NotLike "*TelnetClient*" -AND
$_ -NotLike "*PowerShell*" -AND
$_ -NotLike "*NetFx*" -AND
$_ -NotLike "*Media*" -AND
$_ -NotLike "*NFS*"
}
if ($keepDefender) { $featlist = $featlist | Where-Object { $_ -NotLike "*Defender*" }}
foreach($feature in $featlist)
catch
{
$status = "Removing feature $feature"
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
Write-Debug "Removing feature $feature"
Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $feature -Remove -ErrorAction SilentlyContinue -NoRestart
Write-Host "Unable to get information about the features. MicroWin processing will continue, but features will not be processed"
}
Write-Progress -Activity "Removing features" -Status "Ready" -Completed
Write-Host "You can re-enable the disabled features at any time, using either Windows Update or the SxS folder in <installation media>\Sources."
}
function Remove-Packages
{
$pkglist = (Get-WindowsPackage -Path "$scratchDir").PackageName
$pkglist = $pkglist | Where-Object {
$_ -NotLike "*ApplicationModel*" -AND
$_ -NotLike "*indows-Client-LanguagePack*" -AND
$_ -NotLike "*LanguageFeatures-Basic*" -AND
$_ -NotLike "*Package_for_ServicingStack*" -AND
$_ -NotLike "*.NET*" -AND
$_ -NotLike "*Store*" -AND
$_ -NotLike "*VCLibs*" -AND
$_ -NotLike "*AAD.BrokerPlugin",
$_ -NotLike "*LockApp*" -AND
$_ -NotLike "*Notepad*" -AND
$_ -NotLike "*immersivecontrolpanel*" -AND
$_ -NotLike "*ContentDeliveryManager*" -AND
$_ -NotLike "*PinningConfirMationDialog*" -AND
$_ -NotLike "*SecHealthUI*" -AND
$_ -NotLike "*SecureAssessmentBrowser*" -AND
$_ -NotLike "*PrintDialog*" -AND
$_ -NotLike "*AssignedAccessLockApp*" -AND
$_ -NotLike "*OOBENetworkConnectionFlow*" -AND
$_ -NotLike "*Apprep.ChxApp*" -AND
$_ -NotLike "*CBS*" -AND
$_ -NotLike "*OOBENetworkCaptivePortal*" -AND
$_ -NotLike "*PeopleExperienceHost*" -AND
$_ -NotLike "*ParentalControls*" -AND
$_ -NotLike "*Win32WebViewHost*" -AND
$_ -NotLike "*InputApp*" -AND
$_ -NotLike "*AccountsControl*" -AND
$_ -NotLike "*AsyncTextService*" -AND
$_ -NotLike "*CapturePicker*" -AND
$_ -NotLike "*CredDialogHost*" -AND
$_ -NotLike "*BioEnrollMent*" -AND
$_ -NotLike "*ShellExperienceHost*" -AND
$_ -NotLike "*DesktopAppInstaller*" -AND
$_ -NotLike "*WebMediaExtensions*" -AND
$_ -NotLike "*WMIC*" -AND
$_ -NotLike "*UI.XaML*"
}
foreach ($pkg in $pkglist)
try
{
try {
$status = "Removing $pkg"
Write-Progress -Activity "Removing Apps" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
Remove-WindowsPackage -Path "$scratchDir" -PackageName $pkg -NoRestart -ErrorAction SilentlyContinue
}
catch {
# This can happen if the package that is being removed is a permanent one, like FodMetadata
Write-Host "Could not remove OS package $($pkg)"
continue
$pkglist = (Get-WindowsPackage -Path "$scratchDir").PackageName
$pkglist = $pkglist | Where-Object {
$_ -NotLike "*ApplicationModel*" -AND
$_ -NotLike "*indows-Client-LanguagePack*" -AND
$_ -NotLike "*LanguageFeatures-Basic*" -AND
$_ -NotLike "*Package_for_ServicingStack*" -AND
$_ -NotLike "*.NET*" -AND
$_ -NotLike "*Store*" -AND
$_ -NotLike "*VCLibs*" -AND
$_ -NotLike "*AAD.BrokerPlugin",
$_ -NotLike "*LockApp*" -AND
$_ -NotLike "*Notepad*" -AND
$_ -NotLike "*immersivecontrolpanel*" -AND
$_ -NotLike "*ContentDeliveryManager*" -AND
$_ -NotLike "*PinningConfirMationDialog*" -AND
$_ -NotLike "*SecHealthUI*" -AND
$_ -NotLike "*SecureAssessmentBrowser*" -AND
$_ -NotLike "*PrintDialog*" -AND
$_ -NotLike "*AssignedAccessLockApp*" -AND
$_ -NotLike "*OOBENetworkConnectionFlow*" -AND
$_ -NotLike "*Apprep.ChxApp*" -AND
$_ -NotLike "*CBS*" -AND
$_ -NotLike "*OOBENetworkCaptivePortal*" -AND
$_ -NotLike "*PeopleExperienceHost*" -AND
$_ -NotLike "*ParentalControls*" -AND
$_ -NotLike "*Win32WebViewHost*" -AND
$_ -NotLike "*InputApp*" -AND
$_ -NotLike "*AccountsControl*" -AND
$_ -NotLike "*AsyncTextService*" -AND
$_ -NotLike "*CapturePicker*" -AND
$_ -NotLike "*CredDialogHost*" -AND
$_ -NotLike "*BioEnrollMent*" -AND
$_ -NotLike "*ShellExperienceHost*" -AND
$_ -NotLike "*DesktopAppInstaller*" -AND
$_ -NotLike "*WebMediaExtensions*" -AND
$_ -NotLike "*WMIC*" -AND
$_ -NotLike "*UI.XaML*"
}
foreach ($pkg in $pkglist)
{
try {
$status = "Removing $pkg"
Write-Progress -Activity "Removing Apps" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
Remove-WindowsPackage -Path "$scratchDir" -PackageName $pkg -NoRestart -ErrorAction SilentlyContinue
}
catch {
# This can happen if the package that is being removed is a permanent one, like FodMetadata
Write-Host "Could not remove OS package $($pkg)"
continue
}
}
Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed
}
catch
{
Write-Host "Unable to get information about the packages. MicroWin processing will continue, but packages will not be processed"
}
Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed
}
function Remove-ProvisionedPackages([switch] $keepSecurity = $false)

View File

@ -10,6 +10,8 @@ function Invoke-WinUtilFeatureInstall {
$CheckBox
)
$x = 0
$CheckBox | ForEach-Object {
if($sync.configs.feature.$psitem.feature){
Foreach( $feature in $sync.configs.feature.$psitem.feature ){
@ -20,9 +22,11 @@ function Invoke-WinUtilFeatureInstall {
Catch{
if ($psitem.Exception.Message -like "*requires elevation*"){
Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?"
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
}
else{
Write-Warning "Unable to Install $feature due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
@ -40,14 +44,18 @@ function Invoke-WinUtilFeatureInstall {
Catch{
if ($psitem.Exception.Message -like "*requires elevation*"){
Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?"
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
}
else{
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
Write-Warning "Unable to Install $feature due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
}
}
}
$X++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$CheckBox.Count) })
}
}

View File

@ -0,0 +1,86 @@
function Set-WinUtilTaskbaritem {
<#
.SYNOPSIS
Modifies the Taskbaritem of the WPF Form
.PARAMETER value
Value can be between 0 and 1, 0 being no progress done yet and 1 being fully completed
Value does not affect item without setting the state to 'Normal', 'Error' or 'Paused'
Set-WinUtilTaskbaritem -value 0.5
.PARAMETER state
State can be 'None' > No progress, 'Indeterminate' > inf. loading gray, 'Normal' > Gray, 'Error' > Red, 'Paused' > Yellow
no value needed:
- Set-WinUtilTaskbaritem -state "None"
- Set-WinUtilTaskbaritem -state "Indeterminate"
value needed:
- Set-WinUtilTaskbaritem -state "Error"
- Set-WinUtilTaskbaritem -state "Normal"
- Set-WinUtilTaskbaritem -state "Paused"
.PARAMETER overlay
Overlay icon to display on the taskbar item, there are the presets 'None', 'logo' and 'checkmark' or you can specify a path/link to an image file.
CTT logo preset:
- Set-WinUtilTaskbaritem -overlay "logo"
Checkmark preset:
- Set-WinUtilTaskbaritem -overlay "checkmark"
Warning preset:
- Set-WinUtilTaskbaritem -overlay "warning"
No overlay:
- Set-WinUtilTaskbaritem -overlay "None"
Custom icon (needs to be supported by WPF):
- Set-WinUtilTaskbaritem -overlay "C:\path\to\icon.png"
.PARAMETER description
Description to display on the taskbar item preview
Set-WinUtilTaskbaritem -description "This is a description"
#>
param (
[string]$state,
[double]$value,
[string]$overlay,
[string]$description
)
if ($value) {
$sync["Form"].taskbarItemInfo.ProgressValue = $value
}
if ($state) {
switch ($state) {
'None' { $sync["Form"].taskbarItemInfo.ProgressState = "None" }
'Indeterminate' { $sync["Form"].taskbarItemInfo.ProgressState = "Indeterminate" }
'Normal' { $sync["Form"].taskbarItemInfo.ProgressState = "Normal" }
'Error' { $sync["Form"].taskbarItemInfo.ProgressState = "Error" }
'Paused' { $sync["Form"].taskbarItemInfo.ProgressState = "Paused" }
default { throw "[Set-WinUtilTaskbarItem] Invalid state" }
}
}
if ($overlay) {
switch ($overlay) {
'logo' {
$sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\cttlogo.png"
}
'checkmark' {
$sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\checkmark.png"
}
'warning' {
$sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\warning.png"
}
'None' {
$sync["Form"].taskbarItemInfo.Overlay = $null
}
default {
if (Test-Path $overlay) {
$sync["Form"].taskbarItemInfo.Overlay = $overlay
}
}
}
}
if ($description) {
$sync["Form"].taskbarItemInfo.Description = $description
}
}

View File

@ -16,12 +16,18 @@ function Invoke-WPFFeatureInstall {
Invoke-WPFRunspace -ArgumentList $Features -DebugPreference $DebugPreference -ScriptBlock {
param($Features, $DebugPreference)
$sync.ProcessRunning = $true
if ($Features.count -eq 1){
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
Invoke-WinUtilFeatureInstall $Features
$sync.ProcessRunning = $false
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
Write-Host "==================================="
Write-Host "--- Features are Installed ---"
Write-Host "--- A Reboot may be required ---"

View File

@ -24,6 +24,7 @@ function Invoke-WPFGetInstalled {
param($checkbox, $DebugPreference)
$sync.ProcessRunning = $true
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" })
if($checkbox -eq "winget"){
Write-Host "Getting Installed Programs..."
@ -42,5 +43,6 @@ function Invoke-WPFGetInstalled {
Write-Host "Done..."
$sync.ProcessRunning = $false
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "None" })
}
}

View File

@ -16,6 +16,7 @@ function Invoke-WPFGetIso {
$sync.BusyText.Text="N Busy"
Write-Host " _ __ __ _ "
Write-Host " /\/\ (_) ___ _ __ ___ / / /\ \ \(_) _ __ "
Write-Host " / \ | | / __|| '__| / _ \ \ \/ \/ /| || '_ \ "
@ -88,6 +89,8 @@ function Invoke-WPFGetIso {
return
}
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
# Detect the file size of the ISO and compare it with the free space of the system drive
$isoSize = (Get-Item -Path $filePath).Length
Write-Debug "Size of ISO file: $($isoSize) bytes"
@ -104,6 +107,7 @@ function Invoke-WPFGetIso {
{
# It's critical and we can't continue. Output an error
Write-Host "You don't have enough space for this operation. You need at least $([Math]::Round(($isoSize / ([Math]::Pow(1024, 2))) * 2, 2)) MB of free space to copy the ISO files to a temp directory and to be able to perform additional operations."
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
else
@ -122,6 +126,7 @@ function Invoke-WPFGetIso {
Write-Error "Failed to mount the image. Error: $($_.Exception.Message)"
Write-Error "This is NOT winutil's problem, your ISO might be corrupt, or there is a problem on the system"
Write-Error "Please refer to this wiki for more details https://github.com/ChrisTitusTech/winutil/blob/main/wiki/Error-in-Winutil-MicroWin-during-ISO-mounting%2Cmd"
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
# storing off values in hidden fields for further steps
@ -199,6 +204,7 @@ function Invoke-WPFGetIso {
$msg = "Neither install.wim nor install.esd exist in the image, this could happen if you use unofficial Windows images. Please don't use shady images from the internet, use only official images. Here are instructions how to download ISO images if the Microsoft website is not showing the link to download and ISO. https://www.techrepublic.com/article/how-to-download-a-windows-10-iso-file-without-using-the-media-creation-tool/"
Write-Host $msg
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
throw
}
elseif ((-not (Test-Path -Path $wimFile -PathType Leaf)) -and (Test-Path -Path $wimFile.Replace(".wim", ".esd").Trim() -PathType Leaf))
@ -239,6 +245,7 @@ function Invoke-WPFGetIso {
$sync.BusyMessage.Visibility="Hidden"
$sync.ProcessRunning = $false
Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"
}

View File

@ -20,8 +20,14 @@ function Invoke-WPFInstall {
return
}
Invoke-WPFRunspace -ArgumentList $PackagesToInstall -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $DebugPreference)
if ($PackagesToInstall.count -eq 1){
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
$packagesWinget, $packagesChoco = {
$packagesWinget = [System.Collections.Generic.List`1[System.Object]]::new()
$packagesChoco = [System.Collections.Generic.List`1[System.Object]]::new()
@ -52,13 +58,14 @@ function Invoke-WPFInstall {
Write-Host "==========================================="
Write-Host "-- Installs have finished ---"
Write-Host "==========================================="
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
}
Catch {
Write-Host "==========================================="
Write-Host "Error: $_"
Write-Host "==========================================="
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" })
}
Start-Sleep -Seconds 5
$sync.ProcessRunning = $False
}
}

View File

@ -15,6 +15,8 @@ function Invoke-WPFInstallUpgrade {
return
}
# Set-WinUtilTaskbaritem -state "Indeterminate"
Update-WinUtilProgramWinget
Write-Host "==========================================="

View File

@ -4,6 +4,7 @@ function Invoke-WPFMicrowin {
Invoke MicroWin routines...
#>
if($sync.ProcessRunning) {
$msg = "GetIso process is currently running."
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
@ -39,9 +40,12 @@ public class PowerManagement {
if ($SaveDialog.FileName -eq "") {
Write-Host "No file name for the target image was specified"
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
Write-Host "Target ISO location: $($SaveDialog.FileName)"
$index = $sync.MicrowinWindowsFlavors.SelectedValue.Split(":")[0].Trim()
@ -74,6 +78,7 @@ public class PowerManagement {
$msg = "The export process has failed and MicroWin processing cannot continue"
Write-Host "Failed to export the image"
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
}
@ -87,6 +92,7 @@ public class PowerManagement {
$dlg_msg = $msg + "`n`nIf you want more information, the version of the image selected is $($imgVersion)`n`nIf an image has been incorrectly marked as incompatible, report an issue to the developers."
Write-Host $msg
[System.Windows.MessageBox]::Show($dlg_msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Exclamation)
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
@ -95,6 +101,7 @@ public class PowerManagement {
if (-not $mountDirExists -or -not $scratchDirExists)
{
Write-Error "Required directories '$mountDirExists' '$scratchDirExists' and do not exist."
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
@ -109,6 +116,7 @@ public class PowerManagement {
else
{
Write-Host "Could not mount image. Exiting..."
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
@ -378,6 +386,7 @@ public class PowerManagement {
if (-not (Test-Path -Path "$mountDir\sources\install.wim"))
{
Write-Error "Something went wrong and '$mountDir\sources\install.wim' doesn't exist. Please report this bug to the devs"
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
Write-Host "Windows image completed. Continuing with boot.wim."
@ -479,6 +488,7 @@ public class PowerManagement {
#$msg = "Done. ISO image is located here: $env:temp\microwin.iso"
$msg = "Done. ISO image is located here: $($SaveDialog.FileName)"
Write-Host $msg
Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
} else {
Write-Host "ISO creation failed. The "$($mountDir)" directory has not been removed."

View File

@ -17,8 +17,8 @@ function Invoke-WPFShortcut {
[bool]$RunAsAdmin = $false
)
# add an a Custom Icon if it's available at "$env:TEMP\cttlogo.png", else don't add a Custom Icon.
$iconPath = $null
# Preper the Shortcut Fields and add an a Custom Icon if it's available, else don't add a Custom Icon.
Switch ($ShortcutToAdd) {
"WinUtil" {
# Use Powershell 7 if installed and fallback to PS5 if not
@ -33,12 +33,6 @@ function Invoke-WPFShortcut {
$DestinationName = "WinUtil.lnk"
Invoke-WebRequest -Uri "https://christitus.com/images/logo-full.png" -OutFile "$env:TEMP\cttlogo.png"
if (Test-Path -Path "$env:TEMP\cttlogo.png") {
$iconPath = "$env:LOCALAPPDATA\winutil\cttlogo.ico"
ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath $iconPath
}
}
}
@ -58,10 +52,10 @@ function Invoke-WPFShortcut {
# Prepare the Shortcut paramter
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut($FileBrowser.FileName)
$Shortcut.TargetPath = $shell
$Shortcut.Arguments = $shellArgs
if ($null -ne $iconPath) {
$shortcut.IconLocation = $iconPath
$Shortcut.TargetPath = $SourceExe
$Shortcut.Arguments = $ArgumentsToSourceExe
if (Test-Path -Path $winutildir["logo.ico"]) {
$shortcut.IconLocation = $winutildir["logo.ico"]
}
# Save the Shortcut to disk

View File

@ -29,8 +29,14 @@ function Invoke-WPFUnInstall {
if($confirm -eq "No"){return}
Invoke-WPFRunspace -ArgumentList $PackagesToInstall -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $DebugPreference)
if ($PackagesToInstall.count -eq 1){
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
$packagesWinget, $packagesChoco = {
$packagesWinget = [System.Collections.Generic.List`1[System.Object]]::new()
$packagesChoco = [System.Collections.Generic.List`1[System.Object]]::new()
@ -56,22 +62,20 @@ function Invoke-WPFUnInstall {
Install-WinUtilProgramChoco -ProgramsToInstall $packagesChoco -Manage "Uninstalling"
}
$ButtonType = [System.Windows.MessageBoxButton]::OK
$MessageboxTitle = "Uninstalls are Finished "
$Messageboxbody = ("Done")
$MessageIcon = [System.Windows.MessageBoxImage]::Information
[System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon)
Write-Host "==========================================="
Write-Host "-- Uninstalls have finished ---"
Write-Host "==========================================="
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
}
Catch {
Write-Host "==========================================="
Write-Host "Error: $_"
Write-Host "==========================================="
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" })
}
$sync.ProcessRunning = $False
}
}

View File

@ -30,15 +30,22 @@ function Invoke-WPFtweaksbutton {
$sync.ProcessRunning = $true
if ($Tweaks.count -eq 1){
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
$cnt = 0
# Execute other selected tweaks
foreach ($tweak in $Tweaks) {
Write-Debug "This is a tweak to run $tweak count: $cnt"
Invoke-WinUtilTweaks $tweak
$cnt += 1
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($cnt/$Tweaks.Count) })
}
$sync.ProcessRunning = $false
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
Write-Host "================================="
Write-Host "-- Tweaks are Finished ---"
Write-Host "================================="

View File

@ -24,12 +24,21 @@ function Invoke-WPFundoall {
param($Tweaks, $DebugPreference)
$sync.ProcessRunning = $true
if ($Tweaks.count -eq 1){
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
$cnt = 0
Foreach ($tweak in $tweaks){
Invoke-WinUtilTweaks $tweak -undo $true
$cnt += 1
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($cnt/$Tweaks.Count) })
}
$sync.ProcessRunning = $false
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
Write-Host "=================================="
Write-Host "--- Undo Tweaks are Finished ---"
Write-Host "=================================="

View File

@ -154,6 +154,10 @@ Invoke-WPFRunspace -ScriptBlock {
# Print the logo
Invoke-WPFFormVariables
# Progress bar in taskbaritem > Set-WinUtilProgressbar
$sync["Form"].TaskbarItemInfo = New-Object System.Windows.Shell.TaskbarItemInfo
Set-WinUtilTaskbaritem -state "None"
# Set the titlebar
$sync["Form"].title = $sync["Form"].title + " " + $sync.version
# Set the commands that will run when the form is closed
@ -288,38 +292,6 @@ Add-Type @"
}
}
# Using a TaskbarItem Overlay until someone figures out how to replace the icon correctly
# URL of the image
$imageUrl = "https://christitus.com/images/logo-full.png"
# Download the image
$imagePath = "$env:TEMP\logo-full.png"
Invoke-WebRequest -Uri $imageUrl -OutFile $imagePath
# Read the image file as a byte array
$imageBytes = [System.IO.File]::ReadAllBytes($imagePath)
# Convert the byte array to a Base64 string
$base64String = [System.Convert]::ToBase64String($imageBytes)
# Create a streaming image by streaming the base64 string to a bitmap streamsource
$bitmap = New-Object System.Windows.Media.Imaging.BitmapImage
$bitmap.BeginInit()
$bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($base64String)
$bitmap.EndInit()
$bitmap.Freeze()
# Ensure TaskbarItemInfo is created if not already
if (-not $sync["Form"].TaskbarItemInfo) {
$sync["Form"].TaskbarItemInfo = New-Object System.Windows.Shell.TaskbarItemInfo
}
# Set the overlay icon for the taskbar
$sync["Form"].TaskbarItemInfo.Overlay = $bitmap
$rect = New-Object RECT
[Window]::GetWindowRect($windowHandle, [ref]$rect)
$width = $rect.Right - $rect.Left
@ -458,6 +430,42 @@ $sync["SearchBar"].Add_TextChanged({
$label.Visibility = "Collapsed"}
})
# Initialize the hashtable
$winutildir = @{}
# Set the path for the winutil directory
$winutildir["path"] = "$env:LOCALAPPDATA\winutil\"
if (-NOT (Test-Path -Path $winutildir["path"])) {
New-Item -Path $winutildir["path"] -ItemType Directory
}
# Set the path for the logo and checkmark images
$winutildir["logo.png"] = $winutildir["path"] + "cttlogo.png"
$winutildir["logo.ico"] = $winutildir["path"] + "cttlogo.ico"
if (-NOT (Test-Path -Path $winutildir["logo.png"])) {
Invoke-WebRequest -Uri "https://christitus.com/images/logo-full.png" -OutFile $winutildir["logo.png"]
}
if (-NOT (Test-Path -Path $winutildir["logo.ico"])) {
ConvertTo-Icon -bitmapPath $winutildir["logo.png"] -iconPath $winutildir["logo.ico"]
}
$winutildir["checkmark.png"] = $winutildir["path"] + "checkmark.png"
$winutildir["warning.png"] = $winutildir["path"] + "warning.png"
if (-NOT (Test-Path -Path $winutildir["checkmark.png"])) {
Invoke-WebRequest -Uri "https://christitus.com/images/checkmark.png" -OutFile $winutildir["checkmark.png"]
}
if (-NOT (Test-Path -Path $winutildir["warning.png"])) {
Invoke-WebRequest -Uri "https://christitus.com/images/warning.png" -OutFile $winutildir["warning.png"]
}
Set-WinUtilTaskbaritem -overlay "logo"
$sync["Form"].Add_Activated({
Set-WinUtilTaskbaritem -overlay "logo"
})
# Define event handler for button click
$sync["SettingsButton"].Add_Click({
Write-Debug "SettingsButton clicked"

View File

@ -942,12 +942,18 @@ function Install-WinUtilProgramChoco {
}
if(($chocoInstallStatus -eq 0) -AND ($tryUpgrade -eq $false)){
Write-Host "$($Program.choco) installed successfully using Chocolatey."
$X++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value ($x/$count) })
continue
} else {
Write-Host "Failed to install $($Program.choco) using Chocolatey, Chocolatey output:`n`n$(Get-Content -Path $installOutputFilePath)."
$X++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
}
} catch {
Write-Host "Failed to install $($Program.choco) due to an error: $_"
$X++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
}
}
@ -959,15 +965,20 @@ function Install-WinUtilProgramChoco {
$chocoUninstallStatus = $(Start-Process -FilePath "choco" -ArgumentList "uninstall $($Program.choco) -y" -Wait -PassThru).ExitCode
if($chocoUninstallStatus -eq 0){
Write-Host "$($Program.choco) uninstalled successfully using Chocolatey."
$x++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value ($x/$count) })
continue
} else {
Write-Host "Failed to uninstall $($Program.choco) using Chocolatey, Chocolatey output:`n`n$(Get-Content -Path $uninstallOutputFilePath)."
$x++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
}
} catch {
Write-Host "Failed to uninstall $($Program.choco) due to an error: $_"
$x++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
}
}
$x++
}
Write-Progress -Activity "$manage Applications" -Status "Finished" -Completed
@ -1022,20 +1033,24 @@ Function Install-WinUtilProgramWinget {
$status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode
if($status -eq 0) {
Write-Host "$($Program.winget) installed successfully."
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
continue
}
if ($status -eq -1978335189) {
Write-Host "$($Program.winget) No applicable update found"
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
continue
}
Write-Host "Attempt with User scope"
$status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --scope user --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode
if($status -eq 0) {
Write-Host "$($Program.winget) installed successfully with User scope."
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
continue
}
if ($status -eq -1978335189) {
Write-Host "$($Program.winget) No applicable update found"
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
continue
}
Write-Host "Attempt with User prompt"
@ -1050,15 +1065,18 @@ Function Install-WinUtilProgramWinget {
}
if($status -eq 0) {
Write-Host "$($Program.winget) installed successfully with User prompt."
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
continue
}
if ($status -eq -1978335189) {
Write-Host "$($Program.winget) No applicable update found"
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
continue
}
} catch {
Write-Host "Failed to install $($Program.winget). With winget"
$failedPackages += $Program
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
}
}
elseif($manage -eq "Uninstalling") {
@ -1067,6 +1085,7 @@ Function Install-WinUtilProgramWinget {
$status = $(Start-Process -FilePath "winget" -ArgumentList "uninstall --id $($Program.winget) --silent" -Wait -PassThru -NoNewWindow).ExitCode
if($status -ne 0) {
Write-Host "Failed to uninstall $($Program.winget)."
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
} else {
Write-Host "$($Program.winget) uninstalled successfully."
$failedPackages += $Program
@ -1074,7 +1093,9 @@ Function Install-WinUtilProgramWinget {
} catch {
Write-Host "Failed to uninstall $($Program.winget) due to an error: $_"
$failedPackages += $Program
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
}
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
}
else {
throw "[Install-WinUtilProgramWinget] Invalid Value for Parameter 'manage', Provided Value is: $manage"
@ -1104,6 +1125,7 @@ function Install-WinUtilWinget {
Write-Host "`nWinget is not Installed. Continuing with install.`r" -ForegroundColor Red
}
# Gets the computer's information
if ($null -eq $sync.ComputerInfo){
$ComputerInfo = Get-ComputerInfo -ErrorAction Stop
@ -1148,6 +1170,7 @@ function Install-WinUtilWinget {
throw [WingetFailedInstall]::new('Failed to install!')
}
}
}
function Test-CompatibleImage() {
<#
@ -1189,90 +1212,104 @@ function Remove-Features([switch] $dumpFeatures = $false, [switch] $keepDefender
Remove-Features -keepDefender:$false
#>
$featlist = (Get-WindowsOptionalFeature -Path $scratchDir).FeatureName
if ($dumpFeatures)
try
{
$featlist > allfeaturesdump.txt
$featlist = (Get-WindowsOptionalFeature -Path $scratchDir).FeatureName
if ($dumpFeatures)
{
$featlist > allfeaturesdump.txt
}
$featlist = $featlist | Where-Object {
$_ -NotLike "*Printing*" -AND
$_ -NotLike "*TelnetClient*" -AND
$_ -NotLike "*PowerShell*" -AND
$_ -NotLike "*NetFx*" -AND
$_ -NotLike "*Media*" -AND
$_ -NotLike "*NFS*"
}
if ($keepDefender) { $featlist = $featlist | Where-Object { $_ -NotLike "*Defender*" }}
foreach($feature in $featlist)
{
$status = "Removing feature $feature"
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
Write-Debug "Removing feature $feature"
Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $feature -Remove -ErrorAction SilentlyContinue -NoRestart
}
Write-Progress -Activity "Removing features" -Status "Ready" -Completed
Write-Host "You can re-enable the disabled features at any time, using either Windows Update or the SxS folder in <installation media>\Sources."
}
$featlist = $featlist | Where-Object {
$_ -NotLike "*Printing*" -AND
$_ -NotLike "*TelnetClient*" -AND
$_ -NotLike "*PowerShell*" -AND
$_ -NotLike "*NetFx*" -AND
$_ -NotLike "*Media*" -AND
$_ -NotLike "*NFS*"
}
if ($keepDefender) { $featlist = $featlist | Where-Object { $_ -NotLike "*Defender*" }}
foreach($feature in $featlist)
catch
{
$status = "Removing feature $feature"
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
Write-Debug "Removing feature $feature"
Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $feature -Remove -ErrorAction SilentlyContinue -NoRestart
Write-Host "Unable to get information about the features. MicroWin processing will continue, but features will not be processed"
}
Write-Progress -Activity "Removing features" -Status "Ready" -Completed
Write-Host "You can re-enable the disabled features at any time, using either Windows Update or the SxS folder in <installation media>\Sources."
}
function Remove-Packages
{
$pkglist = (Get-WindowsPackage -Path "$scratchDir").PackageName
$pkglist = $pkglist | Where-Object {
$_ -NotLike "*ApplicationModel*" -AND
$_ -NotLike "*indows-Client-LanguagePack*" -AND
$_ -NotLike "*LanguageFeatures-Basic*" -AND
$_ -NotLike "*Package_for_ServicingStack*" -AND
$_ -NotLike "*.NET*" -AND
$_ -NotLike "*Store*" -AND
$_ -NotLike "*VCLibs*" -AND
$_ -NotLike "*AAD.BrokerPlugin",
$_ -NotLike "*LockApp*" -AND
$_ -NotLike "*Notepad*" -AND
$_ -NotLike "*immersivecontrolpanel*" -AND
$_ -NotLike "*ContentDeliveryManager*" -AND
$_ -NotLike "*PinningConfirMationDialog*" -AND
$_ -NotLike "*SecHealthUI*" -AND
$_ -NotLike "*SecureAssessmentBrowser*" -AND
$_ -NotLike "*PrintDialog*" -AND
$_ -NotLike "*AssignedAccessLockApp*" -AND
$_ -NotLike "*OOBENetworkConnectionFlow*" -AND
$_ -NotLike "*Apprep.ChxApp*" -AND
$_ -NotLike "*CBS*" -AND
$_ -NotLike "*OOBENetworkCaptivePortal*" -AND
$_ -NotLike "*PeopleExperienceHost*" -AND
$_ -NotLike "*ParentalControls*" -AND
$_ -NotLike "*Win32WebViewHost*" -AND
$_ -NotLike "*InputApp*" -AND
$_ -NotLike "*AccountsControl*" -AND
$_ -NotLike "*AsyncTextService*" -AND
$_ -NotLike "*CapturePicker*" -AND
$_ -NotLike "*CredDialogHost*" -AND
$_ -NotLike "*BioEnrollMent*" -AND
$_ -NotLike "*ShellExperienceHost*" -AND
$_ -NotLike "*DesktopAppInstaller*" -AND
$_ -NotLike "*WebMediaExtensions*" -AND
$_ -NotLike "*WMIC*" -AND
$_ -NotLike "*UI.XaML*"
}
foreach ($pkg in $pkglist)
try
{
try {
$status = "Removing $pkg"
Write-Progress -Activity "Removing Apps" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
Remove-WindowsPackage -Path "$scratchDir" -PackageName $pkg -NoRestart -ErrorAction SilentlyContinue
}
catch {
# This can happen if the package that is being removed is a permanent one, like FodMetadata
Write-Host "Could not remove OS package $($pkg)"
continue
$pkglist = (Get-WindowsPackage -Path "$scratchDir").PackageName
$pkglist = $pkglist | Where-Object {
$_ -NotLike "*ApplicationModel*" -AND
$_ -NotLike "*indows-Client-LanguagePack*" -AND
$_ -NotLike "*LanguageFeatures-Basic*" -AND
$_ -NotLike "*Package_for_ServicingStack*" -AND
$_ -NotLike "*.NET*" -AND
$_ -NotLike "*Store*" -AND
$_ -NotLike "*VCLibs*" -AND
$_ -NotLike "*AAD.BrokerPlugin",
$_ -NotLike "*LockApp*" -AND
$_ -NotLike "*Notepad*" -AND
$_ -NotLike "*immersivecontrolpanel*" -AND
$_ -NotLike "*ContentDeliveryManager*" -AND
$_ -NotLike "*PinningConfirMationDialog*" -AND
$_ -NotLike "*SecHealthUI*" -AND
$_ -NotLike "*SecureAssessmentBrowser*" -AND
$_ -NotLike "*PrintDialog*" -AND
$_ -NotLike "*AssignedAccessLockApp*" -AND
$_ -NotLike "*OOBENetworkConnectionFlow*" -AND
$_ -NotLike "*Apprep.ChxApp*" -AND
$_ -NotLike "*CBS*" -AND
$_ -NotLike "*OOBENetworkCaptivePortal*" -AND
$_ -NotLike "*PeopleExperienceHost*" -AND
$_ -NotLike "*ParentalControls*" -AND
$_ -NotLike "*Win32WebViewHost*" -AND
$_ -NotLike "*InputApp*" -AND
$_ -NotLike "*AccountsControl*" -AND
$_ -NotLike "*AsyncTextService*" -AND
$_ -NotLike "*CapturePicker*" -AND
$_ -NotLike "*CredDialogHost*" -AND
$_ -NotLike "*BioEnrollMent*" -AND
$_ -NotLike "*ShellExperienceHost*" -AND
$_ -NotLike "*DesktopAppInstaller*" -AND
$_ -NotLike "*WebMediaExtensions*" -AND
$_ -NotLike "*WMIC*" -AND
$_ -NotLike "*UI.XaML*"
}
foreach ($pkg in $pkglist)
{
try {
$status = "Removing $pkg"
Write-Progress -Activity "Removing Apps" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
Remove-WindowsPackage -Path "$scratchDir" -PackageName $pkg -NoRestart -ErrorAction SilentlyContinue
}
catch {
# This can happen if the package that is being removed is a permanent one, like FodMetadata
Write-Host "Could not remove OS package $($pkg)"
continue
}
}
Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed
}
catch
{
Write-Host "Unable to get information about the packages. MicroWin processing will continue, but packages will not be processed"
}
Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed
}
function Remove-ProvisionedPackages([switch] $keepSecurity = $false)
@ -1987,6 +2024,8 @@ function Invoke-WinUtilFeatureInstall {
$CheckBox
)
$x = 0
$CheckBox | ForEach-Object {
if($sync.configs.feature.$psitem.feature){
Foreach( $feature in $sync.configs.feature.$psitem.feature ){
@ -1997,9 +2036,11 @@ function Invoke-WinUtilFeatureInstall {
Catch{
if ($psitem.Exception.Message -like "*requires elevation*"){
Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?"
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
}
else{
Write-Warning "Unable to Install $feature due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
@ -2017,15 +2058,19 @@ function Invoke-WinUtilFeatureInstall {
Catch{
if ($psitem.Exception.Message -like "*requires elevation*"){
Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?"
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
}
else{
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
Write-Warning "Unable to Install $feature due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
}
}
}
$X++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$CheckBox.Count) })
}
}
function Invoke-WinUtilGPU {
@ -2882,6 +2927,92 @@ Function Set-WinUtilService {
}
}
function Set-WinUtilTaskbaritem {
<#
.SYNOPSIS
Modifies the Taskbaritem of the WPF Form
.PARAMETER value
Value can be between 0 and 1, 0 being no progress done yet and 1 being fully completed
Value does not affect item without setting the state to 'Normal', 'Error' or 'Paused'
Set-WinUtilTaskbaritem -value 0.5
.PARAMETER state
State can be 'None' > No progress, 'Indeterminate' > inf. loading gray, 'Normal' > Gray, 'Error' > Red, 'Paused' > Yellow
no value needed:
- Set-WinUtilTaskbaritem -state "None"
- Set-WinUtilTaskbaritem -state "Indeterminate"
value needed:
- Set-WinUtilTaskbaritem -state "Error"
- Set-WinUtilTaskbaritem -state "Normal"
- Set-WinUtilTaskbaritem -state "Paused"
.PARAMETER overlay
Overlay icon to display on the taskbar item, there are the presets 'None', 'logo' and 'checkmark' or you can specify a path/link to an image file.
CTT logo preset:
- Set-WinUtilTaskbaritem -overlay "logo"
Checkmark preset:
- Set-WinUtilTaskbaritem -overlay "checkmark"
Warning preset:
- Set-WinUtilTaskbaritem -overlay "warning"
No overlay:
- Set-WinUtilTaskbaritem -overlay "None"
Custom icon (needs to be supported by WPF):
- Set-WinUtilTaskbaritem -overlay "C:\path\to\icon.png"
.PARAMETER description
Description to display on the taskbar item preview
Set-WinUtilTaskbaritem -description "This is a description"
#>
param (
[string]$state,
[double]$value,
[string]$overlay,
[string]$description
)
if ($value) {
$sync["Form"].taskbarItemInfo.ProgressValue = $value
}
if ($state) {
switch ($state) {
'None' { $sync["Form"].taskbarItemInfo.ProgressState = "None" }
'Indeterminate' { $sync["Form"].taskbarItemInfo.ProgressState = "Indeterminate" }
'Normal' { $sync["Form"].taskbarItemInfo.ProgressState = "Normal" }
'Error' { $sync["Form"].taskbarItemInfo.ProgressState = "Error" }
'Paused' { $sync["Form"].taskbarItemInfo.ProgressState = "Paused" }
default { throw "[Set-WinUtilTaskbarItem] Invalid state" }
}
}
if ($overlay) {
switch ($overlay) {
'logo' {
$sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\cttlogo.png"
}
'checkmark' {
$sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\checkmark.png"
}
'warning' {
$sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\warning.png"
}
'None' {
$sync["Form"].taskbarItemInfo.Overlay = $null
}
default {
if (Test-Path $overlay) {
$sync["Form"].taskbarItemInfo.Overlay = $overlay
}
}
}
}
if ($description) {
$sync["Form"].taskbarItemInfo.Description = $description
}
}
function Set-WinUtilUITheme {
<#
@ -3488,12 +3619,18 @@ function Invoke-WPFFeatureInstall {
Invoke-WPFRunspace -ArgumentList $Features -DebugPreference $DebugPreference -ScriptBlock {
param($Features, $DebugPreference)
$sync.ProcessRunning = $true
if ($Features.count -eq 1){
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
Invoke-WinUtilFeatureInstall $Features
$sync.ProcessRunning = $false
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
Write-Host "==================================="
Write-Host "--- Features are Installed ---"
Write-Host "--- A Reboot may be required ---"
@ -3897,6 +4034,7 @@ function Invoke-WPFGetInstalled {
param($checkbox, $DebugPreference)
$sync.ProcessRunning = $true
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" })
if($checkbox -eq "winget"){
Write-Host "Getting Installed Programs..."
@ -3915,6 +4053,7 @@ function Invoke-WPFGetInstalled {
Write-Host "Done..."
$sync.ProcessRunning = $false
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "None" })
}
}
function Invoke-WPFGetIso {
@ -3935,6 +4074,7 @@ function Invoke-WPFGetIso {
$sync.BusyText.Text="N Busy"
Write-Host " _ __ __ _ "
Write-Host " /\/\ (_) ___ _ __ ___ / / /\ \ \(_) _ __ "
Write-Host " / \ | | / __|| '__| / _ \ \ \/ \/ /| || '_ \ "
@ -4007,6 +4147,8 @@ function Invoke-WPFGetIso {
return
}
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
# Detect the file size of the ISO and compare it with the free space of the system drive
$isoSize = (Get-Item -Path $filePath).Length
Write-Debug "Size of ISO file: $($isoSize) bytes"
@ -4023,6 +4165,7 @@ function Invoke-WPFGetIso {
{
# It's critical and we can't continue. Output an error
Write-Host "You don't have enough space for this operation. You need at least $([Math]::Round(($isoSize / ([Math]::Pow(1024, 2))) * 2, 2)) MB of free space to copy the ISO files to a temp directory and to be able to perform additional operations."
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
else
@ -4041,6 +4184,7 @@ function Invoke-WPFGetIso {
Write-Error "Failed to mount the image. Error: $($_.Exception.Message)"
Write-Error "This is NOT winutil's problem, your ISO might be corrupt, or there is a problem on the system"
Write-Error "Please refer to this wiki for more details https://github.com/ChrisTitusTech/winutil/blob/main/wiki/Error-in-Winutil-MicroWin-during-ISO-mounting%2Cmd"
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
# storing off values in hidden fields for further steps
@ -4118,6 +4262,7 @@ function Invoke-WPFGetIso {
$msg = "Neither install.wim nor install.esd exist in the image, this could happen if you use unofficial Windows images. Please don't use shady images from the internet, use only official images. Here are instructions how to download ISO images if the Microsoft website is not showing the link to download and ISO. https://www.techrepublic.com/article/how-to-download-a-windows-10-iso-file-without-using-the-media-creation-tool/"
Write-Host $msg
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
throw
}
elseif ((-not (Test-Path -Path $wimFile -PathType Leaf)) -and (Test-Path -Path $wimFile.Replace(".wim", ".esd").Trim() -PathType Leaf))
@ -4158,6 +4303,7 @@ function Invoke-WPFGetIso {
$sync.BusyMessage.Visibility="Hidden"
$sync.ProcessRunning = $false
Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"
}
@ -4244,8 +4390,14 @@ function Invoke-WPFInstall {
return
}
Invoke-WPFRunspace -ArgumentList $PackagesToInstall -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $DebugPreference)
if ($PackagesToInstall.count -eq 1){
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
$packagesWinget, $packagesChoco = {
$packagesWinget = [System.Collections.Generic.List`1[System.Object]]::new()
$packagesChoco = [System.Collections.Generic.List`1[System.Object]]::new()
@ -4276,13 +4428,14 @@ function Invoke-WPFInstall {
Write-Host "==========================================="
Write-Host "-- Installs have finished ---"
Write-Host "==========================================="
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
}
Catch {
Write-Host "==========================================="
Write-Host "Error: $_"
Write-Host "==========================================="
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" })
}
Start-Sleep -Seconds 5
$sync.ProcessRunning = $False
}
}
@ -4303,6 +4456,8 @@ function Invoke-WPFInstallUpgrade {
return
}
# Set-WinUtilTaskbaritem -state "Indeterminate"
Update-WinUtilProgramWinget
Write-Host "==========================================="
@ -4316,6 +4471,7 @@ function Invoke-WPFMicrowin {
Invoke MicroWin routines...
#>
if($sync.ProcessRunning) {
$msg = "GetIso process is currently running."
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
@ -4351,9 +4507,12 @@ public class PowerManagement {
if ($SaveDialog.FileName -eq "") {
Write-Host "No file name for the target image was specified"
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
Write-Host "Target ISO location: $($SaveDialog.FileName)"
$index = $sync.MicrowinWindowsFlavors.SelectedValue.Split(":")[0].Trim()
@ -4386,6 +4545,7 @@ public class PowerManagement {
$msg = "The export process has failed and MicroWin processing cannot continue"
Write-Host "Failed to export the image"
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
}
@ -4399,6 +4559,7 @@ public class PowerManagement {
$dlg_msg = $msg + "`n`nIf you want more information, the version of the image selected is $($imgVersion)`n`nIf an image has been incorrectly marked as incompatible, report an issue to the developers."
Write-Host $msg
[System.Windows.MessageBox]::Show($dlg_msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Exclamation)
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
@ -4407,6 +4568,7 @@ public class PowerManagement {
if (-not $mountDirExists -or -not $scratchDirExists)
{
Write-Error "Required directories '$mountDirExists' '$scratchDirExists' and do not exist."
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
@ -4421,6 +4583,7 @@ public class PowerManagement {
else
{
Write-Host "Could not mount image. Exiting..."
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
@ -4690,6 +4853,7 @@ public class PowerManagement {
if (-not (Test-Path -Path "$mountDir\sources\install.wim"))
{
Write-Error "Something went wrong and '$mountDir\sources\install.wim' doesn't exist. Please report this bug to the devs"
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return
}
Write-Host "Windows image completed. Continuing with boot.wim."
@ -4791,6 +4955,7 @@ public class PowerManagement {
#$msg = "Done. ISO image is located here: $env:temp\microwin.iso"
$msg = "Done. ISO image is located here: $($SaveDialog.FileName)"
Write-Host $msg
Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
} else {
Write-Host "ISO creation failed. The "$($mountDir)" directory has not been removed."
@ -5026,8 +5191,8 @@ function Invoke-WPFShortcut {
[bool]$RunAsAdmin = $false
)
# add an a Custom Icon if it's available at "$env:TEMP\cttlogo.png", else don't add a Custom Icon.
$iconPath = $null
# Preper the Shortcut Fields and add an a Custom Icon if it's available, else don't add a Custom Icon.
Switch ($ShortcutToAdd) {
"WinUtil" {
# Use Powershell 7 if installed and fallback to PS5 if not
@ -5042,12 +5207,6 @@ function Invoke-WPFShortcut {
$DestinationName = "WinUtil.lnk"
Invoke-WebRequest -Uri "https://christitus.com/images/logo-full.png" -OutFile "$env:TEMP\cttlogo.png"
if (Test-Path -Path "$env:TEMP\cttlogo.png") {
$iconPath = "$env:LOCALAPPDATA\winutil\cttlogo.ico"
ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath $iconPath
}
}
}
@ -5067,10 +5226,10 @@ function Invoke-WPFShortcut {
# Prepare the Shortcut paramter
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut($FileBrowser.FileName)
$Shortcut.TargetPath = $shell
$Shortcut.Arguments = $shellArgs
if ($null -ne $iconPath) {
$shortcut.IconLocation = $iconPath
$Shortcut.TargetPath = $SourceExe
$Shortcut.Arguments = $ArgumentsToSourceExe
if (Test-Path -Path $winutildir["logo.ico"]) {
$shortcut.IconLocation = $winutildir["logo.ico"]
}
# Save the Shortcut to disk
@ -5237,15 +5396,22 @@ function Invoke-WPFtweaksbutton {
$sync.ProcessRunning = $true
if ($Tweaks.count -eq 1){
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
$cnt = 0
# Execute other selected tweaks
foreach ($tweak in $Tweaks) {
Write-Debug "This is a tweak to run $tweak count: $cnt"
Invoke-WinUtilTweaks $tweak
$cnt += 1
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($cnt/$Tweaks.Count) })
}
$sync.ProcessRunning = $false
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
Write-Host "================================="
Write-Host "-- Tweaks are Finished ---"
Write-Host "================================="
@ -5336,12 +5502,21 @@ function Invoke-WPFundoall {
param($Tweaks, $DebugPreference)
$sync.ProcessRunning = $true
if ($Tweaks.count -eq 1){
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
$cnt = 0
Foreach ($tweak in $tweaks){
Invoke-WinUtilTweaks $tweak -undo $true
$cnt += 1
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($cnt/$Tweaks.Count) })
}
$sync.ProcessRunning = $false
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
Write-Host "=================================="
Write-Host "--- Undo Tweaks are Finished ---"
Write-Host "=================================="
@ -5537,8 +5712,14 @@ function Invoke-WPFUnInstall {
if($confirm -eq "No"){return}
Invoke-WPFRunspace -ArgumentList $PackagesToInstall -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $DebugPreference)
if ($PackagesToInstall.count -eq 1){
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
$packagesWinget, $packagesChoco = {
$packagesWinget = [System.Collections.Generic.List`1[System.Object]]::new()
$packagesChoco = [System.Collections.Generic.List`1[System.Object]]::new()
@ -5564,23 +5745,21 @@ function Invoke-WPFUnInstall {
Install-WinUtilProgramChoco -ProgramsToInstall $packagesChoco -Manage "Uninstalling"
}
$ButtonType = [System.Windows.MessageBoxButton]::OK
$MessageboxTitle = "Uninstalls are Finished "
$Messageboxbody = ("Done")
$MessageIcon = [System.Windows.MessageBoxImage]::Information
[System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon)
Write-Host "==========================================="
Write-Host "-- Uninstalls have finished ---"
Write-Host "==========================================="
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
}
Catch {
Write-Host "==========================================="
Write-Host "Error: $_"
Write-Host "==========================================="
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" })
}
$sync.ProcessRunning = $False
}
}
function Invoke-WPFUpdatesdefault {
@ -12369,7 +12548,7 @@ $sync.configs.tweaks = '{
"panel": "1",
"Order": "a040_",
"Type": "Combobox",
"ComboItems": "Default DHCP Google Cloudflare Cloudflare_Malware Cloudflare_Malware_Adult Level3 Open_DNS Quad9"
"ComboItems": "Default DHCP Google Cloudflare Cloudflare_Malware Cloudflare_Malware_Adult Open_DNS Quad9 AdGuard_Ads_Trackers AdGuard_Ads_Trackers_Malware_Adult"
},
"WPFTweaksbutton": {
"Content": "Run Tweaks",
@ -14747,9 +14926,10 @@ $inputXML = '<Window x:Class="WinUtility.MainWindow"
<ComboBoxItem Content="Cloudflare" FontSize="{FontSize}"/>
<ComboBoxItem Content="Cloudflare_Malware" FontSize="{FontSize}"/>
<ComboBoxItem Content="Cloudflare_Malware_Adult" FontSize="{FontSize}"/>
<ComboBoxItem Content="Level3" FontSize="{FontSize}"/>
<ComboBoxItem Content="Open_DNS" FontSize="{FontSize}"/>
<ComboBoxItem Content="Quad9" FontSize="{FontSize}"/>
<ComboBoxItem Content="AdGuard_Ads_Trackers" FontSize="{FontSize}"/>
<ComboBoxItem Content="AdGuard_Ads_Trackers_Malware_Adult" FontSize="{FontSize}"/>
</ComboBox>
</StackPanel>
<Button Name="WPFTweaksbutton" Content="Run Tweaks" HorizontalAlignment="Left" Margin="5" Padding="20,5" />
@ -15276,6 +15456,10 @@ Invoke-WPFRunspace -ScriptBlock {
# Print the logo
Invoke-WPFFormVariables
# Progress bar in taskbaritem > Set-WinUtilProgressbar
$sync["Form"].TaskbarItemInfo = New-Object System.Windows.Shell.TaskbarItemInfo
Set-WinUtilTaskbaritem -state "None"
# Set the titlebar
$sync["Form"].title = $sync["Form"].title + " " + $sync.version
# Set the commands that will run when the form is closed
@ -15410,38 +15594,6 @@ Add-Type @"
}
}
# Using a TaskbarItem Overlay until someone figures out how to replace the icon correctly
# URL of the image
$imageUrl = "https://christitus.com/images/logo-full.png"
# Download the image
$imagePath = "$env:TEMP\logo-full.png"
Invoke-WebRequest -Uri $imageUrl -OutFile $imagePath
# Read the image file as a byte array
$imageBytes = [System.IO.File]::ReadAllBytes($imagePath)
# Convert the byte array to a Base64 string
$base64String = [System.Convert]::ToBase64String($imageBytes)
# Create a streaming image by streaming the base64 string to a bitmap streamsource
$bitmap = New-Object System.Windows.Media.Imaging.BitmapImage
$bitmap.BeginInit()
$bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($base64String)
$bitmap.EndInit()
$bitmap.Freeze()
# Ensure TaskbarItemInfo is created if not already
if (-not $sync["Form"].TaskbarItemInfo) {
$sync["Form"].TaskbarItemInfo = New-Object System.Windows.Shell.TaskbarItemInfo
}
# Set the overlay icon for the taskbar
$sync["Form"].TaskbarItemInfo.Overlay = $bitmap
$rect = New-Object RECT
[Window]::GetWindowRect($windowHandle, [ref]$rect)
$width = $rect.Right - $rect.Left
@ -15580,6 +15732,42 @@ $sync["SearchBar"].Add_TextChanged({
$label.Visibility = "Collapsed"}
})
# Initialize the hashtable
$winutildir = @{}
# Set the path for the winutil directory
$winutildir["path"] = "$env:LOCALAPPDATA\winutil\"
if (-NOT (Test-Path -Path $winutildir["path"])) {
New-Item -Path $winutildir["path"] -ItemType Directory
}
# Set the path for the logo and checkmark images
$winutildir["logo.png"] = $winutildir["path"] + "cttlogo.png"
$winutildir["logo.ico"] = $winutildir["path"] + "cttlogo.ico"
if (-NOT (Test-Path -Path $winutildir["logo.png"])) {
Invoke-WebRequest -Uri "https://christitus.com/images/logo-full.png" -OutFile $winutildir["logo.png"]
}
if (-NOT (Test-Path -Path $winutildir["logo.ico"])) {
ConvertTo-Icon -bitmapPath $winutildir["logo.png"] -iconPath $winutildir["logo.ico"]
}
$winutildir["checkmark.png"] = $winutildir["path"] + "checkmark.png"
$winutildir["warning.png"] = $winutildir["path"] + "warning.png"
if (-NOT (Test-Path -Path $winutildir["checkmark.png"])) {
Invoke-WebRequest -Uri "https://christitus.com/images/checkmark.png" -OutFile $winutildir["checkmark.png"]
}
if (-NOT (Test-Path -Path $winutildir["warning.png"])) {
Invoke-WebRequest -Uri "https://christitus.com/images/warning.png" -OutFile $winutildir["warning.png"]
}
Set-WinUtilTaskbaritem -overlay "logo"
$sync["Form"].Add_Activated({
Set-WinUtilTaskbaritem -overlay "logo"
})
# Define event handler for button click
$sync["SettingsButton"].Add_Click({
Write-Debug "SettingsButton clicked"