diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 122ac29ee..ef3fa33ed 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,10 +1,5 @@ -# Pull Request - -## Title - - ## Type of Change - [ ] New feature - [ ] Bug fix diff --git a/.github/workflows/pre-release.yaml b/.github/workflows/pre-release.yaml index c8c0eda9a..39a89d14e 100644 --- a/.github/workflows/pre-release.yaml +++ b/.github/workflows/pre-release.yaml @@ -76,7 +76,7 @@ jobs: - name: Generate Release Notes id: generate_notes - uses: release-drafter/release-drafter@v5 + uses: release-drafter/release-drafter@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: @@ -91,7 +91,7 @@ jobs: name: Pre-Release ${{ env.version }} body: | ${{ steps.generate_notes.outputs.body }} - + ![GitHub Downloads (specific asset, specific tag)](https://img.shields.io/github/downloads/ChrisTitusTech/winutil/${{ env.VERSION }}/winutil.ps1) append_body: false files: ./winutil.ps1 diff --git a/Compile.ps1 b/Compile.ps1 index afbe943d4..b7a61558b 100644 --- a/Compile.ps1 +++ b/Compile.ps1 @@ -4,10 +4,18 @@ param ( [switch]$SkipPreprocessing, [string]$Arguments ) + +if ((Get-Item ".\winutil.ps1" -ErrorAction SilentlyContinue).IsReadOnly) { + Remove-Item ".\winutil.ps1" -Force +} + $OFS = "`r`n" $scriptname = "winutil.ps1" $workingdir = $PSScriptRoot +Push-Location +Set-Location $workingdir + # Variable to sync between runspaces $sync = [Hashtable]::Synchronized(@{}) $sync.PSScriptRoot = $workingdir @@ -42,11 +50,11 @@ if (-NOT $SkipPreprocessing) { # Dot source the 'Invoke-Preprocessing' Function from 'tools/Invoke-Preprocessing.ps1' Script $preprocessingFilePath = ".\tools\Invoke-Preprocessing.ps1" - . "$(($workingdir -replace ('\\$', '')) + '\' + ($preprocessingFilePath -replace ('\.\\', '')))" + . $preprocessingFilePath $excludedFiles = @('.\.git\', '.\.gitignore', '.\.gitattributes', '.\.github\CODEOWNERS', '.\LICENSE', "$preprocessingFilePath", '*.png', '*.exe') $msg = "Pre-req: Code Formatting" - Invoke-Preprocessing -WorkingDir "$workingdir" -ExcludedFiles $excludedFiles -ProgressStatusMessage $msg + Invoke-Preprocessing -WorkingDir "$workingdir" -ExcludedFiles $excludedFiles -ProgressStatusMessage $msg -ThrowExceptionOnEmptyFilesList } # Create the script in memory. @@ -57,14 +65,14 @@ Update-Progress "Adding: Header" 5 $script_content.Add($header) Update-Progress "Adding: Version" 10 -$script_content.Add($(Get-Content "$workingdir\scripts\start.ps1").replace('#{replaceme}',"$(Get-Date -Format yy.MM.dd)")) +$script_content.Add($(Get-Content "scripts\start.ps1").replace('#{replaceme}',"$(Get-Date -Format yy.MM.dd)")) Update-Progress "Adding: Functions" 20 -Get-ChildItem "$workingdir\functions" -Recurse -File | ForEach-Object { +Get-ChildItem "functions" -Recurse -File | ForEach-Object { $script_content.Add($(Get-Content $psitem.FullName)) } Update-Progress "Adding: Config *.json" 40 -Get-ChildItem "$workingdir\config" | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object { +Get-ChildItem "config" | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object { $json = (Get-Content $psitem.FullName).replace("'","''") $jsonAsObject = $json | convertfrom-json @@ -85,34 +93,33 @@ Get-ChildItem "$workingdir\config" | Where-Object {$psitem.extension -eq ".json" $script_content.Add($(Write-output "`$sync.configs.$($psitem.BaseName) = '$json' `| convertfrom-json" )) } -$xaml = (Get-Content "$workingdir\xaml\inputXML.xaml").replace("'","''") +$xaml = (Get-Content "xaml\inputXML.xaml").replace("'","''") Update-Progress "Adding: Xaml " 90 $script_content.Add($(Write-output "`$inputXML = '$xaml'")) -$script_content.Add($(Get-Content "$workingdir\scripts\main.ps1")) +$script_content.Add($(Get-Content "scripts\main.ps1")) if ($Debug) { Update-Progress "Writing debug files" 95 - $appXamlContent | Out-File -FilePath "$workingdir\xaml\inputApp.xaml" -Encoding ascii - $tweaksXamlContent | Out-File -FilePath "$workingdir\xaml\inputTweaks.xaml" -Encoding ascii - $featuresXamlContent | Out-File -FilePath "$workingdir\xaml\inputFeatures.xaml" -Encoding ascii + $appXamlContent | Out-File -FilePath "xaml\inputApp.xaml" -Encoding ascii + $tweaksXamlContent | Out-File -FilePath "xaml\inputTweaks.xaml" -Encoding ascii + $featuresXamlContent | Out-File -FilePath "xaml\inputFeatures.xaml" -Encoding ascii } else { Update-Progress "Removing temporary files" 99 - Remove-Item "$workingdir\xaml\inputApp.xaml" -ErrorAction SilentlyContinue - Remove-Item "$workingdir\xaml\inputTweaks.xaml" -ErrorAction SilentlyContinue - Remove-Item "$workingdir\xaml\inputFeatures.xaml" -ErrorAction SilentlyContinue + Remove-Item "xaml\inputApp.xaml" -ErrorAction SilentlyContinue + Remove-Item "xaml\inputTweaks.xaml" -ErrorAction SilentlyContinue + Remove-Item "xaml\inputFeatures.xaml" -ErrorAction SilentlyContinue } -Set-Content -Path "$workingdir\$scriptname" -Value ($script_content -join "`r`n") -Encoding ascii +Set-Content -Path "$scriptname" -Value ($script_content -join "`r`n") -Encoding ascii Write-Progress -Activity "Compiling" -Completed Update-Progress -Activity "Validating" -StatusMessage "Checking winutil.ps1 Syntax" -Percent 0 try { $null = Get-Command -Syntax .\winutil.ps1 -} -catch { +} catch { Write-Warning "Syntax Validation for 'winutil.ps1' has failed" Write-Host "$($Error[0])" -ForegroundColor Red } @@ -128,3 +135,4 @@ if ($run) { break } +Pop-Location diff --git a/config/autounattend.xml b/config/autounattend.xml index c3a2f2138..6a432641b 100644 --- a/config/autounattend.xml +++ b/config/autounattend.xml @@ -293,7 +293,7 @@ param( - [xml] $Document + [xml]$Document ); $scriptsDir = 'C:\Windows\Setup\Scripts\'; diff --git a/config/feature.json b/config/feature.json index f28a92ed6..0013b211a 100644 --- a/config/feature.json +++ b/config/feature.json @@ -282,6 +282,14 @@ "ButtonWidth": "300", "link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/sound" }, + "WPFPanelprinter": { + "Content": "Printer Panel", + "category": "Legacy Windows Panels", + "panel": "2", + "Type": "Button", + "ButtonWidth": "300", + "link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/printer" + }, "WPFPanelsystem": { "Content": "System Properties", "category": "Legacy Windows Panels", diff --git a/config/themes.json b/config/themes.json index eedb2f83e..ed46caf75 100644 --- a/config/themes.json +++ b/config/themes.json @@ -21,7 +21,6 @@ "TabRowHeightInPixels": "50", "IconFontSize": "14", "IconButtonSize": "35", - "WinUtilIconSize": "Auto", "SettingsIconFontSize": "18", "CloseIconFontSize": "18", diff --git a/docs/dev/features/Legacy-Windows-Panels/printer.md b/docs/dev/features/Legacy-Windows-Panels/printer.md new file mode 100644 index 000000000..05e3471a4 --- /dev/null +++ b/docs/dev/features/Legacy-Windows-Panels/printer.md @@ -0,0 +1,65 @@ +# Printer Settings + +Last Updated: 2024-08-31 + + +!!! info + The Development Documentation is auto generated for every compilation of WinUtil, meaning a part of it will always stay up-to-date. **Developers do have the ability to add custom content, which won't be updated automatically.** + + + + + + +
+Preview Code + +```json +{ + "Content": "Printer Settings", + "category": "Legacy Windows Panels", + "panel": "2", + "Type": "Button", + "ButtonWidth": "300" +} +``` + +
+ +## Function: Invoke-WPFControlPanel + +```powershell +function Invoke-WPFControlPanel { + <# + + .SYNOPSIS + Opens the requested legacy panel + + .PARAMETER Panel + The panel to open + + #> + param($Panel) + + switch ($Panel) { + "WPFPanelcontrol" {cmd /c control} + "WPFPanelnetwork" {cmd /c ncpa.cpl} + "WPFPanelpower" {cmd /c powercfg.cpl} + "WPFPanelregion" {cmd /c intl.cpl} + "WPFPanelsound" {cmd /c mmsys.cpl} + "WPFPanelprinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"} + "WPFPanelsystem" {cmd /c sysdm.cpl} + "WPFPaneluser" {cmd /c "control userpasswords2"} + } +} + +``` + + + + + + + +[View the JSON file](https://github.com/ChrisTitusTech/winutil/tree/main/../config/feature.json) + diff --git a/docs/devdocs.md b/docs/devdocs.md index 7efd5d623..2b9b0a306 100644 --- a/docs/devdocs.md +++ b/docs/devdocs.md @@ -3,107 +3,106 @@ ## Tweaks -### z--Advanced-Tweaks---CAUTION - -- [Adobe Debloat](dev/tweaks/z--Advanced-Tweaks---CAUTION/DebloatAdobe.md) -- [Adobe Network Block](dev/tweaks/z--Advanced-Tweaks---CAUTION/BlockAdobeNet.md) -- [Disable Background Apps](dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableBGapps.md) -- [Disable Fullscreen Optimizations](dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableFSO.md) -- [Disable Intel MM (vPro LMS)](dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableLMS1.md) -- [Disable IPv6](dev/tweaks/z--Advanced-Tweaks---CAUTION/Disableipsix.md) -- [Disable Microsoft Copilot](dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveCopilot.md) -- [Disable Notification Tray/Calendar](dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableNotifications.md) -- [Disable Teredo](dev/tweaks/z--Advanced-Tweaks---CAUTION/Teredo.md) -- [DNS](dev/tweaks/z--Advanced-Tweaks---CAUTION/changedns.md) -- [Remove ALL MS Store Apps - NOT RECOMMENDED](dev/tweaks/z--Advanced-Tweaks---CAUTION/DeBloat.md) -- [Remove Home and Gallery from explorer](dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveHomeGallery.md) -- [Remove Microsoft Edge](dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveEdge.md) -- [Remove OneDrive](dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveOnedrive.md) -- [Run OO Shutup 10](dev/tweaks/z--Advanced-Tweaks---CAUTION/OOSUbutton.md) -- [Run Tweaks](dev/tweaks/z--Advanced-Tweaks---CAUTION/button.md) -- [Set Classic Right-Click Menu ](dev/tweaks/z--Advanced-Tweaks---CAUTION/RightClickMenu.md) -- [Set Display for Performance](dev/tweaks/z--Advanced-Tweaks---CAUTION/Display.md) -- [Set Time to UTC (Dual Boot)](dev/tweaks/z--Advanced-Tweaks---CAUTION/UTC.md) -- [Undo Selected Tweaks](dev/tweaks/z--Advanced-Tweaks---CAUTION/Undoall.md) ### Essential-Tweaks -- [Change Windows Terminal default: PowerShell 5 -> PowerShell 7](dev/tweaks/Essential-Tweaks/Powershell7.md) -- [Create Restore Point](dev/tweaks/Essential-Tweaks/RestorePoint.md) -- [Debloat Edge](dev/tweaks/Essential-Tweaks/EdgeDebloat.md) -- [Delete Temporary Files](dev/tweaks/Essential-Tweaks/DeleteTempFiles.md) -- [Prefer IPv4 over IPv6](dev/tweaks/Essential-Tweaks/IPv46.md) -- [Disable Activity History](dev/tweaks/Essential-Tweaks/AH.md) -- [Disable ConsumerFeatures](dev/tweaks/Essential-Tweaks/ConsumerFeatures.md) -- [Disable GameDVR](dev/tweaks/Essential-Tweaks/DVR.md) -- [Disable Hibernation](dev/tweaks/Essential-Tweaks/Hiber.md) -- [Disable Homegroup](dev/tweaks/Essential-Tweaks/Home.md) -- [Disable Location Tracking](dev/tweaks/Essential-Tweaks/Loc.md) -- [Disable Powershell 7 Telemetry](dev/tweaks/Essential-Tweaks/Powershell7Tele.md) -- [Disable Storage Sense](dev/tweaks/Essential-Tweaks/Storage.md) -- [Disable Telemetry](dev/tweaks/Essential-Tweaks/Tele.md) -- [Disable Wifi-Sense](dev/tweaks/Essential-Tweaks/Wifi.md) -- [Enable End Task With Right Click](dev/tweaks/Essential-Tweaks/EndTaskOnTaskbar.md) -- [Run Disk Cleanup](dev/tweaks/Essential-Tweaks/DiskCleanup.md) -- [Set Hibernation as default (good for laptops)](dev/tweaks/Essential-Tweaks/LaptopHibernation.md) -- [Set Services to Manual](dev/tweaks/Essential-Tweaks/Services.md) +- [Change Windows Terminal default: PowerShell 5 -> PowerShell 7](../docs/dev/tweaks/Essential-Tweaks/Powershell7.md) +- [Create Restore Point](../docs/dev/tweaks/Essential-Tweaks/RestorePoint.md) +- [Debloat Edge](../docs/dev/tweaks/Essential-Tweaks/EdgeDebloat.md) +- [Delete Temporary Files](../docs/dev/tweaks/Essential-Tweaks/DeleteTempFiles.md) +- [Disable Activity History](../docs/dev/tweaks/Essential-Tweaks/AH.md) +- [Disable ConsumerFeatures](../docs/dev/tweaks/Essential-Tweaks/ConsumerFeatures.md) +- [Disable GameDVR](../docs/dev/tweaks/Essential-Tweaks/DVR.md) +- [Disable Hibernation](../docs/dev/tweaks/Essential-Tweaks/Hiber.md) +- [Disable Homegroup](../docs/dev/tweaks/Essential-Tweaks/Home.md) +- [Disable Location Tracking](../docs/dev/tweaks/Essential-Tweaks/Loc.md) +- [Disable Powershell 7 Telemetry](../docs/dev/tweaks/Essential-Tweaks/Powershell7Tele.md) +- [Disable Storage Sense](../docs/dev/tweaks/Essential-Tweaks/Storage.md) +- [Disable Telemetry](../docs/dev/tweaks/Essential-Tweaks/Tele.md) +- [Disable Wifi-Sense](../docs/dev/tweaks/Essential-Tweaks/Wifi.md) +- [Enable End Task With Right Click](../docs/dev/tweaks/Essential-Tweaks/EndTaskOnTaskbar.md) +- [Prefer IPv4 over IPv6](../docs/dev/tweaks/Essential-Tweaks/IPv46.md) +- [Run Disk Cleanup](../docs/dev/tweaks/Essential-Tweaks/DiskCleanup.md) +- [Set Hibernation as default (good for laptops)](../docs/dev/tweaks/Essential-Tweaks/LaptopHibernation.md) +- [Set Services to Manual](../docs/dev/tweaks/Essential-Tweaks/Services.md) ### Shortcuts -- [Create WinUtil Shortcut](dev/tweaks/Shortcuts/Shortcut.md) +- [Create WinUtil Shortcut](../docs/dev/tweaks/Shortcuts/Shortcut.md) +### z--Advanced-Tweaks---CAUTION + +- [Adobe Debloat](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DebloatAdobe.md) +- [Adobe Network Block](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/BlockAdobeNet.md) +- [Disable Background Apps](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableBGapps.md) +- [Disable Fullscreen Optimizations](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableFSO.md) +- [Disable Intel MM (vPro LMS)](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableLMS1.md) +- [Disable IPv6](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/Disableipsix.md) +- [Disable Microsoft Copilot](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveCopilot.md) +- [Disable Notification Tray/Calendar](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableNotifications.md) +- [Disable Teredo](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/Teredo.md) +- [DNS](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/changedns.md) +- [Remove ALL MS Store Apps - NOT RECOMMENDED](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DeBloat.md) +- [Remove Home and Gallery from explorer](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveHomeGallery.md) +- [Remove Microsoft Edge](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveEdge.md) +- [Remove OneDrive](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveOnedrive.md) +- [Run OO Shutup 10](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/OOSUbutton.md) +- [Set Classic Right-Click Menu ](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RightClickMenu.md) +- [Set Display for Performance](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/Display.md) +- [Set Time to UTC (Dual Boot)](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/UTC.md) ### Customize-Preferences -- [Bing Search in Start Menu](dev/tweaks/Customize-Preferences/BingSearch.md) -- [Center Taskbar Items](dev/tweaks/Customize-Preferences/TaskbarAlignment.md) -- [Dark Theme for Windows](dev/tweaks/Customize-Preferences/DarkMode.md) -- [Detailed BSoD](dev/tweaks/Customize-Preferences/DetailedBSoD.md) -- [Mouse Acceleration](dev/tweaks/Customize-Preferences/MouseAcceleration.md) -- [NumLock on Startup](dev/tweaks/Customize-Preferences/NumLock.md) -- [Search Button in Taskbar](dev/tweaks/Customize-Preferences/TaskbarSearch.md) -- [Show File Extensions](dev/tweaks/Customize-Preferences/ShowExt.md) -- [Show Hidden Files](dev/tweaks/Customize-Preferences/HiddenFiles.md) -- [Snap Assist Flyout](dev/tweaks/Customize-Preferences/SnapFlyout.md) -- [Snap Assist Suggestion](dev/tweaks/Customize-Preferences/SnapSuggestion.md) -- [Snap Window](dev/tweaks/Customize-Preferences/SnapWindow.md) -- [Sticky Keys](dev/tweaks/Customize-Preferences/StickyKeys.md) -- [Task View Button in Taskbar](dev/tweaks/Customize-Preferences/TaskView.md) -- [Verbose Messages During Logon](dev/tweaks/Customize-Preferences/VerboseLogon.md) -- [Widgets Button in Taskbar](dev/tweaks/Customize-Preferences/TaskbarWidgets.md) +- [Bing Search in Start Menu](../docs/dev/tweaks/Customize-Preferences/BingSearch.md) +- [Center Taskbar Items](../docs/dev/tweaks/Customize-Preferences/TaskbarAlignment.md) +- [Dark Theme for Windows](../docs/dev/tweaks/Customize-Preferences/DarkMode.md) +- [Detailed BSoD](../docs/dev/tweaks/Customize-Preferences/DetailedBSoD.md) +- [Mouse Acceleration](../docs/dev/tweaks/Customize-Preferences/MouseAcceleration.md) +- [NumLock on Startup](../docs/dev/tweaks/Customize-Preferences/NumLock.md) +- [Search Button in Taskbar](../docs/dev/tweaks/Customize-Preferences/TaskbarSearch.md) +- [Show File Extensions](../docs/dev/tweaks/Customize-Preferences/ShowExt.md) +- [Show Hidden Files](../docs/dev/tweaks/Customize-Preferences/HiddenFiles.md) +- [Snap Assist Flyout](../docs/dev/tweaks/Customize-Preferences/SnapFlyout.md) +- [Snap Assist Suggestion](../docs/dev/tweaks/Customize-Preferences/SnapSuggestion.md) +- [Snap Window](../docs/dev/tweaks/Customize-Preferences/SnapWindow.md) +- [Sticky Keys](../docs/dev/tweaks/Customize-Preferences/StickyKeys.md) +- [Task View Button in Taskbar](../docs/dev/tweaks/Customize-Preferences/TaskView.md) +- [Verbose Messages During Logon](../docs/dev/tweaks/Customize-Preferences/VerboseLogon.md) +- [Widgets Button in Taskbar](../docs/dev/tweaks/Customize-Preferences/TaskbarWidgets.md) ### Performance-Plans -- [Add and Activate Ultimate Performance Profile](dev/tweaks/Performance-Plans/AddUltPerf.md) -- [Remove Ultimate Performance Profile](dev/tweaks/Performance-Plans/RemoveUltPerf.md) +- [Add and Activate Ultimate Performance Profile](../docs/dev/tweaks/Performance-Plans/AddUltPerf.md) +- [Remove Ultimate Performance Profile](../docs/dev/tweaks/Performance-Plans/RemoveUltPerf.md) ## Features -### Legacy-Windows-Panels - -- [Control Panel](dev/features/Legacy-Windows-Panels/control.md) -- [Network Connections](dev/features/Legacy-Windows-Panels/network.md) -- [Power Panel](dev/features/Legacy-Windows-Panels/power.md) -- [Region](dev/features/Legacy-Windows-Panels/region.md) -- [Sound Settings](dev/features/Legacy-Windows-Panels/sound.md) -- [System Properties](dev/features/Legacy-Windows-Panels/system.md) -- [User Accounts](dev/features/Legacy-Windows-Panels/user.md) ### Fixes -- [Remove Adobe Creative Cloud](dev/features/Fixes/RunAdobeCCCleanerTool.md) -- [Reset Network](dev/features/Fixes/Network.md) -- [Reset Windows Update](dev/features/Fixes/Update.md) -- [Set Up Autologin](dev/features/Fixes/Autologin.md) -- [System Corruption Scan](dev/features/Fixes/DISM.md) -- [WinGet Reinstall](dev/features/Fixes/Winget.md) +- [Remove Adobe Creative Cloud](../docs/dev/features/Fixes/RunAdobeCCCleanerTool.md) +- [Reset Network](../docs/dev/features/Fixes/Network.md) +- [Reset Windows Update](../docs/dev/features/Fixes/Update.md) +- [Set Up Autologin](../docs/dev/features/Fixes/Autologin.md) +- [System Corruption Scan](../docs/dev/features/Fixes/DISM.md) +- [WinGet Reinstall](../docs/dev/features/Fixes/Winget.md) +### Legacy-Windows-Panels + +- [Control Panel](../docs/dev/features/Legacy-Windows-Panels/control.md) +- [Network Connections](../docs/dev/features/Legacy-Windows-Panels/network.md) +- [Power Panel](../docs/dev/features/Legacy-Windows-Panels/power.md) +- [Printer Settings](../docs/dev/features/Legacy-Windows-Panels/printer.md) +- [Region](../docs/dev/features/Legacy-Windows-Panels/region.md) +- [Sound Settings](../docs/dev/features/Legacy-Windows-Panels/sound.md) +- [System Properties](../docs/dev/features/Legacy-Windows-Panels/system.md) +- [User Accounts](../docs/dev/features/Legacy-Windows-Panels/user.md) ### Features -- [All .Net Framework (2,3,4)](dev/features/Features/dotnet.md) -- [Disable Legacy F8 Boot Recovery](dev/features/Features/DisableLegacyRecovery.md) -- [Disable Search Box Web Suggestions in Registry(explorer restart)](dev/features/Features/DisableSearchSuggestions.md) -- [Enable Daily Registry Backup Task 12.30am](dev/features/Features/RegBackup.md) -- [Enable Legacy F8 Boot Recovery](dev/features/Features/EnableLegacyRecovery.md) -- [Enable Search Box Web Suggestions in Registry(explorer restart)](dev/features/Features/EnableSearchSuggestions.md) -- [HyperV Virtualization](dev/features/Features/hyperv.md) -- [Install Features](dev/features/Features/Install.md) -- [Legacy Media (WMP, DirectPlay)](dev/features/Features/legacymedia.md) -- [NFS - Network File System](dev/features/Features/nfs.md) -- [Windows Sandbox](dev/features/Features/Sandbox.md) -- [Windows Subsystem for Linux](dev/features/Features/wsl.md) +- [All .Net Framework (2,3,4)](../docs/dev/features/Features/dotnet.md) +- [Disable Legacy F8 Boot Recovery](../docs/dev/features/Features/DisableLegacyRecovery.md) +- [Disable Search Box Web Suggestions in Registry(explorer restart)](../docs/dev/features/Features/DisableSearchSuggestions.md) +- [Enable Daily Registry Backup Task 12.30am](../docs/dev/features/Features/RegBackup.md) +- [Enable Legacy F8 Boot Recovery](../docs/dev/features/Features/EnableLegacyRecovery.md) +- [Enable Search Box Web Suggestions in Registry(explorer restart)](../docs/dev/features/Features/EnableSearchSuggestions.md) +- [HyperV Virtualization](../docs/dev/features/Features/hyperv.md) +- [Install Features](../docs/dev/features/Features/Install.md) +- [Legacy Media (WMP, DirectPlay)](../docs/dev/features/Features/legacymedia.md) +- [NFS - Network File System](../docs/dev/features/Features/nfs.md) +- [Windows Sandbox](../docs/dev/features/Features/Sandbox.md) +- [Windows Subsystem for Linux](../docs/dev/features/Features/wsl.md) diff --git a/functions/private/ConvertTo-Icon.ps1 b/functions/private/ConvertTo-Icon.ps1 deleted file mode 100644 index a40177555..000000000 --- a/functions/private/ConvertTo-Icon.ps1 +++ /dev/null @@ -1,92 +0,0 @@ -function ConvertTo-Icon { - <# - - .DESCRIPTION - This function will convert BMP, GIF, EXIF, JPG, PNG and TIFF to ICO file - - .PARAMETER bitmapPath - The file path to bitmap image to make '.ico' file out of. - Supported file types according to Microsoft Documentation is the following: - BMP, GIF, EXIF, JPG, PNG and TIFF. - - .PARAMETER iconPath - The file path to write the new '.ico' resource. - - .PARAMETER overrideIconFile - An optional boolean Parameter that makes the function overrides - the Icon File Path if the file exists. Defaults to $true. - - .EXAMPLE - try { - ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath "$env:TEMP\cttlogo.ico" - } catch [System.IO.FileNotFoundException] { - # Handle the thrown exception here... - } - - This Example makes a '.ico' file at "$env:TEMP\cttlogo.ico" File Path using the bitmap file - found in "$env:TEMP\cttlogo.png", the function overrides the '.ico' File if it's found. - this function will throw a FileNotFound Exception at the event of not finding the provided bitmap File Path. - - .EXAMPLE - try { - ConvertTo-Icon "$env:TEMP\cttlogo.png" "$env:TEMP\cttlogo.ico" - } catch [System.IO.FileNotFoundException] { - # Handle the thrown exception here... - } - - This Example is the same as Example 1, but uses Positional Parameters instead. - - .EXAMPLE - if (Test-Path "$env:TEMP\cttlogo.png") { - ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath "$env:TEMP\cttlogo.ico" - } - - This Example is same as Example 1, but checks if the bitmap File exists before calling 'ConvertTo-Icon' Function. - This's the recommended way of using this function, as it doesn't require any try-catch blocks. - - .EXAMPLE - try { - ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath "$env:TEMP\cttlogo.ico" -overrideIconFile $false - } catch [System.IO.FileNotFoundException] { - # Handle the thrown exception here... - } - - This Example make use of '-overrideIconFile' Optional Parameter, the default for this parameter is $true. - By doing '-overrideIconFile $false', the 'ConvertTo-Icon' function will raise an exception that needs to be catched throw a 'catch' Code Block, - otherwise it'll crash the running PowerShell instance/process. - - #> - param( - [Parameter(Mandatory, position=0)] - [string]$bitmapPath, - [Parameter(Mandatory, position=1)] - [string]$iconPath, - [Parameter(position=2)] - [bool]$overrideIconFile = $true - ) - - Add-Type -AssemblyName System.Drawing - - if (Test-Path $bitmapPath) { - if ((Test-Path $iconPath) -AND ($overrideIconFile -eq $false)) { - Write-Host "[ConvertTo-Icon] Icon File is found at '$iconPath', and the 'overrideIconFile' Parameter is set to '$overrideIconFile'. Skipping the bitmap to icon convertion..." -ForegroundColor Yellow - return - } - - # Load bitmap file into memory, and make an Icon version out of it - $b = [System.Drawing.Bitmap]::FromFile($bitmapPath) - $icon = [System.Drawing.Icon]::FromHandle($b.GetHicon()) - - # Create the folder for the new icon file if it doesn't exists - $iconFolder = (New-Object System.IO.FileInfo($iconPath)).Directory.FullName - [System.IO.Directory]::CreateDirectory($iconFolder) | Out-Null - - # Write the Icon File and do some cleaning-up - $file = New-Object System.IO.FileStream($iconPath, 'OpenOrCreate') - $icon.Save($file) - $file.Close() - $icon.Dispose() - } else { - throw [System.IO.FileNotFoundException] "[ConvertTo-Icon] The provided bitmap File Path is not found at '$bitmapPath'." - } -} diff --git a/functions/private/Invoke-WinUtilAssets.ps1 b/functions/private/Invoke-WinUtilAssets.ps1 new file mode 100644 index 000000000..6907909e1 --- /dev/null +++ b/functions/private/Invoke-WinUtilAssets.ps1 @@ -0,0 +1,199 @@ +function Invoke-WinUtilAssets { + param ( + $type, + $Size, + [switch]$render + ) + + # Create the Viewbox and set its size + $LogoViewbox = New-Object Windows.Controls.Viewbox + $LogoViewbox.Width = $Size + $LogoViewbox.Height = $Size + + # Create a Canvas to hold the paths + $canvas = New-Object Windows.Controls.Canvas + $canvas.Width = 100 + $canvas.Height = 100 + + # Define a scale factor for the content inside the Canvas + $scaleFactor = $Size / 100 + + # Apply a scale transform to the Canvas content + $scaleTransform = New-Object Windows.Media.ScaleTransform($scaleFactor, $scaleFactor) + $canvas.LayoutTransform = $scaleTransform + + switch ($type) { + 'logo' { + $LogoPathData1 = @" +M 18.00,14.00 +C 18.00,14.00 45.00,27.74 45.00,27.74 +45.00,27.74 57.40,34.63 57.40,34.63 +57.40,34.63 59.00,43.00 59.00,43.00 +59.00,43.00 59.00,83.00 59.00,83.00 +55.35,81.66 46.99,77.79 44.72,74.79 +41.17,70.10 42.01,59.80 42.00,54.00 +42.00,51.62 42.20,48.29 40.98,46.21 +38.34,41.74 25.78,38.60 21.28,33.79 +16.81,29.02 18.00,20.20 18.00,14.00 Z +"@ + $LogoPath1 = New-Object Windows.Shapes.Path + $LogoPath1.Data = [Windows.Media.Geometry]::Parse($LogoPathData1) + $LogoPath1.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#0567ff") + + $LogoPathData2 = @" +M 107.00,14.00 +C 109.01,19.06 108.93,30.37 104.66,34.21 +100.47,37.98 86.38,43.10 84.60,47.21 +83.94,48.74 84.01,51.32 84.00,53.00 +83.97,57.04 84.46,68.90 83.26,72.00 +81.06,77.70 72.54,81.42 67.00,83.00 +67.00,83.00 67.00,43.00 67.00,43.00 +67.00,43.00 67.99,35.63 67.99,35.63 +67.99,35.63 80.00,28.26 80.00,28.26 +80.00,28.26 107.00,14.00 107.00,14.00 Z +"@ + $LogoPath2 = New-Object Windows.Shapes.Path + $LogoPath2.Data = [Windows.Media.Geometry]::Parse($LogoPathData2) + $LogoPath2.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#0567ff") + + $LogoPathData3 = @" +M 19.00,46.00 +C 21.36,47.14 28.67,50.71 30.01,52.63 +31.17,54.30 30.99,57.04 31.00,59.00 +31.04,65.41 30.35,72.16 33.56,78.00 +38.19,86.45 46.10,89.04 54.00,93.31 +56.55,94.69 60.10,97.20 63.00,97.22 +65.50,97.24 68.77,95.36 71.00,94.25 +76.42,91.55 84.51,87.78 88.82,83.68 +94.56,78.20 95.96,70.59 96.00,63.00 +96.01,60.24 95.59,54.63 97.02,52.39 +98.80,49.60 103.95,47.87 107.00,47.00 +107.00,47.00 107.00,67.00 107.00,67.00 +106.90,87.69 96.10,93.85 80.00,103.00 +76.51,104.98 66.66,110.67 63.00,110.52 +60.33,110.41 55.55,107.53 53.00,106.25 +46.21,102.83 36.63,98.57 31.04,93.68 +16.88,81.28 19.00,62.88 19.00,46.00 Z +"@ + $LogoPath3 = New-Object Windows.Shapes.Path + $LogoPath3.Data = [Windows.Media.Geometry]::Parse($LogoPathData3) + $LogoPath3.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#a3a4a6") + + $canvas.Children.Add($LogoPath1) | Out-Null + $canvas.Children.Add($LogoPath2) | Out-Null + $canvas.Children.Add($LogoPath3) | Out-Null + } + 'checkmark' { + $canvas.Width = 512 + $canvas.Height = 512 + + $scaleFactor = $Size / 2.54 + $scaleTransform = New-Object Windows.Media.ScaleTransform($scaleFactor, $scaleFactor) + $canvas.LayoutTransform = $scaleTransform + + # Define the circle path + $circlePathData = "M 1.27,0 A 1.27,1.27 0 1,0 1.27,2.54 A 1.27,1.27 0 1,0 1.27,0" + $circlePath = New-Object Windows.Shapes.Path + $circlePath.Data = [Windows.Media.Geometry]::Parse($circlePathData) + $circlePath.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#39ba00") + + # Define the checkmark path + $checkmarkPathData = "M 0.873 1.89 L 0.41 1.391 A 0.17 0.17 0 0 1 0.418 1.151 A 0.17 0.17 0 0 1 0.658 1.16 L 1.016 1.543 L 1.583 1.013 A 0.17 0.17 0 0 1 1.599 1 L 1.865 0.751 A 0.17 0.17 0 0 1 2.105 0.759 A 0.17 0.17 0 0 1 2.097 0.999 L 1.282 1.759 L 0.999 2.022 L 0.874 1.888 Z" + $checkmarkPath = New-Object Windows.Shapes.Path + $checkmarkPath.Data = [Windows.Media.Geometry]::Parse($checkmarkPathData) + $checkmarkPath.Fill = [Windows.Media.Brushes]::White + + # Add the paths to the Canvas + $canvas.Children.Add($circlePath) | Out-Null + $canvas.Children.Add($checkmarkPath) | Out-Null + } + 'warning' { + $canvas.Width = 512 + $canvas.Height = 512 + + # Define a scale factor for the content inside the Canvas + $scaleFactor = $Size / 512 # Adjust scaling based on the canvas size + $scaleTransform = New-Object Windows.Media.ScaleTransform($scaleFactor, $scaleFactor) + $canvas.LayoutTransform = $scaleTransform + + # Define the circle path + $circlePathData = "M 256,0 A 256,256 0 1,0 256,512 A 256,256 0 1,0 256,0" + $circlePath = New-Object Windows.Shapes.Path + $circlePath.Data = [Windows.Media.Geometry]::Parse($circlePathData) + $circlePath.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#f41b43") + + # Define the exclamation mark path + $exclamationPathData = "M 256 307.2 A 35.89 35.89 0 0 1 220.14 272.74 L 215.41 153.3 A 35.89 35.89 0 0 1 251.27 116 H 260.73 A 35.89 35.89 0 0 1 296.59 153.3 L 291.86 272.74 A 35.89 35.89 0 0 1 256 307.2 Z" + $exclamationPath = New-Object Windows.Shapes.Path + $exclamationPath.Data = [Windows.Media.Geometry]::Parse($exclamationPathData) + $exclamationPath.Fill = [Windows.Media.Brushes]::White + + # Get the bounds of the exclamation mark path + $exclamationBounds = $exclamationPath.Data.Bounds + + # Calculate the center position for the exclamation mark path + $exclamationCenterX = ($canvas.Width - $exclamationBounds.Width) / 2 - $exclamationBounds.X + $exclamationPath.SetValue([Windows.Controls.Canvas]::LeftProperty, $exclamationCenterX) + + # Define the rounded rectangle at the bottom (dot of exclamation mark) + $roundedRectangle = New-Object Windows.Shapes.Rectangle + $roundedRectangle.Width = 80 + $roundedRectangle.Height = 80 + $roundedRectangle.RadiusX = 30 + $roundedRectangle.RadiusY = 30 + $roundedRectangle.Fill = [Windows.Media.Brushes]::White + + # Calculate the center position for the rounded rectangle + $centerX = ($canvas.Width - $roundedRectangle.Width) / 2 + $roundedRectangle.SetValue([Windows.Controls.Canvas]::LeftProperty, $centerX) + $roundedRectangle.SetValue([Windows.Controls.Canvas]::TopProperty, 324.34) + + # Add the paths to the Canvas + $canvas.Children.Add($circlePath) | Out-Null + $canvas.Children.Add($exclamationPath) | Out-Null + $canvas.Children.Add($roundedRectangle) | Out-Null + } + default { + Write-Host "Invalid type: $type" + } + } + + # Add the Canvas to the Viewbox + $LogoViewbox.Child = $canvas + + if ($render) { + # Measure and arrange the canvas to ensure proper rendering + $canvas.Measure([Windows.Size]::new($canvas.Width, $canvas.Height)) + $canvas.Arrange([Windows.Rect]::new(0, 0, $canvas.Width, $canvas.Height)) + $canvas.UpdateLayout() + + # Initialize RenderTargetBitmap correctly with dimensions + $renderTargetBitmap = New-Object Windows.Media.Imaging.RenderTargetBitmap($canvas.Width, $canvas.Height, 96, 96, [Windows.Media.PixelFormats]::Pbgra32) + + # Render the canvas to the bitmap + $renderTargetBitmap.Render($canvas) + + # Create a BitmapFrame from the RenderTargetBitmap + $bitmapFrame = [Windows.Media.Imaging.BitmapFrame]::Create($renderTargetBitmap) + + # Create a PngBitmapEncoder and add the frame + $bitmapEncoder = [Windows.Media.Imaging.PngBitmapEncoder]::new() + $bitmapEncoder.Frames.Add($bitmapFrame) + + # Save to a memory stream + $imageStream = New-Object System.IO.MemoryStream + $bitmapEncoder.Save($imageStream) + $imageStream.Position = 0 + + # Load the stream into a BitmapImage + $bitmapImage = [Windows.Media.Imaging.BitmapImage]::new() + $bitmapImage.BeginInit() + $bitmapImage.StreamSource = $imageStream + $bitmapImage.CacheOption = [Windows.Media.Imaging.BitmapCacheOption]::OnLoad + $bitmapImage.EndInit() + + return $bitmapImage + } else { + return $LogoViewbox + } +} diff --git a/functions/private/Invoke-WinUtilGPU.ps1 b/functions/private/Invoke-WinUtilGPU.ps1 index 2bcbb01b0..6ec42d7af 100644 --- a/functions/private/Invoke-WinUtilGPU.ps1 +++ b/functions/private/Invoke-WinUtilGPU.ps1 @@ -20,4 +20,4 @@ function Invoke-WinUtilGPU { } } return $true -} \ No newline at end of file +} diff --git a/functions/private/Invoke-WinUtilMicroWin-Helper.ps1 b/functions/private/Invoke-WinUtilMicroWin-Helper.ps1 index d1061d67f..0c485a4c5 100644 --- a/functions/private/Invoke-WinUtilMicroWin-Helper.ps1 +++ b/functions/private/Invoke-WinUtilMicroWin-Helper.ps1 @@ -37,23 +37,24 @@ function Remove-Features() { Remove-Features #> try { - $featlist = (Get-WindowsOptionalFeature -Path $scratchDir).FeatureName + $featlist = (Get-WindowsOptionalFeature -Path $scratchDir) $featlist = $featlist | Where-Object { - $_ -NotLike "*Defender*" -AND - $_ -NotLike "*Printing*" -AND - $_ -NotLike "*TelnetClient*" -AND - $_ -NotLike "*PowerShell*" -AND - $_ -NotLike "*NetFx*" -AND - $_ -NotLike "*Media*" -AND - $_ -NotLike "*NFS*" + $_.FeatureName -NotLike "*Defender*" -AND + $_.FeatureName -NotLike "*Printing*" -AND + $_.FeatureName -NotLike "*TelnetClient*" -AND + $_.FeatureName -NotLike "*PowerShell*" -AND + $_.FeatureName -NotLike "*NetFx*" -AND + $_.FeatureName -NotLike "*Media*" -AND + $_.FeatureName -NotLike "*NFS*" -AND + $_.State -ne "Disabled" } foreach($feature in $featlist) { - $status = "Removing feature $feature" + $status = "Removing feature $($feature.FeatureName)" 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-Debug "Removing feature $($feature.FeatureName)" + Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $($feature.FeatureName) -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 \Sources." @@ -259,7 +260,7 @@ function New-Unattend { param ( [Parameter(Mandatory, Position = 0)] [string]$userName, - [Parameter(Position = 1)] [string] $userPassword + [Parameter(Position = 1)] [string]$userPassword ) $unattend = @' diff --git a/functions/private/Set-WinUtilTaskbarItem.ps1 b/functions/private/Set-WinUtilTaskbarItem.ps1 index 465ca4c34..6eeb76749 100644 --- a/functions/private/Set-WinUtilTaskbarItem.ps1 +++ b/functions/private/Set-WinUtilTaskbarItem.ps1 @@ -61,13 +61,13 @@ function Set-WinUtilTaskbaritem { if ($overlay) { switch ($overlay) { 'logo' { - $sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\cttlogo.png" + $sync["Form"].taskbarItemInfo.Overlay = $sync["logorender"] } 'checkmark' { - $sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\checkmark.png" + $sync["Form"].taskbarItemInfo.Overlay = $sync["checkmarkrender"] } 'warning' { - $sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\warning.png" + $sync["Form"].taskbarItemInfo.Overlay = $sync["warningrender"] } 'None' { $sync["Form"].taskbarItemInfo.Overlay = $null diff --git a/functions/private/Show-CustomDialog.ps1 b/functions/private/Show-CustomDialog.ps1 index 7180b60ce..d2bbe0899 100644 --- a/functions/private/Show-CustomDialog.ps1 +++ b/functions/private/Show-CustomDialog.ps1 @@ -51,7 +51,7 @@ function Show-CustomDialog { $buttonBackgroundColor = $sync.configs.themes.$ctttheme.ButtonInstallBackgroundColor $buttonForegroundColor = $sync.configs.themes.$ctttheme.ButtonInstallForegroundColor $shadowColor = [Windows.Media.ColorConverter]::ConvertFromString("#AAAAAAAA") - $logocolor = $sync.configs.themes.$ctttheme.ButtonBackgroundPressedColor + $logocolor = $sync.configs.themes.$ctttheme.LabelboxForegroundColor # Create a custom dialog window $dialog = New-Object Windows.Window @@ -128,73 +128,15 @@ function Show-CustomDialog { $grid.Children.Add($stackPanel) [Windows.Controls.Grid]::SetRow($stackPanel, 0) # Set the row to the second row (0-based index) - $viewbox = New-Object Windows.Controls.Viewbox - $viewbox.Width = $IconSize - $viewbox.Height = $IconSize - - # Combine the paths into a single string -# $cttLogoPath = @" -# M174 1094 c-4 -14 -4 -55 -2 -92 3 -57 9 -75 41 -122 41 -60 45 -75 22 -84 -25 -9 -17 -21 30 -44 l45 -22 0 -103 c0 -91 3 -109 26 -155 30 -60 65 -87 204 -157 l95 -48 110 58 c184 96 205 127 205 293 l0 108 45 22 c47 23 55 36 30 46 -22 8 -18 30 9 63 13 16 34 48 46 71 20 37 21 52 15 116 l-6 73 -69 -23 c-38 -12 -137 -59 -220 -103 -82 -45 -160 -81 -171 -81 -12 0 -47 15 -78 34 -85 51 -239 127 -309 151 l-62 22 -6 -23z m500 -689 c20 -8 36 -19 36 -24 0 -18 -53 -51 -80 -51 -28 0 -80 33 -80 51 0 10 55 38 76 39 6 0 28 -7 48 -15z -# M177 711 c-19 -88 4 -242 49 -318 43 -74 107 -127 232 -191 176 -90 199 -84 28 7 -169 91 -214 129 -258 220 -29 58 -32 74 -37 190 -4 90 -8 116 -14 92z -# M1069 610 c-4 -131 -5 -137 -38 -198 -43 -79 -89 -119 -210 -181 -53 -27 -116 -61 -141 -76 -74 -43 -6 -20 115 40 221 109 296 217 294 425 -1 144 -16 137 -20 -10z -# "@ -$cttLogoPath = @" - M 18.00,14.00 - C 18.00,14.00 45.00,27.74 45.00,27.74 - 45.00,27.74 57.40,34.63 57.40,34.63 - 57.40,34.63 59.00,43.00 59.00,43.00 - 59.00,43.00 59.00,83.00 59.00,83.00 - 55.35,81.66 46.99,77.79 44.72,74.79 - 41.17,70.10 42.01,59.80 42.00,54.00 - 42.00,51.62 42.20,48.29 40.98,46.21 - 38.34,41.74 25.78,38.60 21.28,33.79 - 16.81,29.02 18.00,20.20 18.00,14.00 Z - M 107.00,14.00 - C 109.01,19.06 108.93,30.37 104.66,34.21 - 100.47,37.98 86.38,43.10 84.60,47.21 - 83.94,48.74 84.01,51.32 84.00,53.00 - 83.97,57.04 84.46,68.90 83.26,72.00 - 81.06,77.70 72.54,81.42 67.00,83.00 - 67.00,83.00 67.00,43.00 67.00,43.00 - 67.00,43.00 67.99,35.63 67.99,35.63 - 67.99,35.63 80.00,28.26 80.00,28.26 - 80.00,28.26 107.00,14.00 107.00,14.00 Z - M 19.00,46.00 - C 21.36,47.14 28.67,50.71 30.01,52.63 - 31.17,54.30 30.99,57.04 31.00,59.00 - 31.04,65.41 30.35,72.16 33.56,78.00 - 38.19,86.45 46.10,89.04 54.00,93.31 - 56.55,94.69 60.10,97.20 63.00,97.22 - 65.50,97.24 68.77,95.36 71.00,94.25 - 76.42,91.55 84.51,87.78 88.82,83.68 - 94.56,78.20 95.96,70.59 96.00,63.00 - 96.01,60.24 95.59,54.63 97.02,52.39 - 98.80,49.60 103.95,47.87 107.00,47.00 - 107.00,47.00 107.00,67.00 107.00,67.00 - 106.90,87.69 96.10,93.85 80.00,103.00 - 76.51,104.98 66.66,110.67 63.00,110.52 - 60.33,110.41 55.55,107.53 53.00,106.25 - 46.21,102.83 36.63,98.57 31.04,93.68 - 16.88,81.28 19.00,62.88 19.00,46.00 Z -"@ - - # Add SVG path - $svgPath = New-Object Windows.Shapes.Path - $svgPath.Data = [Windows.Media.Geometry]::Parse($cttLogoPath) - $svgPath.Fill = $logocolor # Set fill color to white - - # Add SVG path to Viewbox - $viewbox.Child = $svgPath - # Add SVG path to the stack panel - $stackPanel.Children.Add($viewbox) + $stackPanel.Children.Add((Invoke-WinUtilAssets -Type "logo" -Size 25)) # Add "Winutil" text $winutilTextBlock = New-Object Windows.Controls.TextBlock $winutilTextBlock.Text = "Winutil" $winutilTextBlock.FontSize = $HeaderFontSize $winutilTextBlock.Foreground = $logocolor - $winutilTextBlock.Margin = New-Object Windows.Thickness(10, 5, 10, 5) # Add margins around the text block + $winutilTextBlock.Margin = New-Object Windows.Thickness(10, 10, 10, 5) # Add margins around the text block $stackPanel.Children.Add($winutilTextBlock) # Add TextBlock for information with text wrapping and margins $messageTextBlock = New-Object Windows.Controls.TextBlock diff --git a/functions/public/Invoke-WPFButton.ps1 b/functions/public/Invoke-WPFButton.ps1 index e3015f09e..65d07a041 100644 --- a/functions/public/Invoke-WPFButton.ps1 +++ b/functions/public/Invoke-WPFButton.ps1 @@ -41,6 +41,7 @@ function Invoke-WPFButton { "WPFPanelpower" {Invoke-WPFControlPanel -Panel $button} "WPFPanelregion" {Invoke-WPFControlPanel -Panel $button} "WPFPanelsound" {Invoke-WPFControlPanel -Panel $button} + "WPFPanelprinter" {Invoke-WPFControlPanel -Panel $button} "WPFPanelsystem" {Invoke-WPFControlPanel -Panel $button} "WPFPaneluser" {Invoke-WPFControlPanel -Panel $button} "WPFUpdatesdefault" {Invoke-WPFUpdatesdefault} diff --git a/functions/public/Invoke-WPFControlPanel.ps1 b/functions/public/Invoke-WPFControlPanel.ps1 index eb0fdb2ac..b7a628e7a 100644 --- a/functions/public/Invoke-WPFControlPanel.ps1 +++ b/functions/public/Invoke-WPFControlPanel.ps1 @@ -16,6 +16,7 @@ function Invoke-WPFControlPanel { "WPFPanelpower" {cmd /c powercfg.cpl} "WPFPanelregion" {cmd /c intl.cpl} "WPFPanelsound" {cmd /c mmsys.cpl} + "WPFPanelprinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"} "WPFPanelsystem" {cmd /c sysdm.cpl} "WPFPaneluser" {cmd /c "control userpasswords2"} } diff --git a/functions/public/Invoke-WPFShortcut.ps1 b/functions/public/Invoke-WPFShortcut.ps1 index 6b25bdfe3..e4e47871e 100644 --- a/functions/public/Invoke-WPFShortcut.ps1 +++ b/functions/public/Invoke-WPFShortcut.ps1 @@ -51,6 +51,9 @@ function Invoke-WPFShortcut { $Shortcut = $WshShell.CreateShortcut($FileBrowser.FileName) $Shortcut.TargetPath = $shell $Shortcut.Arguments = $shellArgs + if (-NOT (Test-Path -Path $winutildir["logo.ico"])) { + Invoke-WebRequest -Uri "https://christitus.com/images/logo-full.ico" -OutFile $winutildir["logo.ico"] + } if (Test-Path -Path $winutildir["logo.ico"]) { $shortcut.IconLocation = $winutildir["logo.ico"] } diff --git a/functions/public/Invoke-WPFUIElements.ps1 b/functions/public/Invoke-WPFUIElements.ps1 index f8e9c7ba0..a1ed85684 100644 --- a/functions/public/Invoke-WPFUIElements.ps1 +++ b/functions/public/Invoke-WPFUIElements.ps1 @@ -304,13 +304,6 @@ function Invoke-WPFUIElements { $textBlock.ToolTip = $entryInfo.Link $textBlock.Style = $HoverTextBlockStyle - # Add event handler for click to open link - $handler = [System.Windows.Input.MouseButtonEventHandler]{ - param($sender, $e) - Start-Process $sender.ToolTip.ToString() - } - $textBlock.AddHandler([Windows.Controls.TextBlock]::MouseLeftButtonUpEvent, $handler) - $horizontalStackPanel.Children.Add($textBlock) | Out-Null $sync[$textBlock.Name] = $textBlock diff --git a/functions/public/Invoke-WPFUltimatePerformance.ps1 b/functions/public/Invoke-WPFUltimatePerformance.ps1 index 8000b4206..ac1dc1a6c 100644 --- a/functions/public/Invoke-WPFUltimatePerformance.ps1 +++ b/functions/public/Invoke-WPFUltimatePerformance.ps1 @@ -2,43 +2,65 @@ Function Invoke-WPFUltimatePerformance { <# .SYNOPSIS - Creates or removes the Ultimate Performance power scheme + Enables or disables the Ultimate Performance power scheme based on its GUID. .PARAMETER State - Indicates whether to enable or disable the Ultimate Performance power scheme + Specifies whether to "Enable" or "Disable" the Ultimate Performance power scheme. #> param($State) + try { - # Check if Ultimate Performance plan is installed - $ultimatePlan = powercfg -list | Select-String -Pattern "Ultimate Performance" - if($state -eq "Enable") { - if ($ultimatePlan) { - Write-Host "Ultimate Performance plan is already installed." - } else { - Write-Host "Installing Ultimate Performance plan..." - powercfg -duplicatescheme e9a42b02-d5df-448d-aa00-03f14749eb61 - Write-Host "> Ultimate Performance plan installed." + # GUID of the Ultimate Performance power plan + $ultimateGUID = "e9a42b02-d5df-448d-aa00-03f14749eb61" + + if ($State -eq "Enable") { + # Duplicate the Ultimate Performance power plan using its GUID + $duplicateOutput = powercfg /duplicatescheme $ultimateGUID + + $guid = $null + $nameFromFile = "ChrisTitus - Ultimate Power Plan" + $description = "Ultimate Power Plan, added via WinUtils" + + # Extract the new GUID from the duplicateOutput + foreach ($line in $duplicateOutput) { + if ($line -match "\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b") { + $guid = $matches[0] # $matches[0] will contain the first match, which is the GUID + Write-Output "GUID: $guid has been extracted and stored in the variable." + break + } } - # Set the Ultimate Performance plan as active - $ultimatePlanGUID = (powercfg -list | Select-String -Pattern "Ultimate Performance").Line.Split()[3] - powercfg -setactive $ultimatePlanGUID + if (-not $guid) { + Write-Output "No GUID found in the duplicateOutput. Check the output format." + exit 1 + } - Write-Host "Ultimate Performance plan is now active." + # Change the name of the power plan and set its description + $changeNameOutput = powercfg /changename $guid "$nameFromFile" "$description" + Write-Output "The power plan name and description have been changed. Output:" + Write-Output $changeNameOutput + # Set the duplicated Ultimate Performance plan as active + $setActiveOutput = powercfg /setactive $guid + Write-Output "The power plan has been set as active. Output:" + Write-Output $setActiveOutput - } - elseif($state -eq "Disable") { - if ($ultimatePlan) { - # Extract the GUID of the Ultimate Performance plan - $ultimatePlanGUID = $ultimatePlan.Line.Split()[3] + Write-Host "> Ultimate Performance plan installed and set as active." + + } elseif ($State -eq "Disable") { + # Check if the Ultimate Performance plan is installed by GUID + $installedPlan = powercfg -list | Select-String -Pattern $ultimateGUID + + if ($installedPlan) { + # Extract the GUID of the installed Ultimate Performance plan + $ultimatePlanGUID = $installedPlan.Line.Split()[3] # Set a different power plan as active before deleting the Ultimate Performance plan $balancedPlanGUID = (powercfg -list | Select-String -Pattern "Balanced").Line.Split()[3] powercfg -setactive $balancedPlanGUID - # Delete the Ultimate Performance plan + # Delete the Ultimate Performance plan by GUID powercfg -delete $ultimatePlanGUID Write-Host "Ultimate Performance plan has been uninstalled." @@ -48,6 +70,6 @@ Function Invoke-WPFUltimatePerformance { } } } catch { - Write-Warning $psitem.Exception.Message + Write-Error "Error occurred: $_" } } diff --git a/scripts/main.ps1 b/scripts/main.ps1 index 0d706c325..ef206840b 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -32,19 +32,19 @@ $sync.runspace.Open() # Create classes for different exceptions class WingetFailedInstall : Exception { - [string] $additionalData + [string]$additionalData WingetFailedInstall($Message) : base($Message) {} } class ChocoFailedInstall : Exception { - [string] $additionalData + [string]$additionalData ChocoFailedInstall($Message) : base($Message) {} } class GenericException : Exception { - [string] $additionalData + [string]$additionalData GenericException($Message) : base($Message) {} } @@ -445,35 +445,25 @@ $sync["Form"].Add_Loaded({ $sync["Form"].MaxHeight = [Double]::PositiveInfinity }) +$NavLogoPanel = $sync["Form"].FindName("NavLogoPanel") +$NavLogoPanel.Children.Add((Invoke-WinUtilAssets -Type "logo" -Size 25)) | Out-Null + # 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 -} +[System.IO.Directory]::CreateDirectory($winutildir["path"]) | Out-Null -# 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"] +if (Test-Path $winutildir["logo.ico"]) { + $sync["logorender"] = $winutildir["logo.ico"] +} else { + $sync["logorender"] = (Invoke-WinUtilAssets -Type "Logo" -Size 90 -Render) } - +$sync["checkmarkrender"] = (Invoke-WinUtilAssets -Type "checkmark" -Size 512 -Render) +$sync["warningrender"] = (Invoke-WinUtilAssets -Type "warning" -Size 512 -Render) Set-WinUtilTaskbaritem -overlay "logo" @@ -522,10 +512,10 @@ Version : - param ( + param ( [Parameter(position=0)] [switch]$SkipExcludedFilesValidation, @@ -66,29 +66,86 @@ [Parameter(position=5)] [string]$ProgressActivity = "Preprocessing" - ) + ) if (-NOT (Test-Path -PathType Container -Path "$WorkingDir")) { throw "[Invoke-Preprocessing] Invalid Paramter Value for 'WorkingDir', passed value: '$WorkingDir'. Either the path is a File or Non-Existing/Invlid, please double check your code." } $count = $ExcludedFiles.Count - if ((-NOT ($count -eq 0)) -AND (-NOT $SkipExcludedFilesValidation)) { + + # Make sure there's a * at the end of folders in ExcludedFiles list + for ($i = 0; $i -lt $count; $i++) { + $excludedFile = $ExcludedFiles[$i] + $isFolder = ($excludedFile) -match '\\$' + if ($isFolder) { $ExcludedFiles[$i] = $excludedFile + '*' } + } + + # Validate the ExcludedFiles List before continuing on, + # that's if there's a list in the first place, and '-SkipExcludedFilesValidation' was not provided. + if (-not $SkipExcludedFilesValidation) { for ($i = 0; $i -lt $count; $i++) { $excludedFile = $ExcludedFiles[$i] $filePath = "$(($WorkingDir -replace ('\\$', '')) + '\' + ($excludedFile -replace ('\.\\', '')))" - if (-NOT (Get-ChildItem -Recurse -Path "$filePath" -File -Force)) { - $failedFilesList += "'$filePath', " + + # Handle paths with wildcards in a different implementation + $matches = ($filePath) -match '^.*?\*' + + if ($matches) { + if (-NOT (Get-ChildItem -Recurse -Path "$filePath" -File)) { + $failedFilesList += "'$filePath', " + } + } else { + if (-NOT (Test-Path -Path "$filePath")) { + $failedFilesList += "'$filePath', " + } } } $failedFilesList = $failedFilesList -replace (',\s*$', '') if (-NOT $failedFilesList -eq "") { - throw "[Invoke-Preprocessing] One or more File Paths & File Patterns were not found, you can use '-SkipExcludedFilesValidation' switch to skip this check, and the failed files are: $failedFilesList" + throw "[Invoke-Preprocessing] One or more File Paths and/or File Patterns were not found, you can use '-SkipExcludedFilesValidation' switch to skip this check, the failed to validate are: $failedFilesList" } } - $files = Get-ChildItem $WorkingDir -Recurse -Exclude $ExcludedFiles -File -Force + # Get Files List + [System.Collections.ArrayList]$files = Get-ChildItem $WorkingDir -Recurse -Exclude $ExcludedFiles -File -Force + $numOfFiles = $files.Count + + # Only keep the 'FullName' Property for every entry in the list + for ($i = 0; $i -lt $numOfFiles; $i++) { + $file = $files[$i] + $files[$i] = $file.FullName + } + # If a file(s) are found in Exclude List, + # Remove the file from files list. + for ($j = 0; $j -lt $excludedFiles.Count; $j++) { + # Prepare some variables + $excluded = $excludedFiles[$j] + $pathToFind = ($excluded) -replace ('^\.\\', '') + $pathToFind = $WorkingDir + '\' + $pathToFind + $index = -1 # reset index on every iteration + + # Handle paths with wildcards in a different implementation + $matches = ($pathToFind) -match '^.*?\*' + + if ($matches) { + $filesToCheck = Get-ChildItem -Recurse -Path "$pathToFind" -File -Force + if ($filesToCheck) { + for ($k = 0; $k -lt $filesToCheck.Count; $k++) { + $fileToCheck = $filesToCheck[$k] + $index = $files.IndexOf("$fileToCheck") + if ($index -ge 0) { $files.RemoveAt($index) } + } + } + } else { + $index = $files.IndexOf("$pathToFind") + if ($index -ge 0) { $files.RemoveAt($index) } + } + } + + # Make sure 'numOfFiles' is synced with the actual Number of Files found in '$files' + # This's done because previous may or may not edit the files list, so we should update it $numOfFiles = $files.Count if ($numOfFiles -eq 0) { @@ -100,26 +157,11 @@ } for ($i = 0; $i -lt $numOfFiles; $i++) { - $file = $files[$i] - - # If the file is in Exclude List, don't proceed to check/modify said file. - $fileIsExcluded = $False - for ($j = 0; $j -lt $excludedFiles.Count; $j++) { - $excluded = $excludedFiles[$j] - $strToCompare = ($excluded) -replace ('^\.\\', '') - if ($file.FullName.Contains("$strToCompare")) { - $fileIsExcluded = $True - break - } - } - - if ($fileIsExcluded) { - continue - } + $fullFileName = $files[$i] # TODO: # make more formatting rules, and document them in WinUtil Official Documentation - (Get-Content "$file").TrimEnd() ` + (Get-Content "$fullFileName").TrimEnd() ` -replace ('\t', ' ') ` -replace ('\)\s*\{', ') {') ` -replace ('(?if|for|foreach)\s*(?\([.*?]\))\s*\{', '${keyword} ${condition} {') ` @@ -130,8 +172,8 @@ -replace ('\}\s*Catch', '} catch') ` -replace ('\}\s*Catch\s*(?(\[.*?\]\s*(\,)?\s*)+)\s*\{', '} catch ${exceptions} {') ` -replace ('\}\s*Catch\s*(?\[.*?\])\s*\{', '} catch ${exceptions} {') ` - -replace ('(?\[.*?\])\s*(?\$.*?(,|\s*\)))', '${parameter_type}${str_after_type}') ` - | Set-Content "$file" + -replace ('(?\[[^$0-9]+\])\s*(?\$.*?)', '${parameter_type}${str_after_type}') ` + | Set-Content "$fullFileName" Write-Progress -Activity $ProgressActivity -Status "$ProgressStatusMessage - Finished $i out of $numOfFiles" -PercentComplete (($i/$numOfFiles)*100) } diff --git a/xaml/inputXML.xaml b/xaml/inputXML.xaml index 8094af4a2..1dd80b944 100644 --- a/xaml/inputXML.xaml +++ b/xaml/inputXML.xaml @@ -649,8 +649,8 @@ - + +