mirror of
https://github.com/ChrisTitusTech/winutil
synced 2026-04-05 22:28:31 +00:00
Compare commits
11 Commits
08b24c7187
...
e909d1a847
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e909d1a847 | ||
|
|
dcfa68476a | ||
|
|
60d31a1fe0 | ||
|
|
5476cd928f | ||
|
|
84f2046912 | ||
|
|
586fd56603 | ||
|
|
70a94abe02 | ||
|
|
0e41122d89 | ||
|
|
4e7416a2dc | ||
|
|
61a6265cf9 | ||
|
|
5582c3cb44 |
19
.github/workflows/pre-release.yaml
vendored
19
.github/workflows/pre-release.yaml
vendored
@@ -16,6 +16,25 @@ jobs:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Generate Dev Docs and Update JSON Links
|
||||
shell: pwsh
|
||||
run: |
|
||||
Set-Location tools
|
||||
./devdocs-generator.ps1
|
||||
|
||||
- name: Commit Updated JSON Links
|
||||
shell: pwsh
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add config/tweaks.json config/feature.json
|
||||
$changes = git diff --cached --quiet; if ($LASTEXITCODE -ne 0) {
|
||||
git commit -m "Update documentation links in JSON configs"
|
||||
git push
|
||||
} else {
|
||||
Write-Host "No JSON link changes to commit"
|
||||
}
|
||||
|
||||
- name: Compile project
|
||||
shell: pwsh
|
||||
run: |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -72,5 +72,13 @@
|
||||
"Type": "Button",
|
||||
"Order": "5",
|
||||
"Description": "Show the selected applications"
|
||||
},
|
||||
"WPFToggleFOSSHighlight": {
|
||||
"Content": "Highlight FOSS",
|
||||
"Category": "__Selection",
|
||||
"Type": "Toggle",
|
||||
"Checked": true,
|
||||
"Order": "6",
|
||||
"Description": "Toggle the green highlight for FOSS applications"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,15 +181,6 @@
|
||||
"ButtonWidth": "300",
|
||||
"link": "https://winutil.christitus.com/dev/features/fixes/winget"
|
||||
},
|
||||
"WPFRunAdobeCCCleanerTool": {
|
||||
"Content": "Remove Adobe Creative Cloud",
|
||||
"category": "Fixes",
|
||||
"panel": "1",
|
||||
"Order": "a045_",
|
||||
"Type": "Button",
|
||||
"ButtonWidth": "300",
|
||||
"link": "https://winutil.christitus.com/dev/features/fixes/runadobecccleanertool"
|
||||
},
|
||||
"WPFPanelControl": {
|
||||
"Content": "Control Panel",
|
||||
"category": "Legacy Windows Panels",
|
||||
|
||||
@@ -65,9 +65,11 @@
|
||||
"panel": "1",
|
||||
"InvokeScript": [
|
||||
"
|
||||
# Sometimes if you dont stop Widgets Process for removal to work
|
||||
# Sometimes if you dont stop the Widgets process the removal may fail
|
||||
|
||||
Stop-Process -Name Widgets
|
||||
Get-AppxPackage Microsoft.WidgetsPlatformRuntime -AllUsers | Remove-AppxPackage -AllUsers
|
||||
Get-AppxPackage MicrosoftWindows.Client.WebExperience -AllUsers | Remove-AppxPackage -AllUsers
|
||||
|
||||
Invoke-WinUtilExplorerUpdate -action \"restart\"
|
||||
Write-Host \"Removed widgets\"
|
||||
@@ -76,59 +78,49 @@
|
||||
"UndoScript": [
|
||||
"
|
||||
Write-Host \"Restoring widgets AppxPackages\"
|
||||
Add-AppxPackage -DisableDevelopmentMode -Register \"C:\\Program Files\\WindowsApps\\Microsoft.WidgetsPlatformRuntime*\\AppxManifest.xml\"
|
||||
|
||||
Add-AppxPackage -Register \"C:\\Program Files\\WindowsApps\\Microsoft.WidgetsPlatformRuntime*\\AppxManifest.xml\" -DisableDevelopmentMode
|
||||
Add-AppxPackage -Register \"C:\\Program Files\\WindowsApps\\MicrosoftWindows.Client.WebExperience*\\AppxManifest.xml\" -DisableDevelopmentMode
|
||||
|
||||
Invoke-WinUtilExplorerUpdate -action \"restart\"
|
||||
"
|
||||
],
|
||||
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/widget"
|
||||
},
|
||||
"WPFTweaksLaptopHibernation": {
|
||||
"Content": "Set Hibernation as default (good for laptops)",
|
||||
"Description": "Most modern laptops have connected standby enabled which drains the battery, this sets hibernation as default which will not drain the battery. See issue https://github.com/ChrisTitusTech/winutil/issues/1399",
|
||||
"WPFTweaksRevertStartMenu": {
|
||||
"Content": "Revert the new start menu",
|
||||
"Description": "Uses vivetool to revert the the original start menu from 24h2",
|
||||
"category": "z__Advanced Tweaks - CAUTION",
|
||||
"panel": "1",
|
||||
"Order": "a030_",
|
||||
"registry": [
|
||||
{
|
||||
"Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Power\\PowerSettings\\238C9FA8-0AAD-41ED-83F4-97BE242C8F20\\7bc4a2f9-d8fc-4469-b07b-33eb785aaca0",
|
||||
"OriginalValue": "1",
|
||||
"Name": "Attributes",
|
||||
"Value": "2",
|
||||
"Type": "DWord"
|
||||
},
|
||||
{
|
||||
"Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Power\\PowerSettings\\abfc2519-3608-4c2a-94ea-171b0ed546ab\\94ac6d29-73ce-41a6-809f-6363ba21b47e",
|
||||
"OriginalValue": "0",
|
||||
"Name": "Attributes ",
|
||||
"Value": "2",
|
||||
"Type": "DWord"
|
||||
}
|
||||
],
|
||||
"InvokeScript": [
|
||||
"
|
||||
Write-Host \"Turn on Hibernation\"
|
||||
powercfg.exe /hibernate on
|
||||
Invoke-WebRequest https://github.com/thebookisclosed/ViVe/releases/download/v0.3.4/ViVeTool-v0.3.4-IntelAmd.zip -OutFile ViVeTool.zip
|
||||
|
||||
Expand-Archive ViVeTool.zip
|
||||
Remove-Item ViVeTool.zip
|
||||
|
||||
Start-Process 'ViVeTool\\ViVeTool.exe' -ArgumentList '/disable /id:47205210' -Wait -NoNewWindow
|
||||
|
||||
Remove-Item ViVeTool -Recurse
|
||||
|
||||
# Set hibernation as the default action
|
||||
powercfg.exe change standby-timeout-ac 60
|
||||
powercfg.exe change standby-timeout-dc 60
|
||||
powercfg.exe change monitor-timeout-ac 10
|
||||
powercfg.exe change monitor-timeout-dc 1
|
||||
Write-Host 'Old start menu reverted please restart your computer to take effect'
|
||||
"
|
||||
],
|
||||
"UndoScript": [
|
||||
"
|
||||
Write-Host \"Turn off Hibernation\"
|
||||
powercfg.exe /hibernate off
|
||||
Invoke-WebRequest https://github.com/thebookisclosed/ViVe/releases/download/v0.3.4/ViVeTool-v0.3.4-IntelAmd.zip -OutFile ViVeTool.zip
|
||||
|
||||
Expand-Archive ViVeTool.zip
|
||||
Remove-Item ViVeTool.zip
|
||||
|
||||
Start-Process 'ViVeTool\\ViVeTool.exe' -ArgumentList '/enable /id:47205210' -Wait -NoNewWindow
|
||||
|
||||
Remove-Item ViVeTool -Recurse
|
||||
|
||||
# Set standby to default values
|
||||
powercfg.exe change standby-timeout-ac 15
|
||||
powercfg.exe change standby-timeout-dc 15
|
||||
powercfg.exe change monitor-timeout-ac 15
|
||||
powercfg.exe change monitor-timeout-dc 15
|
||||
Write-Host 'New start menu reverted please restart your computer to take effect'
|
||||
"
|
||||
],
|
||||
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/laptophibernation"
|
||||
"link": "https://winutil.christitus.com/dev/tweaks/z--Advanced-Tweaks---CAUTION/revertstartmenu"
|
||||
},
|
||||
"WPFTweaksLocation": {
|
||||
"Content": "Disable Location Tracking",
|
||||
@@ -1196,10 +1188,10 @@
|
||||
"OriginalValue": "<RemoveEntry>"
|
||||
},
|
||||
{
|
||||
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
|
||||
"Name": "ofefcgjbeghpigppfmkologfjadafddi",
|
||||
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge\\ExtensionInstallBlocklist",
|
||||
"Name": "1",
|
||||
"Type": "String",
|
||||
"Value": "1",
|
||||
"Value": "ofefcgjbeghpigppfmkologfjadafddi",
|
||||
"OriginalValue": "<RemoveEntry>"
|
||||
},
|
||||
{
|
||||
@@ -1987,9 +1979,9 @@
|
||||
"InvokeScript": [
|
||||
"
|
||||
$hostsUrl = \"https://github.com/Ruddernation-Designs/Adobe-URL-Block-List/raw/refs/heads/master/hosts\"
|
||||
$hosts = \"$env:SystemRoot\\System32\\drivers\\etc\\hosts\"
|
||||
$hosts = \"$Env:SystemRoot\\System32\\drivers\\etc\\hosts\"
|
||||
|
||||
Copy-Item $hosts \"$env:SystemRoot\\System32\\drivers\\etc\\hosts\\$hosts.bak\"
|
||||
Move-Item $hosts \"$hosts.bak\"
|
||||
Invoke-WebRequest $hostsUrl -OutFile $hosts
|
||||
ipconfig /flushdns
|
||||
|
||||
@@ -1998,10 +1990,10 @@
|
||||
],
|
||||
"UndoScript": [
|
||||
"
|
||||
$hosts = \"$env:SystemRoot\\System32\\drivers\\etc\\hosts\"
|
||||
$backup = \"$env:SystemRoot\\System32\\drivers\\etc\\hosts\\$hosts.bak\"
|
||||
$hosts = \"$Env:SystemRoot\\System32\\drivers\\etc\\hosts\"
|
||||
|
||||
Remove-Item $hosts
|
||||
Move-Item \"$hosts.bak\" $hosts
|
||||
ipconfig /flushdns
|
||||
|
||||
Write-Host \"Removed Adobe url block list from host file\"
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
title: "Revert the new start menu"
|
||||
description: ""
|
||||
---
|
||||
|
||||
```json
|
||||
"WPFTweaksRevertStartMenu": {
|
||||
"Content": "Revert the new start menu",
|
||||
"Description": "Uses vivetool to revert the the original start menu from 24h2",
|
||||
"category": "z__Advanced Tweaks - CAUTION",
|
||||
"panel": "1",
|
||||
"InvokeScript": [
|
||||
"
|
||||
Invoke-WebRequest https://github.com/thebookisclosed/ViVe/releases/download/v0.3.4/ViVeTool-v0.3.4-IntelAmd.zip -OutFile ViVeTool.zip
|
||||
|
||||
Expand-Archive ViVeTool.zip
|
||||
Remove-Item ViVeTool.zip
|
||||
|
||||
ViVeTool\\ViVeTool.exe /disable /id:47205210
|
||||
|
||||
Remove-Item ViVeTool -Recurse
|
||||
|
||||
Write-Host 'Old start menu reverted please restart your computer to take effect'
|
||||
"
|
||||
],
|
||||
"UndoScript": [
|
||||
"
|
||||
Invoke-WebRequest https://github.com/thebookisclosed/ViVe/releases/download/v0.3.4/ViVeTool-v0.3.4-IntelAmd.zip -OutFile ViVeTool.zip
|
||||
|
||||
Expand-Archive ViVeTool.zip
|
||||
Remove-Item ViVeTool.zip
|
||||
|
||||
ViVeTool\\ViVeTool.exe /enable /id:47205210
|
||||
|
||||
Remove-Item ViVeTool -Recurse
|
||||
|
||||
Write-Host 'New start menu reverted please restart your computer to take effect'
|
||||
"
|
||||
],
|
||||
```
|
||||
@@ -1,4 +1,4 @@
|
||||
copyright: "© <script>document.write(new Date().getFullYear())</script> <a href='https://christitus.com'> Chris Titus Tech</a>. All rights reserved."
|
||||
copyright: "© <script>document.write(new Date().getFullYear())</script> <a href='https://christitus.com'>Chris Titus Tech</a>. All rights reserved."
|
||||
|
||||
backToTop: "Scroll to top"
|
||||
changeLanguage: "Change language"
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
Function Get-WinUtilCheckBoxes {
|
||||
|
||||
<#
|
||||
|
||||
.SYNOPSIS
|
||||
Finds all checkboxes that are checked on the specific tab and inputs them into a script.
|
||||
|
||||
.PARAMETER unCheck
|
||||
Whether to uncheck the checkboxes that are checked. Defaults to true
|
||||
|
||||
.OUTPUTS
|
||||
A List containing the name of each checked checkbox
|
||||
|
||||
.EXAMPLE
|
||||
Get-WinUtilCheckBoxes "WPFInstall"
|
||||
|
||||
#>
|
||||
|
||||
Param(
|
||||
[boolean]$unCheck = $false
|
||||
)
|
||||
|
||||
$Output = @{
|
||||
Install = @()
|
||||
WPFTweaks = @()
|
||||
WPFFeature = @()
|
||||
WPFInstall = @()
|
||||
WPFToggle = @()
|
||||
}
|
||||
|
||||
$CheckBoxes = $sync.GetEnumerator() | Where-Object { $_.Value -is [System.Windows.Controls.CheckBox] }
|
||||
|
||||
# Collect toggle switch states
|
||||
foreach ($CheckBox in $CheckBoxes) {
|
||||
if ($CheckBox.Key -like "WPFToggle*" -and $CheckBox.Value.IsChecked -eq $true) {
|
||||
$Output["WPFToggle"] += $CheckBox.Key
|
||||
Write-Debug "Adding toggle: $($CheckBox.Key)"
|
||||
}
|
||||
}
|
||||
|
||||
# First check and add WPFTweaksRestorePoint if checked
|
||||
$RestorePoint = $CheckBoxes | Where-Object { $_.Key -eq 'WPFTweaksRestorePoint' -and $_.Value.IsChecked -eq $true }
|
||||
if ($RestorePoint) {
|
||||
$Output["WPFTweaks"] = @('WPFTweaksRestorePoint')
|
||||
Write-Debug "Adding WPFTweaksRestorePoint as first in WPFTweaks"
|
||||
|
||||
if ($unCheck) {
|
||||
$RestorePoint.Value.IsChecked = $false
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($CheckBox in $CheckBoxes) {
|
||||
if ($CheckBox.Key -eq 'WPFTweaksRestorePoint') { continue } # Skip since it's already handled
|
||||
|
||||
$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
|
||||
[PsCustomObject]@{
|
||||
winget="$($sync.configs.applications.$($CheckBox.Name).winget)";
|
||||
choco="$($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) {
|
||||
$CheckBox.Value.IsChecked = $false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $Output
|
||||
}
|
||||
@@ -41,16 +41,19 @@ function Initialize-InstallAppEntry {
|
||||
})
|
||||
|
||||
$checkBox = New-Object Windows.Controls.CheckBox
|
||||
$checkBox.Name = $appKey
|
||||
# Sanitize the name for WPF
|
||||
$checkBox.Name = $appKey -replace '-', '_'
|
||||
# Store the original appKey in Tag
|
||||
$checkBox.Tag = $appKey
|
||||
$checkbox.Style = $sync.Form.Resources.AppEntryCheckboxStyle
|
||||
$checkbox.Add_Checked({
|
||||
Invoke-WPFSelectedAppsUpdate -type "Add" -checkbox $this
|
||||
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $this.Parent.Tag
|
||||
$borderElement = $this.Parent
|
||||
$borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallSelectedColor")
|
||||
})
|
||||
|
||||
$checkbox.Add_Unchecked({
|
||||
Invoke-WPFSelectedAppsUpdate -type "Remove" -checkbox $this
|
||||
Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $this.Parent.Tag
|
||||
$borderElement = $this.Parent
|
||||
$borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor")
|
||||
})
|
||||
@@ -60,6 +63,12 @@ function Initialize-InstallAppEntry {
|
||||
$appName.Style = $sync.Form.Resources.AppEntryNameStyle
|
||||
$appName.Text = $Apps.$appKey.content
|
||||
|
||||
# Change color to Green if FOSS
|
||||
if ($Apps.$appKey.foss -eq $true) {
|
||||
$appName.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "FOSSColor")
|
||||
$appName.FontWeight = "Bold"
|
||||
}
|
||||
|
||||
# Add the name to the Checkbox
|
||||
$checkBox.Content = $appName
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ Function Invoke-WinUtilCurrentSystem {
|
||||
Checks to see what tweaks have already been applied and what programs are installed, and checks the according boxes
|
||||
|
||||
.EXAMPLE
|
||||
Get-WinUtilCheckBoxes "WPFInstall"
|
||||
InvokeWinUtilCurrentSystem -Checkbox "winget"
|
||||
|
||||
#>
|
||||
|
||||
|
||||
@@ -174,6 +174,18 @@ function Invoke-WinutilThemeChange {
|
||||
}
|
||||
}
|
||||
|
||||
# Set FOSS Highlight Color
|
||||
$fossEnabled = $true
|
||||
if ($sync.WPFToggleFOSSHighlight) {
|
||||
$fossEnabled = $sync.WPFToggleFOSSHighlight.IsChecked
|
||||
}
|
||||
|
||||
if ($fossEnabled) {
|
||||
$sync.Form.Resources["FOSSColor"] = [Windows.Media.SolidColorBrush]::new([Windows.Media.Color]::FromRgb(76, 175, 80)) # #4CAF50
|
||||
} else {
|
||||
$sync.Form.Resources["FOSSColor"] = $sync.Form.Resources["MainForegroundColor"]
|
||||
}
|
||||
|
||||
# Update the theme selector button with the appropriate icon
|
||||
$ThemeButton = $sync.Form.FindName("ThemeButton")
|
||||
$ThemeButton.Content = [string]$themeButtonIcon
|
||||
|
||||
75
functions/private/Reset-WPFCheckBoxes.ps1
Normal file
75
functions/private/Reset-WPFCheckBoxes.ps1
Normal file
@@ -0,0 +1,75 @@
|
||||
function Reset-WPFCheckBoxes {
|
||||
<#
|
||||
|
||||
.SYNOPSIS
|
||||
Set winutil checkboxs to match $sync.selected values.
|
||||
Should only need to be run if $sync.selected updated outside of UI (i.e. presets or import)
|
||||
|
||||
.PARAMETER doToggles
|
||||
Whether or not to set UI toggles. WARNING: they will trigger if altered
|
||||
|
||||
.PARAMETER checkboxfilterpattern
|
||||
The Pattern to use when filtering through CheckBoxes, defaults to "**"
|
||||
Used to make reset blazingly fast.
|
||||
#>
|
||||
|
||||
param (
|
||||
[Parameter(position=0)]
|
||||
[bool]$doToggles = $false,
|
||||
|
||||
[Parameter(position=1)]
|
||||
[string]$checkboxfilterpattern = "**"
|
||||
)
|
||||
|
||||
$CheckBoxesToCheck = $sync.selectedApps + $sync.selectedTweaks + $sync.selectedFeatures
|
||||
$CheckBoxes = ($sync.GetEnumerator()).where{ $_.Value -is [System.Windows.Controls.CheckBox] -and $_.Name -notlike "WPFToggle*" -and $_.Name -like "$checkboxfilterpattern"}
|
||||
Write-Debug "Getting checkboxes to set, number of checkboxes: $($CheckBoxes.Count)"
|
||||
|
||||
if ($CheckBoxesToCheck -ne "") {
|
||||
$debugMsg = "CheckBoxes to Check are: "
|
||||
$CheckBoxesToCheck | ForEach-Object { $debugMsg += "$_, " }
|
||||
$debugMsg = $debugMsg -replace (',\s*$', '')
|
||||
Write-Debug "$debugMsg"
|
||||
}
|
||||
|
||||
foreach ($CheckBox in $CheckBoxes) {
|
||||
$checkboxName = $CheckBox.Key
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
# Update Installs tab UI values
|
||||
$count = $sync.SelectedApps.Count
|
||||
$sync.WPFselectedAppsButton.Content = "Selected Apps: $count"
|
||||
# On every change, remove all entries inside the Popup Menu. This is done, so we can keep the alphabetical order even if elements are selected in a random way
|
||||
$sync.selectedAppsstackPanel.Children.Clear()
|
||||
$sync.selectedApps | Foreach-Object { Add-SelectedAppsMenuItem -name $($sync.configs.applicationsHashtable.$_.Content) -key $_ }
|
||||
|
||||
if($doToggles) {
|
||||
# Restore toggle switch states
|
||||
$importedToggles = $sync.selectedToggles
|
||||
$allToggles = $sync.GetEnumerator() | Where-Object { $_.Key -like "WPFToggle*" -and $_.Value -is [System.Windows.Controls.CheckBox] }
|
||||
foreach ($toggle in $allToggles) {
|
||||
if ($importedToggles -contains $toggle.Key) {
|
||||
$sync[$toggle.Key].IsChecked = $true
|
||||
Write-Debug "Restoring toggle: $($toggle.Key) = checked"
|
||||
} else {
|
||||
$sync[$toggle.Key].IsChecked = $false
|
||||
Write-Debug "Restoring toggle: $($toggle.Key) = unchecked"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
59
functions/private/Update-WinUtilSelections.ps1
Normal file
59
functions/private/Update-WinUtilSelections.ps1
Normal file
@@ -0,0 +1,59 @@
|
||||
function Update-WinUtilSelections {
|
||||
<#
|
||||
|
||||
.SYNOPSIS
|
||||
Updates the $sync.selected variables with a given preset.
|
||||
|
||||
.PARAMETER flatJson
|
||||
The flattened json list of $sync values to select.
|
||||
#>
|
||||
|
||||
param (
|
||||
$flatJson
|
||||
)
|
||||
|
||||
Write-Debug "JSON to import: $($flatJson)"
|
||||
|
||||
foreach ($cbkey in $flatJson) {
|
||||
$group = if ($cbkey.StartsWith("WPFInstall")) { "Install" }
|
||||
elseif ($cbkey.StartsWith("WPFTweaks")) { "Tweaks" }
|
||||
elseif ($cbkey.StartsWith("WPFToggle")) { "Toggle" }
|
||||
elseif ($cbkey.StartsWith("WPFFeature")) { "Feature" }
|
||||
else { "na" }
|
||||
|
||||
switch ($group) {
|
||||
"Install" {
|
||||
if (!$sync.selectedApps.Contains($cbkey)) {
|
||||
$sync.selectedApps.Add($cbkey)
|
||||
# The List type needs to be specified again, because otherwise Sort-Object will convert the list to a string if there is only a single entry
|
||||
[System.Collections.Generic.List[pscustomobject]]$sync.selectedApps = $sync.SelectedApps | Sort-Object
|
||||
}
|
||||
}
|
||||
"Tweaks" {
|
||||
if (!$sync.selectedTweaks.Contains($cbkey)) {
|
||||
$sync.selectedTweaks.Add($cbkey)
|
||||
}
|
||||
}
|
||||
"Toggle" {
|
||||
if (!$sync.selectedToggles.Contains($cbkey)) {
|
||||
$sync.selectedToggles.Add($cbkey)
|
||||
}
|
||||
}
|
||||
"Feature" {
|
||||
if (!$sync.selectedFeatures.Contains($cbkey)) {
|
||||
$sync.selectedFeatures.Add($cbkey)
|
||||
}
|
||||
}
|
||||
default {
|
||||
Write-Host "Unknown group for checkbox: $($cbkey)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Debug "-------------------------------------"
|
||||
Write-Debug "Selected Apps: $($sync.selectedApps)"
|
||||
Write-Debug "Selected Tweaks: $($sync.selectedTweaks)"
|
||||
Write-Debug "Selected Toggles: $($sync.selectedToggles)"
|
||||
Write-Debug "Selected Features: $($sync.selectedFeatures)"
|
||||
Write-Debug "--------------------------------------"
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
function Invoke-AutoConfigDialog {
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Sets the automatic configuration file based on a specified JSON file
|
||||
#>
|
||||
|
||||
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
|
||||
$OFD = New-Object System.Windows.Forms.OpenFileDialog
|
||||
$OFD.Filter = "JSON Files (*.json)|*.json"
|
||||
$OFD.ShowDialog()
|
||||
|
||||
if ($OFD.FileName -eq "")
|
||||
{
|
||||
Write-Host "No automatic config file has been selected. Continuing without one..."
|
||||
return
|
||||
}
|
||||
|
||||
return $OFD.FileName
|
||||
}
|
||||
@@ -63,5 +63,12 @@ function Invoke-WPFButton {
|
||||
"WPFWinUtilUninstallPSProfile" {Invoke-WinUtilUninstallPSProfile}
|
||||
"WPFWinUtilSSHServer" {Invoke-WPFSSHServer}
|
||||
"WPFselectedAppsButton" {$sync.selectedAppsPopup.IsOpen = -not $sync.selectedAppsPopup.IsOpen}
|
||||
"WPFToggleFOSSHighlight" {
|
||||
if ($sync.WPFToggleFOSSHighlight.IsChecked) {
|
||||
$sync.Form.Resources["FOSSColor"] = [Windows.Media.SolidColorBrush]::new([Windows.Media.Color]::FromRgb(76, 175, 80)) # #4CAF50
|
||||
} else {
|
||||
$sync.Form.Resources["FOSSColor"] = $sync.Form.Resources["MainForegroundColor"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ function Invoke-WPFFeatureInstall {
|
||||
return
|
||||
}
|
||||
|
||||
$Features = (Get-WinUtilCheckBoxes)["WPFFeature"]
|
||||
$Features = $sync.selectedFeatures
|
||||
|
||||
Invoke-WPFRunspace -ArgumentList $Features -DebugPreference $DebugPreference -ScriptBlock {
|
||||
param($Features, $DebugPreference)
|
||||
|
||||
@@ -44,7 +44,8 @@ function Invoke-WPFImpex {
|
||||
try {
|
||||
$Config = ConfigDialog
|
||||
if ($Config) {
|
||||
$jsonFile = Get-WinUtilCheckBoxes -unCheck $false | ConvertTo-Json
|
||||
$allConfs = $sync.selectedApps + $sync.selectedTweaks + $sync.selectedToggles + $sync.selectedFeatures
|
||||
$jsonFile = $allConfs | ConvertTo-Json
|
||||
$jsonFile | Out-File $Config -Force
|
||||
"iex ""& { `$(irm https://christitus.com/win) } -Config '$Config'""" | Set-Clipboard
|
||||
}
|
||||
@@ -66,21 +67,12 @@ function Invoke-WPFImpex {
|
||||
Write-Error "Failed to load the JSON file from the specified path or URL: $_"
|
||||
return
|
||||
}
|
||||
$flattenedJson = $jsonFile.PSObject.Properties.Where({ $_.Name -ne "Install" -and $_.Name -ne "WPFToggle" }).ForEach({ $_.Value })
|
||||
Invoke-WPFPresets -preset $flattenedJson -imported $true
|
||||
|
||||
# Restore toggle switch states
|
||||
$importedToggles = if ($jsonFile.WPFToggle) { $jsonFile.WPFToggle } else { @() }
|
||||
$allToggles = $sync.GetEnumerator() | Where-Object { $_.Key -like "WPFToggle*" -and $_.Value -is [System.Windows.Controls.CheckBox] }
|
||||
foreach ($toggle in $allToggles) {
|
||||
if ($importedToggles -contains $toggle.Key) {
|
||||
$sync[$toggle.Key].IsChecked = $true
|
||||
Write-Debug "Restoring toggle: $($toggle.Key) = checked"
|
||||
} else {
|
||||
$sync[$toggle.Key].IsChecked = $false
|
||||
Write-Debug "Restoring toggle: $($toggle.Key) = unchecked"
|
||||
}
|
||||
}
|
||||
# TODO how to handle old style? detected json type then flatten it in a func?
|
||||
# $flattenedJson = $jsonFile.PSObject.Properties.Where({ $_.Name -ne "Install" }).ForEach({ $_.Value })
|
||||
$flattenedJson = $jsonFile
|
||||
Update-WinUtilSelections -flatJson $flattenedJson
|
||||
# TODO test with toggles
|
||||
Reset-WPFCheckBoxes -doToggles $true
|
||||
}
|
||||
} catch {
|
||||
Write-Error "An error occurred while importing: $_"
|
||||
|
||||
@@ -2,10 +2,10 @@ function Invoke-WPFPresets {
|
||||
<#
|
||||
|
||||
.SYNOPSIS
|
||||
Sets the options in the tweaks panel to the given preset
|
||||
Sets the checkboxes in winutil to the given preset
|
||||
|
||||
.PARAMETER preset
|
||||
The preset to set the options to
|
||||
The preset to set the checkboxes to
|
||||
|
||||
.PARAMETER imported
|
||||
If the preset is imported from a file, defaults to false
|
||||
@@ -17,7 +17,7 @@ function Invoke-WPFPresets {
|
||||
|
||||
param (
|
||||
[Parameter(position=0)]
|
||||
[Array]$preset = "",
|
||||
[Array]$preset = $null,
|
||||
|
||||
[Parameter(position=1)]
|
||||
[bool]$imported = $false,
|
||||
@@ -32,33 +32,19 @@ function Invoke-WPFPresets {
|
||||
$CheckBoxesToCheck = $sync.configs.preset.$preset
|
||||
}
|
||||
|
||||
$CheckBoxes = ($sync.GetEnumerator()).where{ $_.Value -is [System.Windows.Controls.CheckBox] -and $_.Name -notlike "WPFToggle*" -and $_.Name -like "$checkboxfilterpattern"}
|
||||
Write-Debug "Getting checkboxes to set, number of checkboxes: $($CheckBoxes.Count)"
|
||||
|
||||
if ($CheckBoxesToCheck -ne "") {
|
||||
$debugMsg = "CheckBoxes to Check are: "
|
||||
$CheckBoxesToCheck | ForEach-Object { $debugMsg += "$_, " }
|
||||
$debugMsg = $debugMsg -replace (',\s*$', '')
|
||||
Write-Debug "$debugMsg"
|
||||
}
|
||||
|
||||
foreach ($CheckBox in $CheckBoxes) {
|
||||
$checkboxName = $CheckBox.Key
|
||||
|
||||
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"
|
||||
# clear out the filtered pattern
|
||||
if (!$preset) {
|
||||
switch ($checkboxfilterpattern) {
|
||||
"WPFTweak*" { $sync.selectedTweaks = [System.Collections.Generic.List[string]]::new() }
|
||||
"WPFInstall*" { $sync.selectedApps = [System.Collections.Generic.List[string]]::new() }
|
||||
"WPFeatures" { $sync.selectedFeatures = [System.Collections.Generic.List[string]]::new() }
|
||||
"WPFToggle" { $sync.selectedToggles = [System.Collections.Generic.List[string]]::new() }
|
||||
default {}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Update-WinUtilSelections -flatJson $CheckBoxesToCheck
|
||||
}
|
||||
|
||||
Reset-WPFCheckBoxes -doToggles $false -checkboxfilterpattern $checkboxfilterpattern
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
function Invoke-WPFRunAdobeCCCleanerTool {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
It removes or fixes problem files and resolves permission issues in registry keys.
|
||||
.DESCRIPTION
|
||||
The Creative Cloud Cleaner tool is a utility for experienced users to clean up corrupted installations.
|
||||
#>
|
||||
|
||||
[string]$url="https://swupmf.adobe.com/webfeed/CleanerTool/win/AdobeCreativeCloudCleanerTool.exe"
|
||||
|
||||
Write-Host "The Adobe Creative Cloud Cleaner tool is hosted at"
|
||||
Write-Host "$url"
|
||||
|
||||
try {
|
||||
# Don't show the progress because it will slow down the download speed
|
||||
$ProgressPreference='SilentlyContinue'
|
||||
|
||||
Invoke-WebRequest -Uri $url -OutFile "$env:TEMP\AdobeCreativeCloudCleanerTool.exe" -UseBasicParsing -ErrorAction SilentlyContinue -Verbose
|
||||
|
||||
# Revert back the ProgressPreference variable to the default value since we got the file desired
|
||||
$ProgressPreference='Continue'
|
||||
|
||||
Start-Process -FilePath "$env:TEMP\AdobeCreativeCloudCleanerTool.exe" -Wait -ErrorAction SilentlyContinue -Verbose
|
||||
} catch {
|
||||
Write-Error $_.Exception.Message
|
||||
} finally {
|
||||
if (Test-Path -Path "$env:TEMP\AdobeCreativeCloudCleanerTool.exe") {
|
||||
Write-Host "Cleaning up..."
|
||||
Remove-Item -Path "$env:TEMP\AdobeCreativeCloudCleanerTool.exe" -Verbose
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
function Invoke-WPFSelectedAppsUpdate {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This is a helper function that is called by the Checked and Unchecked events of the Checkboxes on the install tab.
|
||||
It Updates the "Selected Apps" selectedAppLabel on the Install Tab to represent the current collection
|
||||
.PARAMETER type
|
||||
Eigther: Add | Remove
|
||||
.PARAMETER checkbox
|
||||
should contain the current instance of the checkbox that triggered the Event.
|
||||
Most of the time will be the automatic variable $this
|
||||
.EXAMPLE
|
||||
$checkbox.Add_Unchecked({Invoke-WPFSelectedAppsUpdate -type "Remove" -checkbox $this})
|
||||
OR
|
||||
Invoke-WPFSelectedAppsUpdate -type "Add" -checkbox $specificCheckbox
|
||||
#>
|
||||
param (
|
||||
$type,
|
||||
$checkbox
|
||||
)
|
||||
|
||||
$selectedAppsButton = $sync.WPFselectedAppsButton
|
||||
# Get the actual Name from the selectedAppLabel inside the Checkbox
|
||||
$appKey = $checkbox.Parent.Tag
|
||||
if ($type -eq "Add") {
|
||||
$sync.selectedApps.Add($appKey)
|
||||
# The List type needs to be specified again, because otherwise Sort-Object will convert the list to a string if there is only a single entry
|
||||
[System.Collections.Generic.List[pscustomobject]]$sync.selectedApps = $sync.SelectedApps | Sort-Object
|
||||
|
||||
}
|
||||
elseif ($type -eq "Remove") {
|
||||
$sync.SelectedApps.Remove($appKey)
|
||||
}
|
||||
else{
|
||||
Write-Error "Type: $type not implemented"
|
||||
}
|
||||
|
||||
$count = $sync.SelectedApps.Count
|
||||
$selectedAppsButton.Content = "Selected Apps: $count"
|
||||
# On every change, remove all entries inside the Popup Menu. This is done, so we can keep the alphabetical order even if elements are selected in a random way
|
||||
$sync.selectedAppsstackPanel.Children.Clear()
|
||||
$sync.SelectedApps | Foreach-Object { Add-SelectedAppsMenuItem -name $($sync.configs.applicationsHashtable.$_.Content) -key $_ }
|
||||
|
||||
}
|
||||
95
functions/public/Invoke-WPFSelectedCheckboxesUpdate.ps1
Normal file
95
functions/public/Invoke-WPFSelectedCheckboxesUpdate.ps1
Normal file
@@ -0,0 +1,95 @@
|
||||
function Invoke-WPFSelectedCheckboxesUpdate{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This is a helper function that is called by the Checked and Unchecked events of the Checkboxes.
|
||||
It also Updates the "Selected Apps" selectedAppLabel on the Install Tab to represent the current collection
|
||||
.PARAMETER type
|
||||
Either: Add | Remove
|
||||
.PARAMETER checkboxName
|
||||
should contain the name of the current instance of the checkbox that triggered the Event.
|
||||
Most of the time will be the automatic variable $this.Parent.Tag
|
||||
.EXAMPLE
|
||||
$checkbox.Add_Unchecked({Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $this.Parent.Tag})
|
||||
OR
|
||||
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $specificCheckbox.Parent.Tag
|
||||
#>
|
||||
param (
|
||||
$type,
|
||||
$checkboxName
|
||||
)
|
||||
|
||||
if (($type -ne "Add") -and ($type -ne "Remove"))
|
||||
{
|
||||
Write-Error "Type: $type not implemented"
|
||||
return
|
||||
}
|
||||
|
||||
# Get the actual Name from the selectedAppLabel inside the Checkbox
|
||||
$appKey = $checkboxName
|
||||
$group = if ($appKey.StartsWith("WPFInstall")) { "Install" }
|
||||
elseif ($appKey.StartsWith("WPFTweaks")) { "Tweaks" }
|
||||
elseif ($appKey.StartsWith("WPFToggle")) { "Toggle" }
|
||||
elseif ($appKey.StartsWith("WPFFeature")) { "Feature" }
|
||||
else { "na" }
|
||||
|
||||
switch ($group) {
|
||||
"Install" {
|
||||
if ($type -eq "Add") {
|
||||
if (!$sync.selectedApps.Contains($appKey)) {
|
||||
$sync.selectedApps.Add($appKey)
|
||||
# The List type needs to be specified again, because otherwise Sort-Object will convert the list to a string if there is only a single entry
|
||||
[System.Collections.Generic.List[pscustomobject]]$sync.selectedApps = $sync.SelectedApps | Sort-Object
|
||||
}
|
||||
}
|
||||
else{
|
||||
$sync.selectedApps.Remove($appKey)
|
||||
}
|
||||
|
||||
$count = $sync.SelectedApps.Count
|
||||
$sync.WPFselectedAppsButton.Content = "Selected Apps: $count"
|
||||
# On every change, remove all entries inside the Popup Menu. This is done, so we can keep the alphabetical order even if elements are selected in a random way
|
||||
$sync.selectedAppsstackPanel.Children.Clear()
|
||||
$sync.selectedApps | Foreach-Object { Add-SelectedAppsMenuItem -name $($sync.configs.applicationsHashtable.$_.Content) -key $_ }
|
||||
}
|
||||
"Tweaks" {
|
||||
if ($type -eq "Add") {
|
||||
if (!$sync.selectedTweaks.Contains($appKey)) {
|
||||
$sync.selectedTweaks.Add($appKey)
|
||||
}
|
||||
}
|
||||
else{
|
||||
$sync.selectedTweaks.Remove($appKey)
|
||||
}
|
||||
}
|
||||
"Toggle" {
|
||||
if ($type -eq "Add") {
|
||||
if (!$sync.selectedToggles.Contains($appKey)) {
|
||||
$sync.selectedToggles.Add($appKey)
|
||||
}
|
||||
}
|
||||
else{
|
||||
$sync.selectedToggles.Remove($appKey)
|
||||
}
|
||||
}
|
||||
"Feature" {
|
||||
if ($type -eq "Add") {
|
||||
if (!$sync.selectedFeatures.Contains($appKey)) {
|
||||
$sync.selectedFeatures.Add($appKey)
|
||||
}
|
||||
}
|
||||
else{
|
||||
$sync.selectedFeatures.Remove($appKey)
|
||||
}
|
||||
}
|
||||
default {
|
||||
Write-Host "Unknown group for checkbox: $($appKey)"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Debug "-------------------------------------"
|
||||
Write-Debug "Selected Apps: $($sync.selectedApps)"
|
||||
Write-Debug "Selected Tweaks: $($sync.selectedTweaks)"
|
||||
Write-Debug "Selected Toggles: $($sync.selectedToggles)"
|
||||
Write-Debug "Selected Features: $($sync.selectedFeatures)"
|
||||
Write-Debug "--------------------------------------"
|
||||
}
|
||||
@@ -1,137 +1,17 @@
|
||||
function Invoke-WPFSystemRepair {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Checks for system corruption using Chkdsk, SFC, and DISM
|
||||
Checks for system corruption using SFC, and DISM
|
||||
|
||||
.DESCRIPTION
|
||||
1. Chkdsk - Fixes disk and filesystem corruption
|
||||
2. SFC Run 1 - Fixes system file corruption, and fixes DISM if it was corrupted
|
||||
3. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
|
||||
4. SFC Run 2 - Fixes system file corruption, this time with an almost guaranteed uncorrupted system image
|
||||
1. SFC - Fixes system file corruption, and fixes DISM if it was corrupted
|
||||
2. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
|
||||
3. Chkdsk - Checks for disk errors, which can cause system file corruption and notifies of early disk failure
|
||||
#>
|
||||
Start-Process cmd.exe -ArgumentList "/c chkdsk.exe /scan /perf" -NoNewWindow -Wait
|
||||
Start-Process cmd.exe -ArgumentList "/c sfc /scannow" -NoNewWindow -Wait
|
||||
Start-Process cmd.exe -ArgumentList "/c dism /online /cleanup-image /restorehealth" -NoNewWindow -Wait
|
||||
|
||||
function Invoke-Chkdsk {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Runs chkdsk on the system drive
|
||||
.DESCRIPTION
|
||||
Chkdsk /Scan - Runs an online scan on the system drive, attempts to fix any corruption, and queues other corruption for fixing on reboot
|
||||
#>
|
||||
param(
|
||||
[int]$parentProgressId = 0
|
||||
)
|
||||
|
||||
Write-Progress -Id 1 -ParentId $parentProgressId -Activity $childProgressBarActivity -Status "Running chkdsk..." -PercentComplete 0
|
||||
$oldpercent = 0
|
||||
# 2>&1 redirects stdout, allowing iteration over the output
|
||||
chkdsk.exe /scan /perf 2>&1 | ForEach-Object {
|
||||
Write-Debug $_
|
||||
# Regex to match the total percentage regardless of windows locale (it's always the second percentage in the status output)
|
||||
if ($_ -match "%.*?(\d+)%") {
|
||||
[int]$percent = $matches[1]
|
||||
if ($percent -gt $oldpercent) {
|
||||
Write-Progress -Id 1 -Activity $childProgressBarActivity -Status "Running chkdsk... ($percent%)" -PercentComplete $percent
|
||||
$oldpercent = $percent
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Progress -Id 1 -Activity $childProgressBarActivity -Status "chkdsk Completed" -PercentComplete 100 -Completed
|
||||
}
|
||||
|
||||
function Invoke-SFC {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Runs sfc on the system drive
|
||||
.DESCRIPTION
|
||||
SFC /ScanNow - Performs a scan of the system files and fixes any corruption
|
||||
.NOTES
|
||||
ErrorActionPreference is set locally within a script block & {...} to isolate their effects.
|
||||
ErrorActionPreference suppresses false errors caused by sfc.exe output redirection.
|
||||
A bug in SFC output buffering causes progress updates to appear in chunks when redirecting output
|
||||
#>
|
||||
param(
|
||||
[int]$parentProgressId = 0
|
||||
)
|
||||
& {
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
Write-Progress -Id 1 -ParentId $parentProgressId -Activity $childProgressBarActivity -Status "Running SFC..." -PercentComplete 0
|
||||
$oldpercent = 0
|
||||
sfc.exe /scannow 2>&1 | ForEach-Object {
|
||||
Write-Debug $_
|
||||
if ($_ -ne "") {
|
||||
# sfc.exe /scannow outputs unicode characters, so we directly remove null characters for optimization
|
||||
$utf8line = $_ -replace "`0", ""
|
||||
if ($utf8line -match "(\d+)\s*%") {
|
||||
[int]$percent = $matches[1]
|
||||
if ($percent -gt $oldpercent) {
|
||||
Write-Progress -Id 1 -Activity $childProgressBarActivity -Status "Running SFC... ($percent%)" -PercentComplete $percent
|
||||
$oldpercent = $percent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Progress -Id 1 -Activity $childProgressBarActivity -Status "SFC Completed" -PercentComplete 100 -Completed
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-DISM {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Runs DISM on the system drive
|
||||
.DESCRIPTION
|
||||
DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
|
||||
/Online - Fixes the currently running system image
|
||||
/Cleanup-Image - Performs cleanup operations on the image, could remove some unneeded temporary files
|
||||
/Restorehealth - Performs a scan of the image and fixes any corruption
|
||||
#>
|
||||
param(
|
||||
[int]$parentProgressId = 0
|
||||
)
|
||||
Write-Progress -Id 1 -ParentId $parentProgressId -Activity $childProgressBarActivity -Status "Running DISM..." -PercentComplete 0
|
||||
$oldpercent = 0
|
||||
DISM /Online /Cleanup-Image /RestoreHealth | ForEach-Object {
|
||||
Write-Debug $_
|
||||
# Filter for lines that contain a percentage that is greater than the previous one
|
||||
if ($_ -match "(\d+)[.,]\d+%") {
|
||||
[int]$percent = $matches[1]
|
||||
if ($percent -gt $oldpercent) {
|
||||
# Update the progress bar
|
||||
Write-Progress -Id 1 -Activity $childProgressBarActivity -Status "Running DISM... ($percent%)" -PercentComplete $percent
|
||||
$oldpercent = $percent
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Progress -Id 1 -Activity $childProgressBarActivity -Status "DISM Completed" -PercentComplete 100 -Completed
|
||||
}
|
||||
|
||||
try {
|
||||
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
|
||||
|
||||
$childProgressBarActivity = "Scanning for corruption"
|
||||
Write-Progress -Id 0 -Activity "Repairing Windows" -PercentComplete 0
|
||||
# Step 1: Run chkdsk to fix disk and filesystem corruption before proceeding with system file repairs
|
||||
Invoke-Chkdsk
|
||||
Write-Progress -Id 0 -Activity "Repairing Windows" -PercentComplete 25
|
||||
|
||||
# Step 2: Run SFC to fix system file corruption and ensure DISM can operate correctly
|
||||
Invoke-SFC
|
||||
Write-Progress -Id 0 -Activity "Repairing Windows" -PercentComplete 50
|
||||
|
||||
# Step 3: Run DISM to repair the system image, which SFC relies on for accurate repairs
|
||||
Invoke-DISM
|
||||
Write-Progress -Id 0 -Activity "Repairing Windows" -PercentComplete 75
|
||||
|
||||
# Step 4: Run SFC again to ensure system files are repaired using the now-fixed system image
|
||||
Invoke-SFC
|
||||
Write-Progress -Id 0 -Activity "Repairing Windows" -PercentComplete 100 -Completed
|
||||
|
||||
Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"
|
||||
} catch {
|
||||
Write-Error "An error occurred while repairing the system: $_"
|
||||
Set-WinUtilTaskbaritem -state "Error" -overlay "warning"
|
||||
} finally {
|
||||
Write-Host "==> Finished System Repair"
|
||||
Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"
|
||||
}
|
||||
|
||||
Write-Host "==> Finished System Repair"
|
||||
Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"
|
||||
}
|
||||
|
||||
@@ -176,18 +176,32 @@ function Invoke-WPFUIElements {
|
||||
$itemsControl.Items.Add($dockPanel) | Out-Null
|
||||
|
||||
$sync[$entryInfo.Name] = $checkBox
|
||||
|
||||
$sync[$entryInfo.Name].IsChecked = (Get-WinUtilToggleStatus $entryInfo.Name)
|
||||
|
||||
$sync[$entryInfo.Name].Add_Checked({
|
||||
[System.Object]$Sender = $args[0]
|
||||
Invoke-WinUtilTweaks $sender.name
|
||||
})
|
||||
|
||||
$sync[$entryInfo.Name].Add_Unchecked({
|
||||
[System.Object]$Sender = $args[0]
|
||||
Invoke-WinUtiltweaks $sender.name -undo $true
|
||||
})
|
||||
if ($entryInfo.Name -eq "WPFToggleFOSSHighlight") {
|
||||
if ($entryInfo.Checked -eq $true) {
|
||||
$sync[$entryInfo.Name].IsChecked = $true
|
||||
}
|
||||
|
||||
$sync[$entryInfo.Name].Add_Checked({
|
||||
Invoke-WPFButton -Button "WPFToggleFOSSHighlight"
|
||||
})
|
||||
$sync[$entryInfo.Name].Add_Unchecked({
|
||||
Invoke-WPFButton -Button "WPFToggleFOSSHighlight"
|
||||
})
|
||||
} else {
|
||||
$sync[$entryInfo.Name].IsChecked = (Get-WinUtilToggleStatus $entryInfo.Name)
|
||||
|
||||
$sync[$entryInfo.Name].Add_Checked({
|
||||
[System.Object]$Sender = $args[0]
|
||||
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $Sender.name
|
||||
Invoke-WinUtilTweaks $Sender.name
|
||||
})
|
||||
|
||||
$sync[$entryInfo.Name].Add_Unchecked({
|
||||
[System.Object]$Sender = $args[0]
|
||||
Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $Sender.name
|
||||
Invoke-WinUtiltweaks $Sender.name -undo $true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
"ToggleButton" {
|
||||
@@ -355,6 +369,16 @@ function Invoke-WPFUIElements {
|
||||
|
||||
$itemsControl.Items.Add($horizontalStackPanel) | Out-Null
|
||||
$sync[$entryInfo.Name] = $checkBox
|
||||
|
||||
$sync[$entryInfo.Name].Add_Checked({
|
||||
[System.Object]$Sender = $args[0]
|
||||
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $Sender.name
|
||||
})
|
||||
|
||||
$sync[$entryInfo.Name].Add_Unchecked({
|
||||
[System.Object]$Sender = $args[0]
|
||||
Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkbox $Sender.name
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ function Invoke-WPFtweaksbutton {
|
||||
return
|
||||
}
|
||||
|
||||
$Tweaks = (Get-WinUtilCheckBoxes)["WPFTweaks"]
|
||||
$Tweaks = $sync.selectedTweaks
|
||||
|
||||
Set-WinUtilDNS -DNSProvider $sync["WPFchangedns"].text
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ function Invoke-WPFundoall {
|
||||
return
|
||||
}
|
||||
|
||||
$tweaks = (Get-WinUtilCheckBoxes)["WPFtweaks"]
|
||||
$tweaks = $sync.selectedTweaks
|
||||
|
||||
if ($tweaks.count -eq 0) {
|
||||
$msg = "Please check the tweaks you wish to undo."
|
||||
|
||||
@@ -40,6 +40,9 @@ $sync.configs = @{}
|
||||
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
|
||||
$sync.ProcessRunning = $false
|
||||
$sync.selectedApps = [System.Collections.Generic.List[string]]::new()
|
||||
$sync.selectedTweaks = [System.Collections.Generic.List[string]]::new()
|
||||
$sync.selectedToggles = [System.Collections.Generic.List[string]]::new()
|
||||
$sync.selectedFeatures = [System.Collections.Generic.List[string]]::new()
|
||||
$sync.currentTab = "Install"
|
||||
$sync.selectedAppsStackPanel
|
||||
$sync.selectedAppsPopup
|
||||
|
||||
100
tools/devdocs-generator.md
Normal file
100
tools/devdocs-generator.md
Normal file
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: "Dev Docs Generator"
|
||||
description: "How the devdocs-generator.ps1 script works"
|
||||
---
|
||||
|
||||
# Dev Docs Generator
|
||||
|
||||
The `devdocs-generator.ps1` script automatically generates Hugo-compatible markdown files for the development documentation. It pulls content directly from the JSON config files and PowerShell function files so the docs never go out of sync.
|
||||
|
||||
## When Does It Run?
|
||||
|
||||
- Automatically in CI via the GitHub Actions `docs.yaml` workflow before Hugo builds the site
|
||||
- Triggered when any of these change: `docs/**`, `config/tweaks.json`, `config/feature.json`, `functions/**`
|
||||
- Can also be run manually with `workflow_dispatch`
|
||||
|
||||
## What Does It Do?
|
||||
|
||||
### 1. Loads the Data
|
||||
|
||||
- Reads `config/tweaks.json` and `config/feature.json`
|
||||
- Reads all `.ps1` function files from `functions/public/` and `functions/private/`
|
||||
- Parses `Invoke-WPFButton.ps1` to build a mapping of button names to their function names
|
||||
|
||||
### 2. Updates Links in JSON
|
||||
|
||||
- Adds or updates a `"link"` property on every entry in both JSON config files
|
||||
- Each link points to that entry's documentation page on the Hugo site
|
||||
|
||||
### 3. Cleans Up Old Docs
|
||||
|
||||
- Deletes all `.md` files (except `_index.md`) from `docs/content/dev/tweaks/` and `docs/content/dev/features/`
|
||||
- This prevents duplicate or orphaned files from previous runs
|
||||
|
||||
### 4. Generates Tweak Documentation
|
||||
|
||||
For each entry in `tweaks.json` that belongs to a documented category:
|
||||
|
||||
- **Button type** entries get the mapped PowerShell function file embedded
|
||||
- **All other types** get the raw JSON snippet embedded with correct line numbers from the source file
|
||||
- Entries with **registry changes** get a Registry Changes section added
|
||||
- Entries with **services** get the `Set-WinUtilService.ps1` function appended
|
||||
|
||||
### 5. Generates Feature Documentation
|
||||
|
||||
For each entry in `feature.json` that belongs to a documented category:
|
||||
|
||||
- **Fixes and Legacy Windows Panels** get the mapped PowerShell function file embedded
|
||||
- **Features** get the raw JSON snippet embedded with correct line numbers
|
||||
|
||||
### 6. Output Format
|
||||
|
||||
- Every `.md` file gets Hugo frontmatter with `title` and `description`
|
||||
- Code blocks use Hugo syntax with filename labels and line numbers
|
||||
- Files are organized into category subdirectories matching the JSON `category` field
|
||||
|
||||
## Documented Categories
|
||||
|
||||
The script generates docs for entries in these categories:
|
||||
|
||||
- Essential Tweaks
|
||||
- z__Advanced Tweaks - CAUTION
|
||||
- Customize Preferences
|
||||
- Performance Plans
|
||||
- Features
|
||||
- Fixes
|
||||
- Legacy Windows Panels
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
docs/content/dev/
|
||||
tweaks/
|
||||
Essential-Tweaks/
|
||||
z--Advanced-Tweaks---CAUTION/
|
||||
Customize-Preferences/
|
||||
Performance-Plans/
|
||||
features/
|
||||
Features/
|
||||
Fixes/
|
||||
Legacy-Windows-Panels/
|
||||
```
|
||||
|
||||
## How File Names Are Derived
|
||||
|
||||
The script strips common prefixes from the JSON key names using the pattern `WPF(WinUtil|Toggle|Features?|Tweaks?|Panel|Fix(es)?)?`. For example:
|
||||
|
||||
| JSON Key | Generated File |
|
||||
|---|---|
|
||||
| `WPFTweaksHiber` | `Hiber.md` |
|
||||
| `WPFTweaksDeBloat` | `DeBloat.md` |
|
||||
| `WPFFeatureshyperv` | `hyperv.md` |
|
||||
| `WPFPanelDISM` | `DISM.md` |
|
||||
|
||||
## Key Points
|
||||
|
||||
- The JSON config files are the single source of truth
|
||||
- Manual edits to generated `.md` files will be overwritten on the next run
|
||||
- The script does not touch `_index.md` files or `architecture.md`
|
||||
- Category directories are created automatically if they don't exist
|
||||
- The `"link"` property added to JSON entries is excluded from the displayed code blocks
|
||||
@@ -242,7 +242,7 @@ foreach ($itemName in $tweakNames) {
|
||||
|
||||
# Hugo frontmatter
|
||||
$title = $item.Content -replace '"', '\"'
|
||||
$content = "---`r`ntitle: `"$title`"`r`ndescription: `"`"`r`n---`r`n"
|
||||
$content = "---`r`ntitle: `"$title`"`r`ndescription: `"`"`r`n---`r`n`r`n"
|
||||
|
||||
if ($item.Type -eq "Button") {
|
||||
# Button-type tweak: embed the mapped PowerShell function
|
||||
@@ -315,7 +315,7 @@ foreach ($itemName in $featureNames) {
|
||||
}
|
||||
|
||||
$title = $item.Content -replace '"', '\"'
|
||||
$content = "---`r`ntitle: `"$title`"`r`ndescription: `"`"`r`n---`r`n"
|
||||
$content = "---`r`ntitle: `"$title`"`r`ndescription: `"`"`r`n---`r`n`r`n"
|
||||
|
||||
if ($item.category -eq "Fixes" -or $item.category -eq "Legacy Windows Panels") {
|
||||
# Embed the PowerShell function file
|
||||
|
||||
Reference in New Issue
Block a user