From 3b133e704e1d393161ca957f2ce40b111a2355fa Mon Sep 17 00:00:00 2001 From: Chris Titus Date: Mon, 15 Jan 2024 11:32:19 -0600 Subject: [PATCH] Test 2024 01 12 (#1401) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * change logseq url and add .net 8 (#1385) * Update applications.json Add Official logseq url Add .net runtime 8.0 * compile with new logseq and .net 8 runtime * add thorium avx2 * Compile Winutil * Remove Cider Music Player (#1400) * Update winutil.ps1 * Update applications.json * Compile Winutil * Import/Export is now global, Settings menu added and many more improvements (#1398) * Anoter one of those huge PRs - Fix version inefficiency the version is already stored in sync, no need to slow down loading by one extra replace. - Created custom dialog and About message - Create a menu with Import/Export values - press on teh Settings cog in the right upper corner and save all the checkboxes - then you can either load them or load and run automatically - Made Import Export load accross the whole app - Optimized the way checkbox controls are looked up, it is 20% faster now - Added a switch to load all the boxes from a config file - example: .winutil.ps1 -Config "C:UsersasdfDesktop\111.json" - Added a switch to run all the action in unattended mode by passing -Run siwthc - example: .winutil.ps1 -Config "C:UsersasdfDesktop\111.json" -Run - This will run all the tweaks and install all the apps * Fixing a couple of bugs and blur fonts, also menu now closes when focus is lost --------- Co-authored-by: KonTy Co-authored-by: Chris Titus * Update applications.json * Compile Winutil * Add F8 Recovery Menu and Windows Reg Backup and others (#1389) * Update feature.json append F8 legacy startup and Win Reg Backup and web search suggestion in search app - enable automatic windows registry backup and do schedule for it as well (disabled by default in Win10, Win11) this will help when doing last known Good Configuration thru the F8 startup menu. - enable / disable legacy F8 startup recovery option. - enable / disable web search suggestions in the windows search in task bar. * new tick boxes features. F8 recovery, regbackup, search web suggestions - enable automatic windows registry backup and do schedule for it as well (disabled by default in Win10, Win11) this will help when doing last known Good Configuration thru the F8 startup menu. - enable / disable legacy F8 startup recovery option. - enable / disable web search suggestions in the windows search in task bar. * Compile Winutil * add Parsec to installable applications (#1157) (#1396) Identifiers: - Winget: Parsec.parsec - Chocolatey: parsec * Compile Winutil * add Konty to About page * Compile Winutil * fix description (#1388) (#1402) Co-authored-by: howell2024 <156375832+howell2024@users.noreply.github.com> --------- Co-authored-by: Cristian Negulescu Co-authored-by: ChrisTitusTech Co-authored-by: Tommi Pöntinen <98650216+hamburgerghini1@users.noreply.github.com> Co-authored-by: KonTy <9524513+KonTy@users.noreply.github.com> Co-authored-by: KonTy Co-authored-by: Smartek <70715469+smartekIT@users.noreply.github.com> Co-authored-by: Saikrishnan K <53394202+K-Saikrishnan@users.noreply.github.com> Co-authored-by: howell2024 <156375832+howell2024@users.noreply.github.com> --- Compile.ps1 | 6 +- config/applications.json | 40 +- config/feature.json | 65 + config/preset.json | 46 +- config/tweaks.json | 48 +- functions/private/Get-WinUtilCheckBoxes.ps1 | 86 +- functions/private/Invoke-MicroWin-Helper.ps1 | 19 +- functions/private/Invoke-WinUtilTweaks.ps1 | 7 + functions/private/Show-CustomDialog.ps1 | 221 ++++ .../private/Update-WinUtilProgramWinget.ps1 | 1 - functions/public/Invoke-WPFButton.ps1 | 4 - functions/public/Invoke-WPFFeatureInstall.ps1 | 15 +- functions/public/Invoke-WPFGetInstalled.ps1 | 6 +- functions/public/Invoke-WPFImpex.ps1 | 36 +- functions/public/Invoke-WPFInstall.ps1 | 20 +- functions/public/Invoke-WPFInstallUpgrade.ps1 | 2 +- functions/public/Invoke-WPFPresets.ps1 | 41 +- functions/public/Invoke-WPFRunspace.ps1 | 4 +- functions/public/Invoke-WPFShortcut.ps1 | 20 +- functions/public/Invoke-WPFUnInstall.ps1 | 9 +- functions/public/Invoke-WPFtweaksbutton.ps1 | 38 +- functions/public/Invoke-WPFundoall.ps1 | 8 +- scripts/main.ps1 | 137 +- scripts/start.ps1 | 22 + winutil.ps1 | 1143 ++++++++++++----- xaml/inputXML.xaml | 246 ++-- 26 files changed, 1645 insertions(+), 645 deletions(-) create mode 100644 functions/private/Show-CustomDialog.ps1 diff --git a/Compile.ps1 b/Compile.ps1 index 69265228..1bb5b03f 100644 --- a/Compile.ps1 +++ b/Compile.ps1 @@ -15,7 +15,7 @@ Write-output ' ################################################################################################################ ' | Out-File ./$scriptname -Append -Encoding ascii -(Get-Content .\scripts\start.ps1).replace('#{replaceme}',"$(get-date -format yy.MM.dd)") | Out-File ./$scriptname -Append -Encoding ascii +(Get-Content .\scripts\start.ps1).replace('#{replaceme}',"$(Get-Date -Format yy.MM.dd)") | Out-File ./$scriptname -Append -Encoding ascii Get-ChildItem .\functions -Recurse -File | ForEach-Object { Get-Content $psitem.FullName | Out-File ./$scriptname -Append -Encoding ascii @@ -23,9 +23,7 @@ Get-ChildItem .\functions -Recurse -File | ForEach-Object { Get-ChildItem .\xaml | ForEach-Object { $xaml = (Get-Content $psitem.FullName).replace("'","''") - $newXaml = $xaml -replace 'CTTVersion', (Get-Date -Format 'yy.MM.dd') - - Write-output "`$$($psitem.BaseName) = '$newXaml'" | Out-File ./$scriptname -Append -Encoding ascii + Write-output "`$$($psitem.BaseName) = '$xaml'" | Out-File ./$scriptname -Append -Encoding ascii } Get-ChildItem .\config | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object { diff --git a/config/applications.json b/config/applications.json index 36b694d9..c5ffd996 100755 --- a/config/applications.json +++ b/config/applications.json @@ -71,6 +71,15 @@ "link": "https://librewolf-community.gitlab.io/", "description": "LibreWolf is a privacy-focused web browser based on Firefox, with additional privacy and security enhancements." }, + "WPFInstallthorium": { + "winget": "Alex313031.Thorium.AVX2", + "choco": "na", + "category": "Browsers", + "panel": "0", + "content": "Thorium Browser AVX2", + "link": "http://thorium.rocks/", + "description": "Browser built for speed over vanilla chromium. It is built with AVX2 optimizations and is the fastest browser on the market." + }, "WPFInstalltor": { "winget": "TorProject.TorBrowser", "choco": "tor-browser", @@ -653,7 +662,7 @@ "category": "Document", "panel": "1", "content": "Logseq", - "link": "https://github.com/logseq/logseq/releases", + "link": "https://logseq.com/", "description": "Logseq is a versatile knowledge management and note-taking application designed for the digital thinker. With a focus on the interconnectedness of ideas, Logseq allows users to seamlessly organize their thoughts through a combination of hierarchical outlines and bi-directional linking. It supports both structured and unstructured content, enabling users to create a personalized knowledge graph that adapts to their evolving ideas and insights." }, "WPFInstallobsidian": { @@ -961,6 +970,15 @@ "content": ".NET Desktop Runtime 7", "description": ".NET Desktop Runtime 7 is a runtime environment required for running applications developed with .NET 7.", "link": "https://dotnet.microsoft.com/download/dotnet/7.0" + }, + "WPFInstalldotnet8": { + "winget": "Microsoft.DotNet.DesktopRuntime.8", + "choco": "dotnet-8.0-runtime", + "category": "Microsoft Tools", + "panel": "2", + "content": ".NET Desktop Runtime 8", + "description": ".NET Desktop Runtime 8 is a runtime environment required for running applications developed with .NET 7.", + "link": "https://dotnet.microsoft.com/download/dotnet/8.0" }, "WPFInstallnuget": { "winget": "Microsoft.NuGet", @@ -1070,15 +1088,6 @@ "description": "Blender is a powerful open-source 3D creation suite, offering modeling, sculpting, animation, and rendering tools.", "link": "https://www.blender.org/" }, - "WPFInstallcider": { - "winget": "CiderCollective.Cider", - "choco": "cider", - "category": "Multimedia Tools", - "panel": "3", - "content": "Cider (FOSS Music Player)", - "description": "Cider is a free and open-source music player that focuses on simplicity, providing a clean interface for enjoying your music.", - "link": "https://getcider.io/" - }, "WPFInstallclementine": { "winget": "Clementine.Clementine", "choco": "clementine", @@ -1925,6 +1934,15 @@ "link": "https://owncloud.com/desktop-app/", "description": "ownCloud Desktop is the official desktop client for the ownCloud file synchronization and sharing platform." }, + "WPFInstallparsec": { + "winget": "Parsec.parsec", + "choco": "parsec", + "category": "Utilities", + "panel": "4", + "content": "Parsec", + "link": "https://parsec.app/", + "description": "Parsec is a low-latency, high-quality remote desktop sharing application for collaborating and gaming across devices." + }, "WPFInstallpeazip": { "winget": "Giorgiotani.Peazip", "choco": "peazip", @@ -2213,4 +2231,4 @@ "link": "https://www.ghisler.com/", "description": "Total Commander is a file manager for Windows that provides a powerful and intuitive interface for file management." } -} \ No newline at end of file +} diff --git a/config/feature.json b/config/feature.json index 1bb7f09f..9adf4f74 100644 --- a/config/feature.json +++ b/config/feature.json @@ -57,5 +57,70 @@ nfsadmin client localhost config fileaccess=755 SecFlavors=+sys -krb5 -krb5i " ] + }, + "WPFFeatureEnableSearchSuggestions": { + "feature": [ + ], + "InvokeScript": [ + " + If (!(Test-Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer')) { + New-Item -Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' -Force | Out-Null + } + New-ItemProperty -Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' -Name 'DisableSearchBoxSuggestions' -Type DWord -Value 0 -Force + Stop-Process -name explorer -force + " + ] + }, + "WPFFeatureDisableSearchSuggestions": { + "feature": [ + ], + "InvokeScript": [ + " + If (!(Test-Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer')) { + New-Item -Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' -Force | Out-Null + } + New-ItemProperty -Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' -Name 'DisableSearchBoxSuggestions' -Type DWord -Value 1 -Force + Stop-Process -name explorer -force + " + ] + }, + "WPFFeatureRegBackup": { + "feature": [ + ], + "InvokeScript": [ + " + New-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager' -Name 'EnablePeriodicBackup' -Type DWord -Value 1 -Force + New-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager' -Name 'BackupCount' -Type DWord -Value 2 -Force + $action = New-ScheduledTaskAction -Execute 'schtasks' -Argument '/run /i /tn \"\\Microsoft\\Windows\\Registry\\RegIdleBackup\"' + $trigger = New-ScheduledTaskTrigger -Daily -At 00:30 + Register-ScheduledTask -Action $action -Trigger $trigger -TaskName 'AutoRegBackup' -Description 'Create System Registry Backups' -User 'System' + " + ] + }, + "WPFFeatureEnableLegacyRecovery": { + "feature": [ + ], + "InvokeScript": [ + " + If (!(Test-Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood')) { + New-Item -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood' -Force | Out-Null + } + New-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood' -Name 'Enabled' -Type DWord -Value 1 -Force + Start-Process -FilePath cmd.exe -ArgumentList '/c bcdedit /Set {Current} BootMenuPolicy Legacy' -Wait + " + ] + }, + "WPFFeatureDisableLegacyRecovery": { + "feature": [ + ], + "InvokeScript": [ + " + If (!(Test-Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood')) { + New-Item -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood' -Force | Out-Null + } + New-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood' -Name 'Enabled' -Type DWord -Value 0 -Force + Start-Process -FilePath cmd.exe -ArgumentList '/c bcdedit /Set {Current} BootMenuPolicy Standard' -Wait + " + ] } } diff --git a/config/preset.json b/config/preset.json index d7dd7957..51b48fa1 100644 --- a/config/preset.json +++ b/config/preset.json @@ -1,33 +1,33 @@ { "desktop": [ - "WPFEssTweaksAH", - "WPFEssTweaksDVR", - "WPFEssTweaksHiber", - "WPFEssTweaksHome", - "WPFEssTweaksLoc", - "WPFEssTweaksOO", - "WPFEssTweaksServices", - "WPFEssTweaksStorage", - "WPFEssTweaksTele", - "WPFEssTweaksWifi", + "WPFTweaksAH", + "WPFTweaksDVR", + "WPFTweaksHiber", + "WPFTweaksHome", + "WPFTweaksLoc", + "WPFTweaksOO", + "WPFTweaksServices", + "WPFTweaksStorage", + "WPFTweaksTele", + "WPFTweaksWifi", "WPFMiscTweaksPower" ], "laptop": [ - "WPFEssTweaksAH", - "WPFEssTweaksDVR", - "WPFEssTweaksHome", - "WPFEssTweaksLoc", - "WPFEssTweaksOO", - "WPFEssTweaksServices", - "WPFEssTweaksStorage", - "WPFEssTweaksTele", - "WPFEssTweaksWifi", + "WPFTweaksAH", + "WPFTweaksDVR", + "WPFTweaksHome", + "WPFTweaksLoc", + "WPFTweaksOO", + "WPFTweaksServices", + "WPFTweaksStorage", + "WPFTweaksTele", + "WPFTweaksWifi", "WPFMiscTweaksLapPower" ], "minimal": [ - "WPFEssTweaksHome", - "WPFEssTweaksOO", - "WPFEssTweaksServices", - "WPFEssTweaksTele" + "WPFTweaksHome", + "WPFTweaksOO", + "WPFTweaksServices", + "WPFTweaksTele" ] } diff --git a/config/tweaks.json b/config/tweaks.json index ead26d62..ff0dce16 100644 --- a/config/tweaks.json +++ b/config/tweaks.json @@ -1,5 +1,5 @@ { - "WPFEssTweaksAH": { + "WPFTweaksAH": { "registry": [ { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System", @@ -24,7 +24,7 @@ } ] }, - "WPFEssTweaksHiber": { + "WPFTweaksHiber": { "registry": [ { "Path": "HKLM:\\System\\CurrentControlSet\\Control\\Session Manager\\Power", @@ -45,7 +45,7 @@ "powercfg.exe /hibernate off" ] }, - "WPFEssTweaksHome": { + "WPFTweaksHome": { "service": [ { "Name": "HomeGroupListener", @@ -59,7 +59,7 @@ } ] }, - "WPFEssTweaksLoc": { + "WPFTweaksLoc": { "registry": [ { "Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\CapabilityAccessManager\\ConsentStore\\location", @@ -91,7 +91,7 @@ } ] }, - "WPFEssTweaksServices": { + "WPFTweaksServices": { "service": [ { "Name": "AJRouter", @@ -1510,7 +1510,7 @@ } ] }, - "WPFEssTweaksTele": { + "WPFTweaksTele": { "ScheduledTask": [ { "Name": "Microsoft\\Windows\\Application Experience\\Microsoft Compatibility Appraiser", @@ -1897,7 +1897,7 @@ " ] }, - "WPFEssTweaksWifi": { + "WPFTweaksWifi": { "registry": [ { "Path": "HKLM:\\Software\\Microsoft\\PolicyManager\\default\\WiFi\\AllowWiFiHotSpotReporting", @@ -1915,7 +1915,7 @@ } ] }, - "WPFMiscTweaksUTC": { + "WPFTweaksUTC": { "registry": [ { "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation", @@ -1926,7 +1926,7 @@ } ] }, - "WPFMiscTweaksDisplay": { + "WPFTweaksDisplay": { "registry": [ { "Path": "HKCU:\\Control Panel\\Desktop", @@ -2027,7 +2027,7 @@ "Remove-ItemProperty -Path \"HKCU:\\Control Panel\\Desktop\" -Name \"UserPreferencesMask\"" ] }, - "WPFEssTweaksDeBloat": { + "WPFTweaksDeBloat": { "appx": [ "Microsoft.Microsoft3DViewer", "Microsoft.AppConnector", @@ -2141,7 +2141,7 @@ " ] }, - "WPFEssTweaksRestorePoint": { + "WPFTweaksRestorePoint": { "InvokeScript": [ " # Check if the user has administrative privileges @@ -2178,7 +2178,7 @@ " ] }, - "WPFEssTweaksOO": { + "WPFTweaksOO": { "InvokeScript": [ "curl.exe -s \"https://raw.githubusercontent.com/ChrisTitusTech/winutil/main/ooshutup10_winutil_settings.cfg\" -o $ENV:temp\\ooshutup10.cfg curl.exe -s \"https://dl5.oo-software.com/files/ooshutup10/OOSU10.exe\" -o $ENV:temp\\OOSU10.exe @@ -2186,7 +2186,7 @@ " ] }, - "WPFEssTweaksStorage": { + "WPFTweaksStorage": { "InvokeScript": [ "Remove-Item -Path \"HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\StorageSense\\Parameters\\StoragePolicy\" -Recurse -ErrorAction SilentlyContinue" ], @@ -2195,7 +2195,7 @@ " ] }, - "WPFEssTweaksRemoveEdge": { + "WPFTweaksRemoveEdge": { "InvokeScript": [ " #:: Standalone script by AveYo Source: https://raw.githubusercontent.com/AveYo/fox/main/Edge_Removal.bat @@ -2212,7 +2212,7 @@ " ] }, - "WPFEssTweaksRemoveOnedrive": { + "WPFTweaksRemoveOnedrive": { "InvokeScript": [ " @@ -2289,7 +2289,7 @@ " ] }, - "WPFMiscTweaksDisableNotifications": { + "WPFTweaksDisableNotifications": { "registry": [ { "Path": "HKCU:\\Software\\Policies\\Microsoft\\Windows\\Explorer", @@ -2307,7 +2307,7 @@ } ] }, - "WPFMiscTweaksRightClickMenu": { + "WPFTweaksRightClickMenu": { "InvokeScript": [ "New-Item -Path \"HKCU:\\Software\\Classes\\CLSID\\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\" -Name \"InprocServer32\" -force -value \"\" " ], @@ -2318,7 +2318,7 @@ " ] }, - "WPFEssTweaksDiskCleanup": { + "WPFTweaksDiskCleanup": { "InvokeScript": [ " cleanmgr.exe /d C: /VERYLOWDISK @@ -2326,7 +2326,7 @@ " ] }, - "WPFMiscTweaksDisableUAC": { + "WPFTweaksDisableUAC": { "registry": [ { "Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", @@ -2337,13 +2337,13 @@ } ] }, - "WPFEssTweaksDeleteTempFiles": { + "WPFTweaksDeleteTempFiles": { "InvokeScript": [ "Get-ChildItem -Path \"C:\\Windows\\Temp\" *.* -Recurse | Remove-Item -Force -Recurse Get-ChildItem -Path $env:TEMP *.* -Recurse | Remove-Item -Force -Recurse" ] }, - "WPFEssTweaksDVR": { + "WPFTweaksDVR": { "registry": [ { "Path": "HKCU:\\System\\GameConfigStore", @@ -2389,7 +2389,7 @@ } ] }, - "WPFEssTweaksTeredo": { + "WPFTweaksTeredo": { "registry": [ { "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters", @@ -2417,7 +2417,7 @@ } ] }, - "WPFMiscTweaksDisableipsix": { + "WPFTweaksDisableipsix": { "InvokeScript": [ "Disable-NetAdapterBinding -Name \"*\" -ComponentID ms_tcpip6" ], @@ -2425,7 +2425,7 @@ "Enable-NetAdapterBinding -Name \"*\" -ComponentID ms_tcpip6" ] }, - "WPFMiscTweaksEnableipsix": { + "WPFTweaksEnableipsix": { "InvokeScript": [ "Enable-NetAdapterBinding -Name \"*\" -ComponentID ms_tcpip6" ], diff --git a/functions/private/Get-WinUtilCheckBoxes.ps1 b/functions/private/Get-WinUtilCheckBoxes.ps1 index fef27cc8..2096d1fc 100644 --- a/functions/private/Get-WinUtilCheckBoxes.ps1 +++ b/functions/private/Get-WinUtilCheckBoxes.ps1 @@ -20,56 +20,58 @@ Function Get-WinUtilCheckBoxes { #> Param( - $Group, - [boolean]$unCheck = $true + [boolean]$unCheck = $false ) - - $Output = New-Object System.Collections.Generic.List[System.Object] - - if($Group -eq "WPFInstall"){ - $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPFInstall*"} - $CheckBoxes = $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} - Foreach ($CheckBox in $CheckBoxes){ - if($CheckBox.value.ischecked -eq $true){ - $sync.configs.applications.$($CheckBox.Name).winget -split ";" | ForEach-Object { - $Output.Add($psitem) - } - if ($uncheck -eq $true){ - $CheckBox.value.ischecked = $false - } - - } - } + $Output = @{ + Install = @() + WPFTweaks = @() + WPFFeature = @() + WPFInstall = @() } - if($Group -eq "WPFTweaks"){ - $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPF*Tweaks*"} - $CheckBoxes = $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} - Foreach ($CheckBox in $CheckBoxes){ - if($CheckBox.value.ischecked -eq $true){ - $Output.Add($Checkbox.Name) + $CheckBoxes = $sync.GetEnumerator() | Where-Object { $_.Value -is [System.Windows.Controls.CheckBox] } - if ($uncheck -eq $true){ - $CheckBox.value.ischecked = $false + foreach ($CheckBox in $CheckBoxes) { + $group = if ($CheckBox.Key.StartsWith("WPFInstall")) { "Install" } + elseif ($CheckBox.Key.StartsWith("WPFTweaks")) { "WPFTweaks" } + elseif ($CheckBox.Key.StartsWith("WPFFeature")) { "WPFFeature" } + + if ($group) { + if ($CheckBox.Value.IsChecked -eq $true) { + $feature = switch ($group) { + "Install" { + # Get the winget value + $wingetValue = $sync.configs.applications.$($CheckBox.Name).winget + + if (-not [string]::IsNullOrWhiteSpace($wingetValue) -and $wingetValue -ne "na") { + $wingetValue -split ";" + } else { + $sync.configs.applications.$($CheckBox.Name).choco + } + } + default { + $CheckBox.Name + } + } + + if (-not $Output.ContainsKey($group)) { + $Output[$group] = @() + } + if ($group -eq "Install") { + $Output["WPFInstall"] += $CheckBox.Name + Write-Debug "Adding: $($CheckBox.Name) under: WPFInstall" + } + + Write-Debug "Adding: $($feature) under: $($group)" + $Output[$group] += $feature + + if ($uncheck -eq $true) { + $CheckBox.Value.IsChecked = $false } } } } - if($Group -eq "WPFFeature"){ - $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPF*Feature*"} - $CheckBoxes = $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} - Foreach ($CheckBox in $CheckBoxes){ - if($CheckBox.value.ischecked -eq $true){ - $Output.Add($Checkbox.Name) - - if ($uncheck -eq $true){ - $CheckBox.value.ischecked = $false - } - } - } - } - - Write-Output $($Output | Select-Object -Unique) + return $Output } diff --git a/functions/private/Invoke-MicroWin-Helper.ps1 b/functions/private/Invoke-MicroWin-Helper.ps1 index 7abc4936..fb679b47 100644 --- a/functions/private/Invoke-MicroWin-Helper.ps1 +++ b/functions/private/Invoke-MicroWin-Helper.ps1 @@ -276,19 +276,22 @@ function New-Unattend { # net user administrator /active:yes # + # this section doesn't work in win10/???? +# +# +# 0 +# +# +# false +# +# + $unattend = @' - - - 0 - - - false - - + diff --git a/functions/private/Invoke-WinUtilTweaks.ps1 b/functions/private/Invoke-WinUtilTweaks.ps1 index e57a6e73..dfce78e6 100644 --- a/functions/private/Invoke-WinUtilTweaks.ps1 +++ b/functions/private/Invoke-WinUtilTweaks.ps1 @@ -16,6 +16,8 @@ function Invoke-WinUtilTweaks { $CheckBox, $undo = $false ) + + Write-Debug "Tweaks: $($CheckBox)" if($undo){ $Values = @{ Registry = "OriginalValue" @@ -35,21 +37,25 @@ function Invoke-WinUtilTweaks { } if($sync.configs.tweaks.$CheckBox.ScheduledTask){ $sync.configs.tweaks.$CheckBox.ScheduledTask | ForEach-Object { + Write-Debug "$($psitem.Name) and state is $($psitem.$($values.ScheduledTask))" Set-WinUtilScheduledTask -Name $psitem.Name -State $psitem.$($values.ScheduledTask) } } if($sync.configs.tweaks.$CheckBox.service){ $sync.configs.tweaks.$CheckBox.service | ForEach-Object { + Write-Debug "$($psitem.Name) and state is $($psitem.$($values.service))" Set-WinUtilService -Name $psitem.Name -StartupType $psitem.$($values.Service) } } if($sync.configs.tweaks.$CheckBox.registry){ $sync.configs.tweaks.$CheckBox.registry | ForEach-Object { + Write-Debug "$($psitem.Name) and state is $($psitem.$($values.registry))" Set-WinUtilRegistry -Name $psitem.Name -Path $psitem.Path -Type $psitem.Type -Value $psitem.$($values.registry) } } if($sync.configs.tweaks.$CheckBox.$($values.ScriptType)){ $sync.configs.tweaks.$CheckBox.$($values.ScriptType) | ForEach-Object { + Write-Debug "$($psitem) and state is $($psitem.$($values.ScriptType))" $Scriptblock = [scriptblock]::Create($psitem) Invoke-WinUtilScript -ScriptBlock $scriptblock -Name $CheckBox } @@ -58,6 +64,7 @@ function Invoke-WinUtilTweaks { if(!$undo){ if($sync.configs.tweaks.$CheckBox.appx){ $sync.configs.tweaks.$CheckBox.appx | ForEach-Object { + Write-Debug "UNDO $($psitem.Name)" Remove-WinUtilAPPX -Name $psitem } } diff --git a/functions/private/Show-CustomDialog.ps1 b/functions/private/Show-CustomDialog.ps1 new file mode 100644 index 00000000..e102c43e --- /dev/null +++ b/functions/private/Show-CustomDialog.ps1 @@ -0,0 +1,221 @@ +function Show-CustomDialog { + <# + .SYNOPSIS + Displays a custom dialog box with an image, heading, message, and an OK button. + + .DESCRIPTION + This function creates a custom dialog box with the specified message and additional elements such as an image, heading, and an OK button. The dialog box is designed with a green border, rounded corners, and a black background. + + .PARAMETER Message + The message to be displayed in the dialog box. + + .PARAMETER Width + The width of the custom dialog window. + + .PARAMETER Height + The height of the custom dialog window. + + .EXAMPLE + Show-CustomDialog -Message "This is a custom dialog with a message and an image above." -Width 300 -Height 200 + + #> + param( + [string]$Message, + [int]$Width = 300, + [int]$Height = 200 + ) + + Add-Type -AssemblyName PresentationFramework + + # Define theme colors + $foregroundColor = [Windows.Media.Brushes]::White + $backgroundColor = [Windows.Media.Brushes]::Black + $font = New-Object Windows.Media.FontFamily("Consolas") + $borderColor = [Windows.Media.Brushes]::Green + $buttonBackgroundColor = [Windows.Media.Brushes]::Black + $buttonForegroundColor = [Windows.Media.Brushes]::White + $shadowColor = [Windows.Media.ColorConverter]::ConvertFromString("#AAAAAAAA") + + # Create a custom dialog window + $dialog = New-Object Windows.Window + $dialog.Title = "About" + $dialog.Height = $Height + $dialog.Width = $Width + $dialog.Margin = New-Object Windows.Thickness(10) # Add margin to the entire dialog box + $dialog.WindowStyle = [Windows.WindowStyle]::None # Remove title bar and window controls + $dialog.ResizeMode = [Windows.ResizeMode]::NoResize # Disable resizing + $dialog.WindowStartupLocation = [Windows.WindowStartupLocation]::CenterScreen # Center the window + $dialog.Foreground = $foregroundColor + $dialog.Background = $backgroundColor + $dialog.FontFamily = $font + + # Create a Border for the green edge with rounded corners + $border = New-Object Windows.Controls.Border + $border.BorderBrush = $borderColor + $border.BorderThickness = New-Object Windows.Thickness(1) # Adjust border thickness as needed + $border.CornerRadius = New-Object Windows.CornerRadius(10) # Adjust the radius for rounded corners + + # Create a drop shadow effect + $dropShadow = New-Object Windows.Media.Effects.DropShadowEffect + $dropShadow.Color = $shadowColor + $dropShadow.Direction = 270 + $dropShadow.ShadowDepth = 5 + $dropShadow.BlurRadius = 10 + + # Apply drop shadow effect to the border + $dialog.Effect = $dropShadow + + $dialog.Content = $border + + # Create a grid for layout inside the Border + $grid = New-Object Windows.Controls.Grid + $border.Child = $grid + + # Add the following line to show gridlines + #$grid.ShowGridLines = $true + + # Add the following line to set the background color of the grid + $grid.Background = [Windows.Media.Brushes]::Transparent + # Add the following line to make the Grid stretch + $grid.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch + $grid.VerticalAlignment = [Windows.VerticalAlignment]::Stretch + + # Add the following line to make the Border stretch + $border.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch + $border.VerticalAlignment = [Windows.VerticalAlignment]::Stretch + + + # Set up Row Definitions + $row0 = New-Object Windows.Controls.RowDefinition + $row0.Height = [Windows.GridLength]::Auto + + $row1 = New-Object Windows.Controls.RowDefinition + $row1.Height = [Windows.GridLength]::new(1, [Windows.GridUnitType]::Star) + + $row2 = New-Object Windows.Controls.RowDefinition + $row2.Height = [Windows.GridLength]::Auto + + # Add Row Definitions to Grid + $grid.RowDefinitions.Add($row0) + $grid.RowDefinitions.Add($row1) + $grid.RowDefinitions.Add($row2) + + # Add StackPanel for horizontal layout with margins + $stackPanel = New-Object Windows.Controls.StackPanel + $stackPanel.Margin = New-Object Windows.Thickness(10) # Add margins around the stack panel + $stackPanel.Orientation = [Windows.Controls.Orientation]::Horizontal + $stackPanel.HorizontalAlignment = [Windows.HorizontalAlignment]::Left # Align to the left + $stackPanel.VerticalAlignment = [Windows.VerticalAlignment]::Top # Align to the top + + $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 = 25 + $viewbox.Height = 25 + + # 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 = $foregroundColor # Set fill color to white + + # Add SVG path to Viewbox + $viewbox.Child = $svgPath + + # Add SVG path to the stack panel + $stackPanel.Children.Add($viewbox) + + # Add "Winutil" text + $winutilTextBlock = New-Object Windows.Controls.TextBlock + $winutilTextBlock.Text = "Winutil" + $winutilTextBlock.FontSize = 18 # Adjust font size as needed + $winutilTextBlock.Foreground = $foregroundColor + $winutilTextBlock.Margin = New-Object Windows.Thickness(10, 5, 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 + $messageTextBlock.Text = $Message + $messageTextBlock.TextWrapping = [Windows.TextWrapping]::Wrap # Enable text wrapping + $messageTextBlock.HorizontalAlignment = [Windows.HorizontalAlignment]::Left + $messageTextBlock.VerticalAlignment = [Windows.VerticalAlignment]::Top + $messageTextBlock.Margin = New-Object Windows.Thickness(10) # Add margins around the text block + $grid.Children.Add($messageTextBlock) + [Windows.Controls.Grid]::SetRow($messageTextBlock, 1) # Set the row to the second row (0-based index) + + # Add OK button + $okButton = New-Object Windows.Controls.Button + $okButton.Content = "OK" + $okButton.Width = 80 + $okButton.Height = 30 + $okButton.HorizontalAlignment = [Windows.HorizontalAlignment]::Center + $okButton.VerticalAlignment = [Windows.VerticalAlignment]::Bottom + $okButton.Margin = New-Object Windows.Thickness(0, 0, 0, 10) + $okButton.Background = $buttonBackgroundColor + $okButton.Foreground = $buttonForegroundColor + $okButton.BorderBrush = $borderColor + $okButton.Add_Click({ + $dialog.Close() + }) + $grid.Children.Add($okButton) + [Windows.Controls.Grid]::SetRow($okButton, 2) # Set the row to the third row (0-based index) + + # Handle Escape key press to close the dialog + $dialog.Add_KeyDown({ + if ($_.Key -eq 'Escape') { + $dialog.Close() + } + }) + + # Set the OK button as the default button (activated on Enter) + $okButton.IsDefault = $true + + # Show the custom dialog + $dialog.ShowDialog() +} diff --git a/functions/private/Update-WinUtilProgramWinget.ps1 b/functions/private/Update-WinUtilProgramWinget.ps1 index 5deac59c..1fc0c2df 100644 --- a/functions/private/Update-WinUtilProgramWinget.ps1 +++ b/functions/private/Update-WinUtilProgramWinget.ps1 @@ -14,7 +14,6 @@ Function Update-WinUtilProgramWinget { Start-Transcript $ENV:TEMP\winget-update.log -Append winget upgrade --all - Pause } $global:WinGetInstall = Start-Process -Verb runas powershell -ArgumentList "-command invoke-command -scriptblock {$wingetinstall} -argumentlist '$($ProgramsToInstall -join ",")'" -PassThru diff --git a/functions/public/Invoke-WPFButton.ps1 b/functions/public/Invoke-WPFButton.ps1 index a0f1ab21..1460a6be 100644 --- a/functions/public/Invoke-WPFButton.ps1 +++ b/functions/public/Invoke-WPFButton.ps1 @@ -24,10 +24,6 @@ function Invoke-WPFButton { "WPFdesktop" {Invoke-WPFPresets "Desktop"} "WPFlaptop" {Invoke-WPFPresets "laptop"} "WPFminimal" {Invoke-WPFPresets "minimal"} - "WPFexport" {Invoke-WPFImpex -type "export" -CheckBox "WPFTweaks"} - "WPFimport" {Invoke-WPFImpex -type "import" -CheckBox "WPFTweaks"} - "WPFexportWinget" {Invoke-WPFImpex -type "export" -CheckBox "WPFInstall"} - "WPFimportWinget" {Invoke-WPFImpex -type "import" -CheckBox "WPFInstall"} "WPFclear" {Invoke-WPFPresets -preset $null -imported $true} "WPFclearWinget" {Invoke-WPFPresets -preset $null -imported $true -CheckBox "WPFInstall"} "WPFtweaksbutton" {Invoke-WPFtweaksbutton} diff --git a/functions/public/Invoke-WPFFeatureInstall.ps1 b/functions/public/Invoke-WPFFeatureInstall.ps1 index 2277b753..a8bc995a 100644 --- a/functions/public/Invoke-WPFFeatureInstall.ps1 +++ b/functions/public/Invoke-WPFFeatureInstall.ps1 @@ -7,15 +7,15 @@ function Invoke-WPFFeatureInstall { #> if($sync.ProcessRunning){ - $msg = "Install process is currently running." + $msg = "[Invoke-WPFFeatureInstall] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } - $Features = Get-WinUtilCheckBoxes -Group "WPFFeature" + $Features = (Get-WinUtilCheckBoxes)["WPFFeatures"] - Invoke-WPFRunspace -ArgumentList $Features -ScriptBlock { - param($Features) + Invoke-WPFRunspace -ArgumentList $Features,$DebugPreference -ScriptBlock { + param($Features, $DebugPreference) $sync.ProcessRunning = $true @@ -26,12 +26,5 @@ function Invoke-WPFFeatureInstall { Write-Host "--- Features are Installed ---" Write-Host "--- A Reboot may be required ---" Write-Host "===================================" - - $ButtonType = [System.Windows.MessageBoxButton]::OK - $MessageboxTitle = "All features are now installed " - $Messageboxbody = ("Done") - $MessageIcon = [System.Windows.MessageBoxImage]::Information - - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) } } \ No newline at end of file diff --git a/functions/public/Invoke-WPFGetInstalled.ps1 b/functions/public/Invoke-WPFGetInstalled.ps1 index 001cce2b..b4b33307 100644 --- a/functions/public/Invoke-WPFGetInstalled.ps1 +++ b/functions/public/Invoke-WPFGetInstalled.ps1 @@ -11,7 +11,7 @@ function Invoke-WPFGetInstalled { param($checkbox) if($sync.ProcessRunning){ - $msg = "Install process is currently running." + $msg = "[Invoke-WPFGetInstalled] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } @@ -23,8 +23,8 @@ function Invoke-WPFGetInstalled { return } - Invoke-WPFRunspace -ArgumentList $checkbox -ScriptBlock { - param($checkbox) + Invoke-WPFRunspace -ArgumentList $checkbox,$DebugPreference -ScriptBlock { + param($checkbox, $DebugPreference) $sync.ProcessRunning = $true diff --git a/functions/public/Invoke-WPFImpex.ps1 b/functions/public/Invoke-WPFImpex.ps1 index f02de2ed..f40ac515 100644 --- a/functions/public/Invoke-WPFImpex.ps1 +++ b/functions/public/Invoke-WPFImpex.ps1 @@ -16,7 +16,7 @@ function Invoke-WPFImpex { #> param( $type, - $checkbox + $Config = $null ) if ($type -eq "export"){ @@ -26,20 +26,36 @@ function Invoke-WPFImpex { $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog } - $FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop') - $FileBrowser.Filter = "JSON Files (*.json)|*.json" - $FileBrowser.ShowDialog() | Out-Null + if (-not $Config){ + $FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop') + $FileBrowser.Filter = "JSON Files (*.json)|*.json" + $FileBrowser.ShowDialog() | Out-Null - if($FileBrowser.FileName -eq ""){ - return + if($FileBrowser.FileName -eq ""){ + return + } + else{ + $Config = $FileBrowser.FileName + } } - + if ($type -eq "export"){ - $jsonFile = Get-WinUtilCheckBoxes $checkbox -unCheck $false + $jsonFile = Get-WinUtilCheckBoxes -unCheck $false $jsonFile | ConvertTo-Json | Out-File $FileBrowser.FileName -Force } if ($type -eq "import"){ - $jsonFile = Get-Content $FileBrowser.FileName | ConvertFrom-Json - Invoke-WPFPresets -preset $jsonFile -imported $true -CheckBox $checkbox + $jsonFile = Get-Content $Config | ConvertFrom-Json + + $flattenedJson = @() + $jsonFile.PSObject.Properties | ForEach-Object { + $category = $_.Name + foreach ($checkboxName in $_.Value) { + if ($category -ne "Install") { + $flattenedJson += $checkboxName + } + } + } + + Invoke-WPFPresets -preset $flattenedJson -imported $true } } diff --git a/functions/public/Invoke-WPFInstall.ps1 b/functions/public/Invoke-WPFInstall.ps1 index 89dd0b49..12362b12 100644 --- a/functions/public/Invoke-WPFInstall.ps1 +++ b/functions/public/Invoke-WPFInstall.ps1 @@ -7,12 +7,12 @@ function Invoke-WPFInstall { #> if($sync.ProcessRunning){ - $msg = "Install process is currently running." + $msg = "[Invoke-WPFInstall] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } - $WingetInstall = Get-WinUtilCheckBoxes -Group "WPFInstall" + $WingetInstall = (Get-WinUtilCheckBoxes)["Install"] if ($wingetinstall.Count -eq 0) { $WarningMsg = "Please select the program(s) to install" @@ -20,24 +20,15 @@ function Invoke-WPFInstall { return } - Invoke-WPFRunspace -ArgumentList $WingetInstall -scriptblock { - param($WingetInstall) + Invoke-WPFRunspace -ArgumentList $WingetInstall,$DebugPreference -ScriptBlock { + param($WingetInstall, $DebugPreference) + try{ $sync.ProcessRunning = $true - # Ensure winget is installed Install-WinUtilWinget - - # Install all selected programs in new window Install-WinUtilProgramWinget -ProgramsToInstall $WingetInstall - $ButtonType = [System.Windows.MessageBoxButton]::OK - $MessageboxTitle = "Installs are Finished " - $Messageboxbody = ("Done") - $MessageIcon = [System.Windows.MessageBoxImage]::Information - - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) - Write-Host "===========================================" Write-Host "-- Installs have finished ---" Write-Host "===========================================" @@ -47,6 +38,7 @@ function Invoke-WPFInstall { Write-Host "-- Winget failed to install ---" Write-Host "===========================================" } + Start-Sleep -Seconds 5 $sync.ProcessRunning = $False } } \ No newline at end of file diff --git a/functions/public/Invoke-WPFInstallUpgrade.ps1 b/functions/public/Invoke-WPFInstallUpgrade.ps1 index c2fb9df1..8cf026a7 100644 --- a/functions/public/Invoke-WPFInstallUpgrade.ps1 +++ b/functions/public/Invoke-WPFInstallUpgrade.ps1 @@ -13,7 +13,7 @@ function Invoke-WPFInstallUpgrade { } if(Get-WinUtilInstallerProcess -Process $global:WinGetInstall){ - $msg = "Install process is currently running. Please check for a powershell window labeled 'Winget Install'" + $msg = "[Invoke-WPFInstallUpgrade] Install process is currently running. Please check for a powershell window labeled 'Winget Install'" [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } diff --git a/functions/public/Invoke-WPFPresets.ps1 b/functions/public/Invoke-WPFPresets.ps1 index 4b61e40b..a513776b 100644 --- a/functions/public/Invoke-WPFPresets.ps1 +++ b/functions/public/Invoke-WPFPresets.ps1 @@ -17,8 +17,7 @@ function Invoke-WPFPresets { param( $preset, - [bool]$imported = $false, - $checkbox = "WPFTweaks" + [bool]$imported = $false ) if($imported -eq $true){ @@ -28,23 +27,33 @@ function Invoke-WPFPresets { $CheckBoxesToCheck = $sync.configs.preset.$preset } - if($checkbox -eq "WPFTweaks"){ - $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "*tweaks*"} - $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} | ForEach-Object { - if ($CheckBoxesToCheck -contains $PSItem.name){ - $sync.$($PSItem.name).ischecked = $true - } - else{$sync.$($PSItem.name).ischecked = $false} + $CheckBoxes = $sync.GetEnumerator() | Where-Object { $_.Value -is [System.Windows.Controls.CheckBox] } + Write-Debug "Getting checkboxes to set $($CheckBoxes.Count)" + + $CheckBoxesToCheck | ForEach-Object { + if ($_ -ne $null) { + Write-Debug $_ } } - if($checkbox -eq "WPFInstall"){ + + foreach ($CheckBox in $CheckBoxes) { + $checkboxName = $CheckBox.Key - $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPFInstall*"} - $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} | ForEach-Object { - if($($sync.configs.applications.$($psitem.name).winget) -in $CheckBoxesToCheck){ - $sync.$($PSItem.name).ischecked = $true - } - else{$sync.$($PSItem.name).ischecked = $false} + if (-not $CheckBoxesToCheck) + { + $sync.$checkboxName.IsChecked = $false + continue + } + + # Check if the checkbox name exists in the flattened JSON hashtable + if ($CheckBoxesToCheck.Contains($checkboxName)) { + # If it exists, set IsChecked to true + $sync.$checkboxName.IsChecked = $true + Write-Debug "$checkboxName is checked" + } else { + # If it doesn't exist, set IsChecked to false + $sync.$checkboxName.IsChecked = $false + Write-Debug "$checkboxName is not checked" } } } \ No newline at end of file diff --git a/functions/public/Invoke-WPFRunspace.ps1 b/functions/public/Invoke-WPFRunspace.ps1 index 975f44a7..cb624ef3 100644 --- a/functions/public/Invoke-WPFRunspace.ps1 +++ b/functions/public/Invoke-WPFRunspace.ps1 @@ -21,7 +21,8 @@ function Invoke-WPFRunspace { [CmdletBinding()] Param ( $ScriptBlock, - $ArgumentList + $ArgumentList, + $DebugPreference ) # Create a PowerShell instance @@ -30,6 +31,7 @@ function Invoke-WPFRunspace { # Add Scriptblock and Arguments to runspace $script:powershell.AddScript($ScriptBlock) $script:powershell.AddArgument($ArgumentList) + $script:powershell.AddArgument($DebugPreference) # Pass DebugPreference to the script block $script:powershell.RunspacePool = $sync.runspace # Execute the RunspacePool diff --git a/functions/public/Invoke-WPFShortcut.ps1 b/functions/public/Invoke-WPFShortcut.ps1 index 80aacf8b..0f819086 100644 --- a/functions/public/Invoke-WPFShortcut.ps1 +++ b/functions/public/Invoke-WPFShortcut.ps1 @@ -13,19 +13,19 @@ function Invoke-WPFShortcut { $iconPath = $null Switch ($ShortcutToAdd) { - "WinUtil" { - $SourceExe = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" - $IRM = 'irm https://christitus.com/win | iex' - $Powershell = '-ExecutionPolicy Bypass -Command "Start-Process powershell.exe -verb runas -ArgumentList' - $ArgumentsToSourceExe = "$powershell '$IRM'" - $DestinationName = "WinUtil.lnk" + "WinUtil" { + $SourceExe = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" + $IRM = 'irm https://christitus.com/win | iex' + $Powershell = '-ExecutionPolicy Bypass -Command "Start-Process powershell.exe -verb runas -ArgumentList' + $ArgumentsToSourceExe = "$powershell '$IRM'" + $DestinationName = "WinUtil.lnk" - if (Test-Path -Path "$env:TEMP\cttlogo.png") { - $iconPath = "$env:SystempRoot\cttlogo.ico" - ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath $iconPath + if (Test-Path -Path "$env:TEMP\cttlogo.png") { + $iconPath = "$env:SystempRoot\cttlogo.ico" + ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath $iconPath + } } } - } $FileBrowser = New-Object System.Windows.Forms.SaveFileDialog $FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop') diff --git a/functions/public/Invoke-WPFUnInstall.ps1 b/functions/public/Invoke-WPFUnInstall.ps1 index 81cfc57c..af69a964 100644 --- a/functions/public/Invoke-WPFUnInstall.ps1 +++ b/functions/public/Invoke-WPFUnInstall.ps1 @@ -7,12 +7,12 @@ function Invoke-WPFUnInstall { #> if($sync.ProcessRunning){ - $msg = "Install process is currently running" + $msg = "[Invoke-WPFUnInstall] Install process is currently running" [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } - $WingetInstall = Get-WinUtilCheckBoxes -Group "WPFInstall" + $WingetInstall = (Get-WinUtilCheckBoxes)["Install"] if ($wingetinstall.Count -eq 0) { $WarningMsg = "Please select the program(s) to install" @@ -29,8 +29,9 @@ function Invoke-WPFUnInstall { if($confirm -eq "No"){return} - Invoke-WPFRunspace -ArgumentList $WingetInstall -scriptblock { - param($WingetInstall) + Invoke-WPFRunspace -ArgumentList $WingetInstall,$DebugPreference -ScriptBlock { + param($WingetInstall, $DebugPreference) + try{ $sync.ProcessRunning = $true diff --git a/functions/public/Invoke-WPFtweaksbutton.ps1 b/functions/public/Invoke-WPFtweaksbutton.ps1 index 90d7b00d..47012b66 100644 --- a/functions/public/Invoke-WPFtweaksbutton.ps1 +++ b/functions/public/Invoke-WPFtweaksbutton.ps1 @@ -7,13 +7,13 @@ function Invoke-WPFtweaksbutton { #> if($sync.ProcessRunning){ - $msg = "Install process is currently running." + $msg = "[Invoke-WPFtweaksbutton] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } - $Tweaks = Get-WinUtilCheckBoxes -Group "WPFTweaks" - + $Tweaks = (Get-WinUtilCheckBoxes)["WPFTweaks"] + Set-WinUtilDNS -DNSProvider $sync["WPFchangedns"].text if ($tweaks.count -eq 0 -and $sync["WPFchangedns"].text -eq "Default"){ @@ -22,21 +22,20 @@ function Invoke-WPFtweaksbutton { return } - Invoke-WPFRunspace -ArgumentList $Tweaks -ScriptBlock { - param($Tweaks) + Write-Debug "Number of tweaks to process: $($Tweaks.Count)" + + Invoke-WPFRunspace -ArgumentList $Tweaks -DebugPreference $DebugPreference -ScriptBlock { + param($Tweaks, $DebugPreference) + Write-Debug "Inside Number of tweaks to process: $($Tweaks.Count)" $sync.ProcessRunning = $true - # Executes first if selected - if ("WPFEssTweaksRestorePoint" -in $Tweaks) { - Invoke-WinUtilTweaks "WPFEssTweaksRestorePoint" - } - + $cnt = 0 # Execute other selected tweaks - foreach ($tweak in $tweaks) { - if ($tweak -ne "WPFEssTweaksRestorePoint") { - Invoke-WinUtilTweaks $tweak - } + foreach ($tweak in $Tweaks) { + Write-Debug "This is a tweak to run $tweak count: $cnt" + Invoke-WinUtilTweaks $tweak + $cnt += 1 } $sync.ProcessRunning = $false @@ -44,11 +43,10 @@ function Invoke-WPFtweaksbutton { Write-Host "-- Tweaks are Finished ---" Write-Host "=================================" - $ButtonType = [System.Windows.MessageBoxButton]::OK - $MessageboxTitle = "Tweaks are Finished " - $Messageboxbody = ("Done") - $MessageIcon = [System.Windows.MessageBoxImage]::Information - - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) + # $ButtonType = [System.Windows.MessageBoxButton]::OK + # $MessageboxTitle = "Tweaks are Finished " + # $Messageboxbody = ("Done") + # $MessageIcon = [System.Windows.MessageBoxImage]::Information + # [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) } } \ No newline at end of file diff --git a/functions/public/Invoke-WPFundoall.ps1 b/functions/public/Invoke-WPFundoall.ps1 index 76eff6cc..8f2a6590 100644 --- a/functions/public/Invoke-WPFundoall.ps1 +++ b/functions/public/Invoke-WPFundoall.ps1 @@ -7,12 +7,12 @@ function Invoke-WPFundoall { #> if($sync.ProcessRunning){ - $msg = "Install process is currently running." + $msg = "[Invoke-WPFundoall] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } - $Tweaks = Get-WinUtilCheckBoxes -Group "WPFTweaks" + $Tweaks = (Get-WinUtilCheckBoxes)["WPFTweaks"] if ($tweaks.count -eq 0){ $msg = "Please check the tweaks you wish to undo." @@ -20,8 +20,8 @@ function Invoke-WPFundoall { return } - Invoke-WPFRunspace -ArgumentList $Tweaks -ScriptBlock { - param($Tweaks) + Invoke-WPFRunspace -ArgumentList $Tweaks,$DebugPreference -ScriptBlock { + param($Tweaks, $DebugPreference) $sync.ProcessRunning = $true diff --git a/scripts/main.ps1 b/scripts/main.ps1 index 5a91b2df..85bf37b8 100644 --- a/scripts/main.ps1 +++ b/scripts/main.ps1 @@ -1,5 +1,4 @@ # SPDX-License-Identifier: MIT - # Set the maximum number of threads for the RunspacePool to the number of threads on the machine $maxthreads = [int]$env:NUMBER_OF_PROCESSORS @@ -129,8 +128,6 @@ catch { Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed." } - - #=========================================================================== # Store Form Objects In PowerShell #=========================================================================== @@ -168,7 +165,7 @@ $sync.keys | ForEach-Object { $sync["$psitem"].Add_MouseUp({ [System.Object]$Sender = $args[0] Start-Process $Sender.ToolTip -ErrorAction Stop - Write-Host "Let's go: $($Sender.ToolTip)" + Write-Debug "Opening: $($Sender.ToolTip)" }) } @@ -206,7 +203,6 @@ $sync["Form"].Add_Closing({ [System.GC]::Collect() }) - # Attach the event handler to the Click event $sync.CheckboxFilterClear.Add_Click({ $sync.CheckboxFilter.Text = "" @@ -264,8 +260,10 @@ $commonKeyEvents = { $sync["Form"].Add_PreViewKeyDown($commonKeyEvents) -# adding some left mouse window move on drag capability $sync["Form"].Add_MouseLeftButtonDown({ + if ($sync["SettingsPopup"].IsOpen) { + $sync["SettingsPopup"].IsOpen = $false + } $sync["Form"].DragMove() }) @@ -280,31 +278,36 @@ $sync["Form"].Add_MouseDoubleClick({ } }) -$sync["Form"].Add_ContentRendered({ - - foreach ($proc in (Get-Process | Where-Object { $_.MainWindowTitle -and $_.MainWindowTitle -like "*tit*" })) { - if ($proc.Id -ne [System.IntPtr]::Zero) { - Write-Debug "MainWindowHandle: $($proc.Id) $($proc.MainWindowTitle) $($proc.MainWindowHandle)" - $windowHandle = $proc.MainWindowHandle - } +$sync["Form"].Add_Deactivated({ + Write-Debug "WinUtil lost focus" + if ($sync["SettingsPopup"].IsOpen) { + $sync["SettingsPopup"].IsOpen = $false } +}) + +$sync["Form"].Add_ContentRendered({ try { [void][Window] } catch { - Add-Type @" +Add-Type @" using System; using System.Runtime.InteropServices; public class Window { + [DllImport("user32.dll")] + public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); + [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); + [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw); + [DllImport("user32.dll")] public static extern int GetSystemMetrics(int nIndex); - } + }; public struct RECT { public int Left; // x position of upper-left corner public int Top; // y position of upper-left corner @@ -314,8 +317,29 @@ $sync["Form"].Add_ContentRendered({ "@ } + foreach ($proc in (Get-Process | Where-Object { $_.MainWindowTitle -and $_.MainWindowTitle -like "*titus*" })) { + if ($proc.Id -ne [System.IntPtr]::Zero) { + Write-Debug "MainWindowHandle: $($proc.Id) $($proc.MainWindowTitle) $($proc.MainWindowHandle)" + $windowHandle = $proc.MainWindowHandle + } + } + + # need to experiemnt more + # setting icon for the windows is still not working + # $pngUrl = "https://christitus.com/images/logo-full.png" + # $pngPath = "$env:TEMP\cttlogo.png" + # $iconPath = "$env:TEMP\cttlogo.ico" + # # Download the PNG file + # Invoke-WebRequest -Uri $pngUrl -OutFile $pngPath + # if (Test-Path -Path $pngPath) { + # ConvertTo-Icon -bitmapPath $pngPath -iconPath $iconPath + # } + # $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($iconPath) + # Write-Host $icon.Handle + # [Window]::SendMessage($windowHandle, 0x80, [IntPtr]::Zero, $icon.Handle) + $rect = New-Object RECT - [void][Window]::GetWindowRect($windowHandle, [ref]$rect) + [Window]::GetWindowRect($windowHandle, [ref]$rect) $width = $rect.Right - $rect.Left $height = $rect.Bottom - $rect.Top @@ -347,6 +371,42 @@ $sync["Form"].Add_ContentRendered({ Invoke-WPFTab "WPFTab1BT" $sync["Form"].Focus() + + # maybe this is not the best place to load and execute config file? + # maybe community can help? + if ($PARAM_CONFIG){ + Invoke-WPFImpex -type "import" -Config $PARAM_CONFIG + if ($PARAM_RUN){ + while ($sync.ProcessRunning) { + Start-Sleep -Seconds 5 + } + Start-Sleep -Seconds 5 + + Write-Host "Applying tweaks..." + Invoke-WPFtweaksbutton + while ($sync.ProcessRunning) { + Start-Sleep -Seconds 5 + } + Start-Sleep -Seconds 5 + + Write-Host "Installing features..." + Invoke-WPFFeatureInstall + while ($sync.ProcessRunning) { + Start-Sleep -Seconds 5 + } + + Start-Sleep -Seconds 5 + Write-Host "Installing applications..." + while ($sync.ProcessRunning) { + Start-Sleep -Seconds 1 + } + Invoke-WPFInstall + Start-Sleep -Seconds 5 + + Write-Host "Done." + } + } + }) $sync["CheckboxFilter"].Add_TextChanged({ @@ -392,5 +452,50 @@ $sync["CheckboxFilter"].Add_TextChanged({ }) +# Define event handler for button click +$sync["SettingsButton"].Add_Click({ + Write-Debug "SettingsButton clicked" + if ($sync["SettingsPopup"].IsOpen) { + $sync["SettingsPopup"].IsOpen = $false + } + else { + $sync["SettingsPopup"].IsOpen = $true + } + $_.Handled = $false +}) + +# Define event handlers for menu items +$sync["ImportMenuItem"].Add_Click({ + # Handle Import menu item click + Write-Debug "Import clicked" + $sync["SettingsPopup"].IsOpen = $false + Invoke-WPFImpex -type "import" + $_.Handled = $false +}) + +$sync["ExportMenuItem"].Add_Click({ + # Handle Export menu item click + Write-Debug "Export clicked" + $sync["SettingsPopup"].IsOpen = $false + Invoke-WPFImpex -type "export" + $_.Handled = $false +}) + +$sync["AboutMenuItem"].Add_Click({ + # Handle Export menu item click + Write-Debug "About clicked" + $sync["SettingsPopup"].IsOpen = $false + # Example usage + $authorInfo = @" +Author : @christitustech +Runspace : @DeveloperDurp +GUI : @KonTy +MicroWin : @KonTy +GitHub : https://github.com/ChrisTitusTech/winutil +Version : $($sync.version) +"@ + Show-CustomDialog -Message $authorInfo -Width 400 +}) + $sync["Form"].ShowDialog() | out-null Stop-Transcript \ No newline at end of file diff --git a/scripts/start.ps1 b/scripts/start.ps1 index 948591ed..5f216172 100644 --- a/scripts/start.ps1 +++ b/scripts/start.ps1 @@ -5,6 +5,27 @@ GitHub : https://github.com/ChrisTitusTech Version : #{replaceme} #> +param ( + [switch]$Debug, + [string]$Config, + [switch]$Run +) + +# Set DebugPreference based on the -Debug switch +if ($Debug) { + $DebugPreference = "Continue" +} + +if ($Config) { + $PARAM_CONFIG = $Config +} + +$PARAM_RUN = $false +# Handle the -Run switch +if ($Run) { + Write-Host "Running config file tasks..." + $PARAM_RUN = $true +} if (!(Test-Path -Path $ENV:TEMP)) { New-Item -ItemType Directory -Force -Path $ENV:TEMP @@ -27,6 +48,7 @@ $currentPid = [System.Security.Principal.WindowsIdentity]::GetCurrent() $principal = new-object System.Security.Principal.WindowsPrincipal($currentPid) $adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator + if ($principal.IsInRole($adminRole)) { $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Admin)" diff --git a/winutil.ps1 b/winutil.ps1 index d961feed..f29d2d26 100644 --- a/winutil.ps1 +++ b/winutil.ps1 @@ -10,8 +10,29 @@ Author : Chris Titus @christitustech Runspace Author: @DeveloperDurp GitHub : https://github.com/ChrisTitusTech - Version : 24.01.12 + Version : 24.01.15 #> +param ( + [switch]$Debug, + [string]$Config, + [switch]$Run +) + +# Set DebugPreference based on the -Debug switch +if ($Debug) { + $DebugPreference = "Continue" +} + +if ($Config) { + $PARAM_CONFIG = $Config +} + +$PARAM_RUN = $false +# Handle the -Run switch +if ($Run) { + Write-Host "Running config file tasks..." + $PARAM_RUN = $true +} if (!(Test-Path -Path $ENV:TEMP)) { New-Item -ItemType Directory -Force -Path $ENV:TEMP @@ -26,7 +47,7 @@ Add-Type -AssemblyName System.Windows.Forms # Variable to sync between runspaces $sync = [Hashtable]::Synchronized(@{}) $sync.PSScriptRoot = $PSScriptRoot -$sync.version = "24.01.12" +$sync.version = "24.01.15" $sync.configs = @{} $sync.ProcessRunning = $false @@ -34,6 +55,7 @@ $currentPid = [System.Security.Principal.WindowsIdentity]::GetCurrent() $principal = new-object System.Security.Principal.WindowsPrincipal($currentPid) $adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator + if ($principal.IsInRole($adminRole)) { $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Admin)" @@ -258,58 +280,60 @@ Function Get-WinUtilCheckBoxes { #> Param( - $Group, - [boolean]$unCheck = $true + [boolean]$unCheck = $false ) - - $Output = New-Object System.Collections.Generic.List[System.Object] - - if($Group -eq "WPFInstall"){ - $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPFInstall*"} - $CheckBoxes = $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} - Foreach ($CheckBox in $CheckBoxes){ - if($CheckBox.value.ischecked -eq $true){ - $sync.configs.applications.$($CheckBox.Name).winget -split ";" | ForEach-Object { - $Output.Add($psitem) - } - if ($uncheck -eq $true){ - $CheckBox.value.ischecked = $false - } - - } - } + $Output = @{ + Install = @() + WPFTweaks = @() + WPFFeature = @() + WPFInstall = @() } - if($Group -eq "WPFTweaks"){ - $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPF*Tweaks*"} - $CheckBoxes = $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} - Foreach ($CheckBox in $CheckBoxes){ - if($CheckBox.value.ischecked -eq $true){ - $Output.Add($Checkbox.Name) + $CheckBoxes = $sync.GetEnumerator() | Where-Object { $_.Value -is [System.Windows.Controls.CheckBox] } - if ($uncheck -eq $true){ - $CheckBox.value.ischecked = $false + foreach ($CheckBox in $CheckBoxes) { + $group = if ($CheckBox.Key.StartsWith("WPFInstall")) { "Install" } + elseif ($CheckBox.Key.StartsWith("WPFTweaks")) { "WPFTweaks" } + elseif ($CheckBox.Key.StartsWith("WPFFeature")) { "WPFFeature" } + + if ($group) { + if ($CheckBox.Value.IsChecked -eq $true) { + $feature = switch ($group) { + "Install" { + # Get the winget value + $wingetValue = $sync.configs.applications.$($CheckBox.Name).winget + + if (-not [string]::IsNullOrWhiteSpace($wingetValue) -and $wingetValue -ne "na") { + $wingetValue -split ";" + } else { + $sync.configs.applications.$($CheckBox.Name).choco + } + } + default { + $CheckBox.Name + } + } + + if (-not $Output.ContainsKey($group)) { + $Output[$group] = @() + } + if ($group -eq "Install") { + $Output["WPFInstall"] += $CheckBox.Name + Write-Debug "Adding: $($CheckBox.Name) under: WPFInstall" + } + + Write-Debug "Adding: $($feature) under: $($group)" + $Output[$group] += $feature + + if ($uncheck -eq $true) { + $CheckBox.Value.IsChecked = $false } } } } - if($Group -eq "WPFFeature"){ - $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPF*Feature*"} - $CheckBoxes = $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} - Foreach ($CheckBox in $CheckBoxes){ - if($CheckBox.value.ischecked -eq $true){ - $Output.Add($Checkbox.Name) - - if ($uncheck -eq $true){ - $CheckBox.value.ischecked = $false - } - } - } - } - - Write-Output $($Output | Select-Object -Unique) + return $Output } function Get-WinUtilInstallerProcess { <# @@ -874,19 +898,22 @@ function New-Unattend { # net user administrator /active:yes # + # this section doesn't work in win10/???? +# +# +# 0 +# +# +# false +# +# + $unattend = @' - - - 0 - - - false - - + @@ -1590,6 +1617,8 @@ function Invoke-WinUtilTweaks { $CheckBox, $undo = $false ) + + Write-Debug "Tweaks: $($CheckBox)" if($undo){ $Values = @{ Registry = "OriginalValue" @@ -1609,21 +1638,25 @@ function Invoke-WinUtilTweaks { } if($sync.configs.tweaks.$CheckBox.ScheduledTask){ $sync.configs.tweaks.$CheckBox.ScheduledTask | ForEach-Object { + Write-Debug "$($psitem.Name) and state is $($psitem.$($values.ScheduledTask))" Set-WinUtilScheduledTask -Name $psitem.Name -State $psitem.$($values.ScheduledTask) } } if($sync.configs.tweaks.$CheckBox.service){ $sync.configs.tweaks.$CheckBox.service | ForEach-Object { + Write-Debug "$($psitem.Name) and state is $($psitem.$($values.service))" Set-WinUtilService -Name $psitem.Name -StartupType $psitem.$($values.Service) } } if($sync.configs.tweaks.$CheckBox.registry){ $sync.configs.tweaks.$CheckBox.registry | ForEach-Object { + Write-Debug "$($psitem.Name) and state is $($psitem.$($values.registry))" Set-WinUtilRegistry -Name $psitem.Name -Path $psitem.Path -Type $psitem.Type -Value $psitem.$($values.registry) } } if($sync.configs.tweaks.$CheckBox.$($values.ScriptType)){ $sync.configs.tweaks.$CheckBox.$($values.ScriptType) | ForEach-Object { + Write-Debug "$($psitem) and state is $($psitem.$($values.ScriptType))" $Scriptblock = [scriptblock]::Create($psitem) Invoke-WinUtilScript -ScriptBlock $scriptblock -Name $CheckBox } @@ -1632,6 +1665,7 @@ function Invoke-WinUtilTweaks { if(!$undo){ if($sync.configs.tweaks.$CheckBox.appx){ $sync.configs.tweaks.$CheckBox.appx | ForEach-Object { + Write-Debug "UNDO $($psitem.Name)" Remove-WinUtilAPPX -Name $psitem } } @@ -1926,6 +1960,227 @@ function Set-WinUtilUITheme { return $inputXML; } +function Show-CustomDialog { + <# + .SYNOPSIS + Displays a custom dialog box with an image, heading, message, and an OK button. + + .DESCRIPTION + This function creates a custom dialog box with the specified message and additional elements such as an image, heading, and an OK button. The dialog box is designed with a green border, rounded corners, and a black background. + + .PARAMETER Message + The message to be displayed in the dialog box. + + .PARAMETER Width + The width of the custom dialog window. + + .PARAMETER Height + The height of the custom dialog window. + + .EXAMPLE + Show-CustomDialog -Message "This is a custom dialog with a message and an image above." -Width 300 -Height 200 + + #> + param( + [string]$Message, + [int]$Width = 300, + [int]$Height = 200 + ) + + Add-Type -AssemblyName PresentationFramework + + # Define theme colors + $foregroundColor = [Windows.Media.Brushes]::White + $backgroundColor = [Windows.Media.Brushes]::Black + $font = New-Object Windows.Media.FontFamily("Consolas") + $borderColor = [Windows.Media.Brushes]::Green + $buttonBackgroundColor = [Windows.Media.Brushes]::Black + $buttonForegroundColor = [Windows.Media.Brushes]::White + $shadowColor = [Windows.Media.ColorConverter]::ConvertFromString("#AAAAAAAA") + + # Create a custom dialog window + $dialog = New-Object Windows.Window + $dialog.Title = "About" + $dialog.Height = $Height + $dialog.Width = $Width + $dialog.Margin = New-Object Windows.Thickness(10) # Add margin to the entire dialog box + $dialog.WindowStyle = [Windows.WindowStyle]::None # Remove title bar and window controls + $dialog.ResizeMode = [Windows.ResizeMode]::NoResize # Disable resizing + $dialog.WindowStartupLocation = [Windows.WindowStartupLocation]::CenterScreen # Center the window + $dialog.Foreground = $foregroundColor + $dialog.Background = $backgroundColor + $dialog.FontFamily = $font + + # Create a Border for the green edge with rounded corners + $border = New-Object Windows.Controls.Border + $border.BorderBrush = $borderColor + $border.BorderThickness = New-Object Windows.Thickness(1) # Adjust border thickness as needed + $border.CornerRadius = New-Object Windows.CornerRadius(10) # Adjust the radius for rounded corners + + # Create a drop shadow effect + $dropShadow = New-Object Windows.Media.Effects.DropShadowEffect + $dropShadow.Color = $shadowColor + $dropShadow.Direction = 270 + $dropShadow.ShadowDepth = 5 + $dropShadow.BlurRadius = 10 + + # Apply drop shadow effect to the border + $dialog.Effect = $dropShadow + + $dialog.Content = $border + + # Create a grid for layout inside the Border + $grid = New-Object Windows.Controls.Grid + $border.Child = $grid + + # Add the following line to show gridlines + #$grid.ShowGridLines = $true + + # Add the following line to set the background color of the grid + $grid.Background = [Windows.Media.Brushes]::Transparent + # Add the following line to make the Grid stretch + $grid.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch + $grid.VerticalAlignment = [Windows.VerticalAlignment]::Stretch + + # Add the following line to make the Border stretch + $border.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch + $border.VerticalAlignment = [Windows.VerticalAlignment]::Stretch + + + # Set up Row Definitions + $row0 = New-Object Windows.Controls.RowDefinition + $row0.Height = [Windows.GridLength]::Auto + + $row1 = New-Object Windows.Controls.RowDefinition + $row1.Height = [Windows.GridLength]::new(1, [Windows.GridUnitType]::Star) + + $row2 = New-Object Windows.Controls.RowDefinition + $row2.Height = [Windows.GridLength]::Auto + + # Add Row Definitions to Grid + $grid.RowDefinitions.Add($row0) + $grid.RowDefinitions.Add($row1) + $grid.RowDefinitions.Add($row2) + + # Add StackPanel for horizontal layout with margins + $stackPanel = New-Object Windows.Controls.StackPanel + $stackPanel.Margin = New-Object Windows.Thickness(10) # Add margins around the stack panel + $stackPanel.Orientation = [Windows.Controls.Orientation]::Horizontal + $stackPanel.HorizontalAlignment = [Windows.HorizontalAlignment]::Left # Align to the left + $stackPanel.VerticalAlignment = [Windows.VerticalAlignment]::Top # Align to the top + + $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 = 25 + $viewbox.Height = 25 + + # 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 = $foregroundColor # Set fill color to white + + # Add SVG path to Viewbox + $viewbox.Child = $svgPath + + # Add SVG path to the stack panel + $stackPanel.Children.Add($viewbox) + + # Add "Winutil" text + $winutilTextBlock = New-Object Windows.Controls.TextBlock + $winutilTextBlock.Text = "Winutil" + $winutilTextBlock.FontSize = 18 # Adjust font size as needed + $winutilTextBlock.Foreground = $foregroundColor + $winutilTextBlock.Margin = New-Object Windows.Thickness(10, 5, 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 + $messageTextBlock.Text = $Message + $messageTextBlock.TextWrapping = [Windows.TextWrapping]::Wrap # Enable text wrapping + $messageTextBlock.HorizontalAlignment = [Windows.HorizontalAlignment]::Left + $messageTextBlock.VerticalAlignment = [Windows.VerticalAlignment]::Top + $messageTextBlock.Margin = New-Object Windows.Thickness(10) # Add margins around the text block + $grid.Children.Add($messageTextBlock) + [Windows.Controls.Grid]::SetRow($messageTextBlock, 1) # Set the row to the second row (0-based index) + + # Add OK button + $okButton = New-Object Windows.Controls.Button + $okButton.Content = "OK" + $okButton.Width = 80 + $okButton.Height = 30 + $okButton.HorizontalAlignment = [Windows.HorizontalAlignment]::Center + $okButton.VerticalAlignment = [Windows.VerticalAlignment]::Bottom + $okButton.Margin = New-Object Windows.Thickness(0, 0, 0, 10) + $okButton.Background = $buttonBackgroundColor + $okButton.Foreground = $buttonForegroundColor + $okButton.BorderBrush = $borderColor + $okButton.Add_Click({ + $dialog.Close() + }) + $grid.Children.Add($okButton) + [Windows.Controls.Grid]::SetRow($okButton, 2) # Set the row to the third row (0-based index) + + # Handle Escape key press to close the dialog + $dialog.Add_KeyDown({ + if ($_.Key -eq 'Escape') { + $dialog.Close() + } + }) + + # Set the OK button as the default button (activated on Enter) + $okButton.IsDefault = $true + + # Show the custom dialog + $dialog.ShowDialog() +} function Test-WinUtilPackageManager { <# @@ -1975,7 +2230,6 @@ Function Update-WinUtilProgramWinget { Start-Transcript $ENV:TEMP\winget-update.log -Append winget upgrade --all - Pause } $global:WinGetInstall = Start-Process -Verb runas powershell -ArgumentList "-command invoke-command -scriptblock {$wingetinstall} -argumentlist '$($ProgramsToInstall -join ",")'" -PassThru @@ -2007,10 +2261,6 @@ function Invoke-WPFButton { "WPFdesktop" {Invoke-WPFPresets "Desktop"} "WPFlaptop" {Invoke-WPFPresets "laptop"} "WPFminimal" {Invoke-WPFPresets "minimal"} - "WPFexport" {Invoke-WPFImpex -type "export" -CheckBox "WPFTweaks"} - "WPFimport" {Invoke-WPFImpex -type "import" -CheckBox "WPFTweaks"} - "WPFexportWinget" {Invoke-WPFImpex -type "export" -CheckBox "WPFInstall"} - "WPFimportWinget" {Invoke-WPFImpex -type "import" -CheckBox "WPFInstall"} "WPFclear" {Invoke-WPFPresets -preset $null -imported $true} "WPFclearWinget" {Invoke-WPFPresets -preset $null -imported $true -CheckBox "WPFInstall"} "WPFtweaksbutton" {Invoke-WPFtweaksbutton} @@ -2084,15 +2334,15 @@ function Invoke-WPFFeatureInstall { #> if($sync.ProcessRunning){ - $msg = "Install process is currently running." + $msg = "[Invoke-WPFFeatureInstall] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } - $Features = Get-WinUtilCheckBoxes -Group "WPFFeature" + $Features = (Get-WinUtilCheckBoxes)["WPFFeatures"] - Invoke-WPFRunspace -ArgumentList $Features -ScriptBlock { - param($Features) + Invoke-WPFRunspace -ArgumentList $Features,$DebugPreference -ScriptBlock { + param($Features, $DebugPreference) $sync.ProcessRunning = $true @@ -2103,13 +2353,6 @@ function Invoke-WPFFeatureInstall { Write-Host "--- Features are Installed ---" Write-Host "--- A Reboot may be required ---" Write-Host "===================================" - - $ButtonType = [System.Windows.MessageBoxButton]::OK - $MessageboxTitle = "All features are now installed " - $Messageboxbody = ("Done") - $MessageIcon = [System.Windows.MessageBoxImage]::Information - - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) } } function Invoke-WPFFixesNetwork { @@ -2292,7 +2535,7 @@ function Invoke-WPFGetInstalled { param($checkbox) if($sync.ProcessRunning){ - $msg = "Install process is currently running." + $msg = "[Invoke-WPFGetInstalled] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } @@ -2304,8 +2547,8 @@ function Invoke-WPFGetInstalled { return } - Invoke-WPFRunspace -ArgumentList $checkbox -ScriptBlock { - param($checkbox) + Invoke-WPFRunspace -ArgumentList $checkbox,$DebugPreference -ScriptBlock { + param($checkbox, $DebugPreference) $sync.ProcessRunning = $true @@ -2506,7 +2749,7 @@ function Invoke-WPFImpex { #> param( $type, - $checkbox + $Config = $null ) if ($type -eq "export"){ @@ -2516,21 +2759,37 @@ function Invoke-WPFImpex { $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog } - $FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop') - $FileBrowser.Filter = "JSON Files (*.json)|*.json" - $FileBrowser.ShowDialog() | Out-Null + if (-not $Config){ + $FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop') + $FileBrowser.Filter = "JSON Files (*.json)|*.json" + $FileBrowser.ShowDialog() | Out-Null - if($FileBrowser.FileName -eq ""){ - return + if($FileBrowser.FileName -eq ""){ + return + } + else{ + $Config = $FileBrowser.FileName + } } - + if ($type -eq "export"){ - $jsonFile = Get-WinUtilCheckBoxes $checkbox -unCheck $false + $jsonFile = Get-WinUtilCheckBoxes -unCheck $false $jsonFile | ConvertTo-Json | Out-File $FileBrowser.FileName -Force } if ($type -eq "import"){ - $jsonFile = Get-Content $FileBrowser.FileName | ConvertFrom-Json - Invoke-WPFPresets -preset $jsonFile -imported $true -CheckBox $checkbox + $jsonFile = Get-Content $Config | ConvertFrom-Json + + $flattenedJson = @() + $jsonFile.PSObject.Properties | ForEach-Object { + $category = $_.Name + foreach ($checkboxName in $_.Value) { + if ($category -ne "Install") { + $flattenedJson += $checkboxName + } + } + } + + Invoke-WPFPresets -preset $flattenedJson -imported $true } } function Invoke-WPFInstall { @@ -2542,12 +2801,12 @@ function Invoke-WPFInstall { #> if($sync.ProcessRunning){ - $msg = "Install process is currently running." + $msg = "[Invoke-WPFInstall] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } - $WingetInstall = Get-WinUtilCheckBoxes -Group "WPFInstall" + $WingetInstall = (Get-WinUtilCheckBoxes)["Install"] if ($wingetinstall.Count -eq 0) { $WarningMsg = "Please select the program(s) to install" @@ -2555,24 +2814,15 @@ function Invoke-WPFInstall { return } - Invoke-WPFRunspace -ArgumentList $WingetInstall -scriptblock { - param($WingetInstall) + Invoke-WPFRunspace -ArgumentList $WingetInstall,$DebugPreference -ScriptBlock { + param($WingetInstall, $DebugPreference) + try{ $sync.ProcessRunning = $true - # Ensure winget is installed Install-WinUtilWinget - - # Install all selected programs in new window Install-WinUtilProgramWinget -ProgramsToInstall $WingetInstall - $ButtonType = [System.Windows.MessageBoxButton]::OK - $MessageboxTitle = "Installs are Finished " - $Messageboxbody = ("Done") - $MessageIcon = [System.Windows.MessageBoxImage]::Information - - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) - Write-Host "===========================================" Write-Host "-- Installs have finished ---" Write-Host "===========================================" @@ -2582,6 +2832,7 @@ function Invoke-WPFInstall { Write-Host "-- Winget failed to install ---" Write-Host "===========================================" } + Start-Sleep -Seconds 5 $sync.ProcessRunning = $False } } @@ -2600,7 +2851,7 @@ function Invoke-WPFInstallUpgrade { } if(Get-WinUtilInstallerProcess -Process $global:WinGetInstall){ - $msg = "Install process is currently running. Please check for a powershell window labeled 'Winget Install'" + $msg = "[Invoke-WPFInstallUpgrade] Install process is currently running. Please check for a powershell window labeled 'Winget Install'" [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } @@ -3069,8 +3320,7 @@ function Invoke-WPFPresets { param( $preset, - [bool]$imported = $false, - $checkbox = "WPFTweaks" + [bool]$imported = $false ) if($imported -eq $true){ @@ -3080,23 +3330,33 @@ function Invoke-WPFPresets { $CheckBoxesToCheck = $sync.configs.preset.$preset } - if($checkbox -eq "WPFTweaks"){ - $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "*tweaks*"} - $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} | ForEach-Object { - if ($CheckBoxesToCheck -contains $PSItem.name){ - $sync.$($PSItem.name).ischecked = $true - } - else{$sync.$($PSItem.name).ischecked = $false} + $CheckBoxes = $sync.GetEnumerator() | Where-Object { $_.Value -is [System.Windows.Controls.CheckBox] } + Write-Debug "Getting checkboxes to set $($CheckBoxes.Count)" + + $CheckBoxesToCheck | ForEach-Object { + if ($_ -ne $null) { + Write-Debug $_ } } - if($checkbox -eq "WPFInstall"){ + + foreach ($CheckBox in $CheckBoxes) { + $checkboxName = $CheckBox.Key - $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPFInstall*"} - $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} | ForEach-Object { - if($($sync.configs.applications.$($psitem.name).winget) -in $CheckBoxesToCheck){ - $sync.$($PSItem.name).ischecked = $true - } - else{$sync.$($PSItem.name).ischecked = $false} + if (-not $CheckBoxesToCheck) + { + $sync.$checkboxName.IsChecked = $false + continue + } + + # Check if the checkbox name exists in the flattened JSON hashtable + if ($CheckBoxesToCheck.Contains($checkboxName)) { + # If it exists, set IsChecked to true + $sync.$checkboxName.IsChecked = $true + Write-Debug "$checkboxName is checked" + } else { + # If it doesn't exist, set IsChecked to false + $sync.$checkboxName.IsChecked = $false + Write-Debug "$checkboxName is not checked" } } } @@ -3123,7 +3383,8 @@ function Invoke-WPFRunspace { [CmdletBinding()] Param ( $ScriptBlock, - $ArgumentList + $ArgumentList, + $DebugPreference ) # Create a PowerShell instance @@ -3132,6 +3393,7 @@ function Invoke-WPFRunspace { # Add Scriptblock and Arguments to runspace $script:powershell.AddScript($ScriptBlock) $script:powershell.AddArgument($ArgumentList) + $script:powershell.AddArgument($DebugPreference) # Pass DebugPreference to the script block $script:powershell.RunspacePool = $sync.runspace # Execute the RunspacePool @@ -3162,19 +3424,19 @@ function Invoke-WPFShortcut { $iconPath = $null Switch ($ShortcutToAdd) { - "WinUtil" { - $SourceExe = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" - $IRM = 'irm https://christitus.com/win | iex' - $Powershell = '-ExecutionPolicy Bypass -Command "Start-Process powershell.exe -verb runas -ArgumentList' - $ArgumentsToSourceExe = "$powershell '$IRM'" - $DestinationName = "WinUtil.lnk" + "WinUtil" { + $SourceExe = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" + $IRM = 'irm https://christitus.com/win | iex' + $Powershell = '-ExecutionPolicy Bypass -Command "Start-Process powershell.exe -verb runas -ArgumentList' + $ArgumentsToSourceExe = "$powershell '$IRM'" + $DestinationName = "WinUtil.lnk" - if (Test-Path -Path "$env:TEMP\cttlogo.png") { - $iconPath = "$env:SystempRoot\cttlogo.ico" - ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath $iconPath + if (Test-Path -Path "$env:TEMP\cttlogo.png") { + $iconPath = "$env:SystempRoot\cttlogo.ico" + ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath $iconPath + } } } - } $FileBrowser = New-Object System.Windows.Forms.SaveFileDialog $FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop') @@ -3260,13 +3522,13 @@ function Invoke-WPFtweaksbutton { #> if($sync.ProcessRunning){ - $msg = "Install process is currently running." + $msg = "[Invoke-WPFtweaksbutton] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } - $Tweaks = Get-WinUtilCheckBoxes -Group "WPFTweaks" - + $Tweaks = (Get-WinUtilCheckBoxes)["WPFTweaks"] + Set-WinUtilDNS -DNSProvider $sync["WPFchangedns"].text if ($tweaks.count -eq 0 -and $sync["WPFchangedns"].text -eq "Default"){ @@ -3275,21 +3537,20 @@ function Invoke-WPFtweaksbutton { return } - Invoke-WPFRunspace -ArgumentList $Tweaks -ScriptBlock { - param($Tweaks) + Write-Debug "Number of tweaks to process: $($Tweaks.Count)" + + Invoke-WPFRunspace -ArgumentList $Tweaks -DebugPreference $DebugPreference -ScriptBlock { + param($Tweaks, $DebugPreference) + Write-Debug "Inside Number of tweaks to process: $($Tweaks.Count)" $sync.ProcessRunning = $true - # Executes first if selected - if ("WPFEssTweaksRestorePoint" -in $Tweaks) { - Invoke-WinUtilTweaks "WPFEssTweaksRestorePoint" - } - + $cnt = 0 # Execute other selected tweaks - foreach ($tweak in $tweaks) { - if ($tweak -ne "WPFEssTweaksRestorePoint") { - Invoke-WinUtilTweaks $tweak - } + foreach ($tweak in $Tweaks) { + Write-Debug "This is a tweak to run $tweak count: $cnt" + Invoke-WinUtilTweaks $tweak + $cnt += 1 } $sync.ProcessRunning = $false @@ -3297,12 +3558,11 @@ function Invoke-WPFtweaksbutton { Write-Host "-- Tweaks are Finished ---" Write-Host "=================================" - $ButtonType = [System.Windows.MessageBoxButton]::OK - $MessageboxTitle = "Tweaks are Finished " - $Messageboxbody = ("Done") - $MessageIcon = [System.Windows.MessageBoxImage]::Information - - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) + # $ButtonType = [System.Windows.MessageBoxButton]::OK + # $MessageboxTitle = "Tweaks are Finished " + # $Messageboxbody = ("Done") + # $MessageIcon = [System.Windows.MessageBoxImage]::Information + # [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) } } Function Invoke-WPFUltimatePerformance { @@ -3392,12 +3652,12 @@ function Invoke-WPFundoall { #> if($sync.ProcessRunning){ - $msg = "Install process is currently running." + $msg = "[Invoke-WPFundoall] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } - $Tweaks = Get-WinUtilCheckBoxes -Group "WPFTweaks" + $Tweaks = (Get-WinUtilCheckBoxes)["WPFTweaks"] if ($tweaks.count -eq 0){ $msg = "Please check the tweaks you wish to undo." @@ -3405,8 +3665,8 @@ function Invoke-WPFundoall { return } - Invoke-WPFRunspace -ArgumentList $Tweaks -ScriptBlock { - param($Tweaks) + Invoke-WPFRunspace -ArgumentList $Tweaks,$DebugPreference -ScriptBlock { + param($Tweaks, $DebugPreference) $sync.ProcessRunning = $true @@ -3588,12 +3848,12 @@ function Invoke-WPFUnInstall { #> if($sync.ProcessRunning){ - $msg = "Install process is currently running" + $msg = "[Invoke-WPFUnInstall] Install process is currently running" [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } - $WingetInstall = Get-WinUtilCheckBoxes -Group "WPFInstall" + $WingetInstall = (Get-WinUtilCheckBoxes)["Install"] if ($wingetinstall.Count -eq 0) { $WarningMsg = "Please select the program(s) to install" @@ -3610,8 +3870,9 @@ function Invoke-WPFUnInstall { if($confirm -eq "No"){return} - Invoke-WPFRunspace -ArgumentList $WingetInstall -scriptblock { - param($WingetInstall) + Invoke-WPFRunspace -ArgumentList $WingetInstall,$DebugPreference -ScriptBlock { + param($WingetInstall, $DebugPreference) + try{ $sync.ProcessRunning = $true @@ -3785,15 +4046,6 @@ $inputXML = ' - - - - - - - - - + + + + + +