mirror of
https://github.com/ChrisTitusTech/winutil
synced 2026-04-06 14:48:31 +00:00
Compare commits
9 Commits
5eec99df1c
...
349889b194
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
349889b194 | ||
|
|
c619f3a830 | ||
|
|
d005a225a2 | ||
|
|
e79e946e76 | ||
|
|
3b957e1a77 | ||
|
|
d078d67b1d | ||
|
|
191fe95572 | ||
|
|
d10c9413ac | ||
|
|
e93753e5c9 |
@@ -1,5 +1,4 @@
|
|||||||
param (
|
param (
|
||||||
[switch]$Debug,
|
|
||||||
[switch]$Run,
|
[switch]$Run,
|
||||||
[string]$Arguments
|
[string]$Arguments
|
||||||
)
|
)
|
||||||
@@ -106,17 +105,10 @@ $xaml
|
|||||||
|
|
||||||
$script_content.Add($(Get-Content "scripts\main.ps1"))
|
$script_content.Add($(Get-Content "scripts\main.ps1"))
|
||||||
|
|
||||||
if ($Debug) {
|
|
||||||
Update-Progress "Writing debug files" 95
|
|
||||||
$appXamlContent | Out-File -FilePath "xaml\inputApp.xaml" -Encoding ascii
|
|
||||||
$tweaksXamlContent | Out-File -FilePath "xaml\inputTweaks.xaml" -Encoding ascii
|
|
||||||
$featuresXamlContent | Out-File -FilePath "xaml\inputFeatures.xaml" -Encoding ascii
|
|
||||||
} else {
|
|
||||||
Update-Progress "Removing temporary files" 99
|
Update-Progress "Removing temporary files" 99
|
||||||
Remove-Item "xaml\inputApp.xaml" -ErrorAction SilentlyContinue
|
Remove-Item "xaml\inputApp.xaml" -ErrorAction SilentlyContinue
|
||||||
Remove-Item "xaml\inputTweaks.xaml" -ErrorAction SilentlyContinue
|
Remove-Item "xaml\inputTweaks.xaml" -ErrorAction SilentlyContinue
|
||||||
Remove-Item "xaml\inputFeatures.xaml" -ErrorAction SilentlyContinue
|
Remove-Item "xaml\inputFeatures.xaml" -ErrorAction SilentlyContinue
|
||||||
}
|
|
||||||
|
|
||||||
Set-Content -Path "$scriptname" -Value ($script_content -join "`r`n") -Encoding ascii
|
Set-Content -Path "$scriptname" -Value ($script_content -join "`r`n") -Encoding ascii
|
||||||
Write-Progress -Activity "Compiling" -Completed
|
Write-Progress -Activity "Compiling" -Completed
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ You'll see a new file named `winutil.ps1`, which's created by `Compile.ps1` scri
|
|||||||
|
|
||||||
These are the sponsors that help keep this project alive with monthly contributions.
|
These are the sponsors that help keep this project alive with monthly contributions.
|
||||||
|
|
||||||
<!-- sponsors --><a href="https://github.com/dwelfusius"><img src="https://github.com/dwelfusius.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/mews-se"><img src="https://github.com/mews-se.png" width="60px" alt="User avatar: Martin Stockzell" /></a><a href="https://github.com/jdiegmueller"><img src="https://github.com/jdiegmueller.png" width="60px" alt="User avatar: Jason A. Diegmueller" /></a><a href="https://github.com/robertsandrock"><img src="https://github.com/robertsandrock.png" width="60px" alt="User avatar: RMS" /></a><a href="https://github.com/KenichiQaz"><img src="https://github.com/KenichiQaz.png" width="60px" alt="User avatar: Stefan" /></a><a href="https://github.com/paulsheets"><img src="https://github.com/paulsheets.png" width="60px" alt="User avatar: Paul" /></a><a href="https://github.com/djones369"><img src="https://github.com/djones369.png" width="60px" alt="User avatar: Dave J (WhamGeek)" /></a><a href="https://github.com/anthonymendez"><img src="https://github.com/anthonymendez.png" width="60px" alt="User avatar: Anthony Mendez" /></a><a href="https://github.com/FatBastard0"><img src="https://github.com/FatBastard0.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DursleyGuy"><img src="https://github.com/DursleyGuy.png" width="60px" alt="User avatar: DursleyGuy" /></a><a href="https://github.com/quaszi"><img src="https://github.com/quaszi.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DwayneTheRockLobster1"><img src="https://github.com/DwayneTheRockLobster1.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/KieraKujisawa"><img src="https://github.com/KieraKujisawa.png" width="60px" alt="User avatar: Kiera Meredith" /></a><a href="https://github.com/andrewpayne68"><img src="https://github.com/andrewpayne68.png" width="60px" alt="User avatar: Andrew P" /></a><!-- sponsors -->
|
<!-- sponsors --><a href="https://github.com/dwelfusius"><img src="https://github.com/dwelfusius.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/mews-se"><img src="https://github.com/mews-se.png" width="60px" alt="User avatar: Martin Stockzell" /></a><a href="https://github.com/jdiegmueller"><img src="https://github.com/jdiegmueller.png" width="60px" alt="User avatar: Jason A. Diegmueller" /></a><a href="https://github.com/robertsandrock"><img src="https://github.com/robertsandrock.png" width="60px" alt="User avatar: RMS" /></a><a href="https://github.com/KenichiQaz"><img src="https://github.com/KenichiQaz.png" width="60px" alt="User avatar: Stefan" /></a><a href="https://github.com/paulsheets"><img src="https://github.com/paulsheets.png" width="60px" alt="User avatar: Paul" /></a><a href="https://github.com/djones369"><img src="https://github.com/djones369.png" width="60px" alt="User avatar: Dave J (WhamGeek)" /></a><a href="https://github.com/anthonymendez"><img src="https://github.com/anthonymendez.png" width="60px" alt="User avatar: Anthony Mendez" /></a><a href="https://github.com/FatBastard0"><img src="https://github.com/FatBastard0.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DursleyGuy"><img src="https://github.com/DursleyGuy.png" width="60px" alt="User avatar: DursleyGuy" /></a><a href="https://github.com/quaszi"><img src="https://github.com/quaszi.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DwayneTheRockLobster1"><img src="https://github.com/DwayneTheRockLobster1.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/KieraKujisawa"><img src="https://github.com/KieraKujisawa.png" width="60px" alt="User avatar: Kiera Meredith" /></a><a href="https://github.com/andrewpayne68"><img src="https://github.com/andrewpayne68.png" width="60px" alt="User avatar: Andrew P" /></a><a href="https://github.com/nathanzilgo"><img src="https://github.com/nathanzilgo.png" width="60px" alt="User avatar: Nathan Fernandes Pedroza" /></a><!-- sponsors -->
|
||||||
|
|
||||||
## 🏅 Thanks to all Contributors
|
## 🏅 Thanks to all Contributors
|
||||||
Thanks a lot for spending your time helping Winutil grow. Thanks a lot! Keep rocking 🍻.
|
Thanks a lot for spending your time helping Winutil grow. Thanks a lot! Keep rocking 🍻.
|
||||||
|
|||||||
@@ -496,6 +496,14 @@
|
|||||||
"link": "https://dotnet.microsoft.com/download/dotnet/9.0",
|
"link": "https://dotnet.microsoft.com/download/dotnet/9.0",
|
||||||
"winget": "Microsoft.DotNet.DesktopRuntime.9"
|
"winget": "Microsoft.DotNet.DesktopRuntime.9"
|
||||||
},
|
},
|
||||||
|
"dotnet10": {
|
||||||
|
"category": "Microsoft Tools",
|
||||||
|
"choco": "dotnet-10.0-runtime",
|
||||||
|
"content": ".NET Desktop Runtime 10",
|
||||||
|
"description": ".NET Desktop Runtime 10 is a runtime environment required for running applications developed with .NET 10.",
|
||||||
|
"link": "https://dotnet.microsoft.com/download/dotnet/10.0",
|
||||||
|
"winget": "Microsoft.DotNet.DesktopRuntime.10"
|
||||||
|
},
|
||||||
"dmt": {
|
"dmt": {
|
||||||
"winget": "GNE.DualMonitorTools",
|
"winget": "GNE.DualMonitorTools",
|
||||||
"choco": "dual-monitor-tools",
|
"choco": "dual-monitor-tools",
|
||||||
@@ -3226,5 +3234,23 @@
|
|||||||
"link": "https://zed.dev/",
|
"link": "https://zed.dev/",
|
||||||
"winget": "ZedIndustries.Zed",
|
"winget": "ZedIndustries.Zed",
|
||||||
"foss": true
|
"foss": true
|
||||||
|
},
|
||||||
|
"LLLVM": {
|
||||||
|
"category": "Development",
|
||||||
|
"choco": "llvm",
|
||||||
|
"winget": "LLVM.LLVM",
|
||||||
|
"description": "A collection of modular and reusable compiler and toolchain technologies.",
|
||||||
|
"content": "LLVM",
|
||||||
|
"link": "https://llvm.org",
|
||||||
|
"foss": true
|
||||||
|
},
|
||||||
|
"NASM": {
|
||||||
|
"category": "Development",
|
||||||
|
"choco": "nasm",
|
||||||
|
"winget": "NASM.NASM",
|
||||||
|
"description": "A powerful assembler for the x86 platform.",
|
||||||
|
"content": "NASM",
|
||||||
|
"link": "https://nasm.us",
|
||||||
|
"foss": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
"Description": ".NET and .NET Framework is a developer platform made up of tools, programming languages, and libraries for building many different types of applications.",
|
"Description": ".NET and .NET Framework is a developer platform made up of tools, programming languages, and libraries for building many different types of applications.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a010_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"NetFx4-AdvSrvs",
|
"NetFx4-AdvSrvs",
|
||||||
"NetFx3"
|
"NetFx3"
|
||||||
@@ -17,7 +16,6 @@
|
|||||||
"Description": "Hyper-V is a hardware virtualization product developed by Microsoft that allows users to create and manage virtual machines.",
|
"Description": "Hyper-V is a hardware virtualization product developed by Microsoft that allows users to create and manage virtual machines.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a011_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"Microsoft-Hyper-V-All"
|
"Microsoft-Hyper-V-All"
|
||||||
],
|
],
|
||||||
@@ -31,7 +29,6 @@
|
|||||||
"Description": "Enables legacy programs from previous versions of windows",
|
"Description": "Enables legacy programs from previous versions of windows",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a012_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"WindowsMediaPlayer",
|
"WindowsMediaPlayer",
|
||||||
"MediaPlayback",
|
"MediaPlayback",
|
||||||
@@ -46,7 +43,6 @@
|
|||||||
"Description": "Windows Subsystem for Linux is an optional feature of Windows that allows Linux programs to run natively on Windows without the need for a separate virtual machine or dual booting.",
|
"Description": "Windows Subsystem for Linux is an optional feature of Windows that allows Linux programs to run natively on Windows without the need for a separate virtual machine or dual booting.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a020_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"VirtualMachinePlatform",
|
"VirtualMachinePlatform",
|
||||||
"Microsoft-Windows-Subsystem-Linux"
|
"Microsoft-Windows-Subsystem-Linux"
|
||||||
@@ -59,7 +55,6 @@
|
|||||||
"Description": "Network File System (NFS) is a mechanism for storing files on a network.",
|
"Description": "Network File System (NFS) is a mechanism for storing files on a network.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a014_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"ServicesForNFS-ClientOnly",
|
"ServicesForNFS-ClientOnly",
|
||||||
"ClientForNFS-Infrastructure",
|
"ClientForNFS-Infrastructure",
|
||||||
@@ -79,7 +74,6 @@
|
|||||||
"Description": "Enables daily registry backup, previously disabled by Microsoft in Windows 10 1803.",
|
"Description": "Enables daily registry backup, previously disabled by Microsoft in Windows 10 1803.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a017_",
|
|
||||||
"feature": [],
|
"feature": [],
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"
|
"
|
||||||
@@ -97,7 +91,6 @@
|
|||||||
"Description": "Enables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.",
|
"Description": "Enables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a018_",
|
|
||||||
"feature": [],
|
"feature": [],
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"bcdedit /set bootmenupolicy legacy"
|
"bcdedit /set bootmenupolicy legacy"
|
||||||
@@ -109,7 +102,6 @@
|
|||||||
"Description": "Disables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.",
|
"Description": "Disables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a019_",
|
|
||||||
"feature": [],
|
"feature": [],
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"bcdedit /set bootmenupolicy standard"
|
"bcdedit /set bootmenupolicy standard"
|
||||||
@@ -121,7 +113,6 @@
|
|||||||
"Description": "Windows Sandbox is a lightweight virtual machine that provides a temporary desktop environment to safely run applications and programs in isolation.",
|
"Description": "Windows Sandbox is a lightweight virtual machine that provides a temporary desktop environment to safely run applications and programs in isolation.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a021_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"Containers-DisposableClientVM"
|
"Containers-DisposableClientVM"
|
||||||
],
|
],
|
||||||
@@ -131,54 +122,54 @@
|
|||||||
"Content": "Install Features",
|
"Content": "Install Features",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a060_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFFeatureInstall",
|
||||||
"link": "https://winutil.christitus.com/dev/features/features/install"
|
"link": "https://winutil.christitus.com/dev/features/features/install"
|
||||||
},
|
},
|
||||||
"WPFPanelAutologin": {
|
"WPFPanelAutologin": {
|
||||||
"Content": "Set Up Autologin",
|
"Content": "Set Up Autologin",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"Order": "a040_",
|
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFPanelAutologin",
|
||||||
"link": "https://winutil.christitus.com/dev/features/fixes/autologin"
|
"link": "https://winutil.christitus.com/dev/features/fixes/autologin"
|
||||||
},
|
},
|
||||||
"WPFFixesUpdate": {
|
"WPFFixesUpdate": {
|
||||||
"Content": "Reset Windows Update",
|
"Content": "Reset Windows Update",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a041_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFFixesUpdate",
|
||||||
"link": "https://winutil.christitus.com/dev/features/fixes/update"
|
"link": "https://winutil.christitus.com/dev/features/fixes/update"
|
||||||
},
|
},
|
||||||
"WPFFixesNetwork": {
|
"WPFFixesNetwork": {
|
||||||
"Content": "Reset Network",
|
"Content": "Reset Network",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"Order": "a042_",
|
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFFixesNetwork",
|
||||||
"link": "https://winutil.christitus.com/dev/features/fixes/network"
|
"link": "https://winutil.christitus.com/dev/features/fixes/network"
|
||||||
},
|
},
|
||||||
"WPFPanelDISM": {
|
"WPFPanelDISM": {
|
||||||
"Content": "System Corruption Scan",
|
"Content": "System Corruption Scan",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a043_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFSystemRepair",
|
||||||
"link": "https://winutil.christitus.com/dev/features/fixes/dism"
|
"link": "https://winutil.christitus.com/dev/features/fixes/dism"
|
||||||
},
|
},
|
||||||
"WPFFixesWinget": {
|
"WPFFixesWinget": {
|
||||||
"Content": "WinGet Reinstall",
|
"Content": "WinGet Reinstall",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a044_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFFixesWinget",
|
||||||
"link": "https://winutil.christitus.com/dev/features/fixes/winget"
|
"link": "https://winutil.christitus.com/dev/features/fixes/winget"
|
||||||
},
|
},
|
||||||
"WPFPanelControl": {
|
"WPFPanelControl": {
|
||||||
@@ -187,6 +178,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"control"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/control"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/control"
|
||||||
},
|
},
|
||||||
"WPFPanelComputer": {
|
"WPFPanelComputer": {
|
||||||
@@ -195,6 +189,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"compmgmt.msc"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/computer"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/computer"
|
||||||
},
|
},
|
||||||
"WPFPanelNetwork": {
|
"WPFPanelNetwork": {
|
||||||
@@ -203,6 +200,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"ncpa.cpl"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/network"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/network"
|
||||||
},
|
},
|
||||||
"WPFPanelPower": {
|
"WPFPanelPower": {
|
||||||
@@ -211,6 +211,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"powercfg.cpl"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/power"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/power"
|
||||||
},
|
},
|
||||||
"WPFPanelPrinter": {
|
"WPFPanelPrinter": {
|
||||||
@@ -219,6 +222,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"Start-Process 'shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}'"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/printer"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/printer"
|
||||||
},
|
},
|
||||||
"WPFPanelRegion": {
|
"WPFPanelRegion": {
|
||||||
@@ -227,6 +233,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"intl.cpl"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/region"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/region"
|
||||||
},
|
},
|
||||||
"WPFPanelRestore": {
|
"WPFPanelRestore": {
|
||||||
@@ -235,6 +244,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"rstrui.exe"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/restore"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/restore"
|
||||||
},
|
},
|
||||||
"WPFPanelSound": {
|
"WPFPanelSound": {
|
||||||
@@ -243,6 +255,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"mmsys.cpl"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/sound"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/sound"
|
||||||
},
|
},
|
||||||
"WPFPanelSystem": {
|
"WPFPanelSystem": {
|
||||||
@@ -251,6 +266,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"sysdm.cpl"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/system"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/system"
|
||||||
},
|
},
|
||||||
"WPFPanelTimedate": {
|
"WPFPanelTimedate": {
|
||||||
@@ -259,33 +277,36 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"timedate.cpl"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/timedate"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/timedate"
|
||||||
},
|
},
|
||||||
"WPFWinUtilInstallPSProfile": {
|
"WPFWinUtilInstallPSProfile": {
|
||||||
"Content": "Install CTT PowerShell Profile",
|
"Content": "Install CTT PowerShell Profile",
|
||||||
"category": "Powershell Profile Powershell 7+ Only",
|
"category": "Powershell Profile Powershell 7+ Only",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Order": "a083_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WinUtilInstallPSProfile",
|
||||||
"link": "https://winutil.christitus.com/dev/features/powershell-profile-powershell-7--only/installpsprofile"
|
"link": "https://winutil.christitus.com/dev/features/powershell-profile-powershell-7--only/installpsprofile"
|
||||||
},
|
},
|
||||||
"WPFWinUtilUninstallPSProfile": {
|
"WPFWinUtilUninstallPSProfile": {
|
||||||
"Content": "Uninstall CTT PowerShell Profile",
|
"Content": "Uninstall CTT PowerShell Profile",
|
||||||
"category": "Powershell Profile Powershell 7+ Only",
|
"category": "Powershell Profile Powershell 7+ Only",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Order": "a084_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WinUtilUninstallPSProfile",
|
||||||
"link": "https://winutil.christitus.com/dev/features/powershell-profile-powershell-7--only/uninstallpsprofile"
|
"link": "https://winutil.christitus.com/dev/features/powershell-profile-powershell-7--only/uninstallpsprofile"
|
||||||
},
|
},
|
||||||
"WPFWinUtilSSHServer": {
|
"WPFWinUtilSSHServer": {
|
||||||
"Content": "Enable OpenSSH Server",
|
"Content": "Enable OpenSSH Server",
|
||||||
"category": "Remote Access",
|
"category": "Remote Access",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Order": "a084_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFSSHServer",
|
||||||
"link": "https://winutil.christitus.com/dev/features/remote-access/sshserver"
|
"link": "https://winutil.christitus.com/dev/features/remote-access/sshserver"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1907,7 +1907,7 @@
|
|||||||
},
|
},
|
||||||
"WPFTweaksRazerBlock": {
|
"WPFTweaksRazerBlock": {
|
||||||
"Content": "Block Razer Software Installs",
|
"Content": "Block Razer Software Installs",
|
||||||
"Description": "Blocks ALL Razer Software installations. The hardware works fine without any software. WARNING: this will also block all Windows third-party driver installations.",
|
"Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.",
|
||||||
"category": "z__Advanced Tweaks - CAUTION",
|
"category": "z__Advanced Tweaks - CAUTION",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"registry": [
|
"registry": [
|
||||||
|
|||||||
@@ -27,6 +27,14 @@ If you are still having issues, try using a **VPN**, or changing your **DNS prov
|
|||||||
| Cloudflare | `1.1.1.1` | `1.0.0.1` |
|
| Cloudflare | `1.1.1.1` | `1.0.0.1` |
|
||||||
| Google | `8.8.8.8` | `8.8.4.4` |
|
| Google | `8.8.8.8` | `8.8.4.4` |
|
||||||
|
|
||||||
|
### Script Won't Run
|
||||||
|
|
||||||
|
If your PowerShell session is running in **Constrained Language Mode**, some scripts and commands may fail to execute. To check the current language mode, run:
|
||||||
|
```powershell
|
||||||
|
$ExecutionContext.SessionState.LanguageMode
|
||||||
|
```
|
||||||
|
If it returns `ConstrainedLanguage`, you may need to switch to `FullLanguage` mode or run the script in a session with administrative privileges. Be aware that some security policies may enforce Constrained Language Mode, especially in corporate or managed environments.
|
||||||
|
|
||||||
### Script blocked by Execution Policy
|
### Script blocked by Execution Policy
|
||||||
|
|
||||||
1. Ensure you are running PowerShell as admin: Press `Windows Key`+`X` and select _PowerShell (Admin)_ in Windows 10, or `Windows Terminal (Admin)` in Windows 11.
|
1. Ensure you are running PowerShell as admin: Press `Windows Key`+`X` and select _PowerShell (Admin)_ in Windows 10, or `Windows Terminal (Admin)` in Windows 11.
|
||||||
|
|||||||
@@ -42,3 +42,11 @@ toc: false
|
|||||||
### Features
|
### Features
|
||||||
|
|
||||||
{{< autolinks section="dev/features/features" >}}
|
{{< autolinks section="dev/features/features" >}}
|
||||||
|
|
||||||
|
### Remote Access
|
||||||
|
|
||||||
|
{{< autolinks section="dev/features/remote-access" >}}
|
||||||
|
|
||||||
|
### Powershell Profile Powershell 7+ Only
|
||||||
|
|
||||||
|
{{< autolinks section="dev/features/powershell-profile-powershell-7--only" >}}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: "Powershell Profile Powershell 7+ Only"
|
||||||
|
weight: 5
|
||||||
|
toc: false
|
||||||
|
---
|
||||||
|
|
||||||
|
{{< autolinks section="dev/features/powershell-profile-powershell-7--only" >}}
|
||||||
7
docs/content/dev/features/Remote-Access/_index.md
Normal file
7
docs/content/dev/features/Remote-Access/_index.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: "Remote Access"
|
||||||
|
weight: 4
|
||||||
|
toc: false
|
||||||
|
---
|
||||||
|
|
||||||
|
{{< autolinks section="dev/features/remote-access" >}}
|
||||||
@@ -15,3 +15,11 @@ toc: false
|
|||||||
### Features
|
### Features
|
||||||
|
|
||||||
{{< autolinks section="dev/features/features" >}}
|
{{< autolinks section="dev/features/features" >}}
|
||||||
|
|
||||||
|
### Remote Access
|
||||||
|
|
||||||
|
{{< autolinks section="dev/features/remote-access" >}}
|
||||||
|
|
||||||
|
### Powershell Profile Powershell 7+ Only
|
||||||
|
|
||||||
|
{{< autolinks section="dev/features/powershell-profile-powershell-7--only" >}}
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ function Get-WinUtilSelectedPackages
|
|||||||
)
|
)
|
||||||
|
|
||||||
if ($PackageList.count -eq 1) {
|
if ($PackageList.count -eq 1) {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }
|
||||||
} else {
|
} else {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }
|
||||||
}
|
}
|
||||||
|
|
||||||
$packages = [System.Collections.Hashtable]::new()
|
$packages = [System.Collections.Hashtable]::new()
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ function Hide-WPFInstallAppBusy {
|
|||||||
Hides the busy overlay in the install app area of the WPF form.
|
Hides the busy overlay in the install app area of the WPF form.
|
||||||
This is used to indicate that an install or uninstall has finished.
|
This is used to indicate that an install or uninstall has finished.
|
||||||
#>
|
#>
|
||||||
$sync.form.Dispatcher.Invoke([action]{
|
Invoke-WPFUIThread -ScriptBlock {
|
||||||
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Collapsed
|
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Collapsed
|
||||||
$sync.InstallAppAreaBorder.IsEnabled = $true
|
$sync.InstallAppAreaBorder.IsEnabled = $true
|
||||||
$sync.InstallAppAreaScrollViewer.Effect.Radius = 0
|
$sync.InstallAppAreaScrollViewer.Effect.Radius = 0
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ function Install-WinUtilProgramChoco {
|
|||||||
[int]$totalPrograms
|
[int]$totalPrograms
|
||||||
)
|
)
|
||||||
$progressState = if ($currentIndex -eq $totalPrograms) { "Normal" } else { "Error" }
|
$progressState = if ($currentIndex -eq $totalPrograms) { "Normal" } else { "Error" }
|
||||||
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state $progressState -value ($currentIndex / $totalPrograms) })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state $progressState -value ($currentIndex / $totalPrograms) }
|
||||||
}
|
}
|
||||||
|
|
||||||
function Install-ChocoPackage {
|
function Install-ChocoPackage {
|
||||||
@@ -234,7 +234,7 @@ function Install-WinUtilProgramChoco {
|
|||||||
for ($currentIndex = 0; $currentIndex -lt $totalPrograms; $currentIndex++) {
|
for ($currentIndex = 0; $currentIndex -lt $totalPrograms; $currentIndex++) {
|
||||||
$Program = $Programs[$currentIndex]
|
$Program = $Programs[$currentIndex]
|
||||||
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($currentIndex / $totalPrograms * 100)
|
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($currentIndex / $totalPrograms * 100)
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($currentIndex / $totalPrograms)})
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($currentIndex / $totalPrograms)}
|
||||||
|
|
||||||
switch ($Action) {
|
switch ($Action) {
|
||||||
"Install" {
|
"Install" {
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ Function Install-WinUtilProgramWinget {
|
|||||||
$Program = $Programs[$i]
|
$Program = $Programs[$i]
|
||||||
$result = $false
|
$result = $false
|
||||||
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($i / $count * 100)
|
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($i / $count * 100)
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i / $count)})
|
Invoke-WPFUIThread -ScriptBlock{ Set-WinUtilTaskbaritem -value ($i / $count)}
|
||||||
|
|
||||||
$result = switch ($Action) {
|
$result = switch ($Action) {
|
||||||
"Install" {Invoke-Install -Program $Program}
|
"Install" {Invoke-Install -Program $Program}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ function Invoke-WinUtilExplorerUpdate {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if ($action -eq "refresh") {
|
if ($action -eq "refresh") {
|
||||||
Invoke-WPFRunspace -DebugPreference $DebugPreference -ScriptBlock {
|
Invoke-WPFRunspace -ScriptBlock {
|
||||||
# Define the Win32 type only if it doesn't exist
|
# Define the Win32 type only if it doesn't exist
|
||||||
if (-not ([System.Management.Automation.PSTypeName]'Win32').Type) {
|
if (-not ([System.Management.Automation.PSTypeName]'Win32').Type) {
|
||||||
Add-Type -TypeDefinition @"
|
Add-Type -TypeDefinition @"
|
||||||
|
|||||||
@@ -10,46 +10,40 @@ function Invoke-WinUtilFeatureInstall {
|
|||||||
$CheckBox
|
$CheckBox
|
||||||
)
|
)
|
||||||
|
|
||||||
$x = 0
|
if($sync.configs.feature.$CheckBox.feature) {
|
||||||
|
Foreach( $feature in $sync.configs.feature.$CheckBox.feature ) {
|
||||||
$CheckBox | ForEach-Object {
|
|
||||||
if($sync.configs.feature.$psitem.feature) {
|
|
||||||
Foreach( $feature in $sync.configs.feature.$psitem.feature ) {
|
|
||||||
try {
|
try {
|
||||||
Write-Host "Installing $feature"
|
Write-Host "Installing $feature"
|
||||||
Enable-WindowsOptionalFeature -Online -FeatureName $feature -All -NoRestart
|
Enable-WindowsOptionalFeature -Online -FeatureName $feature -All -NoRestart
|
||||||
} catch {
|
} catch {
|
||||||
if ($psitem.Exception.Message -like "*requires elevation*") {
|
if ($CheckBox.Exception.Message -like "*requires elevation*") {
|
||||||
Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?"
|
Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?"
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" }
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Write-Warning "Unable to Install $feature due to unhandled exception"
|
Write-Warning "Unable to Install $feature due to unhandled exception"
|
||||||
Write-Warning $psitem.Exception.StackTrace
|
Write-Warning $CheckBox.Exception.StackTrace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($sync.configs.feature.$psitem.InvokeScript) {
|
if($sync.configs.feature.$CheckBox.InvokeScript) {
|
||||||
Foreach( $script in $sync.configs.feature.$psitem.InvokeScript ) {
|
Foreach( $script in $sync.configs.feature.$CheckBox.InvokeScript ) {
|
||||||
try {
|
try {
|
||||||
$Scriptblock = [scriptblock]::Create($script)
|
$Scriptblock = [scriptblock]::Create($script)
|
||||||
|
|
||||||
Write-Host "Running Script for $psitem"
|
Write-Host "Running Script for $CheckBox"
|
||||||
Invoke-Command $scriptblock -ErrorAction stop
|
Invoke-Command $scriptblock -ErrorAction stop
|
||||||
} catch {
|
} catch {
|
||||||
if ($psitem.Exception.Message -like "*requires elevation*") {
|
if ($CheckBox.Exception.Message -like "*requires elevation*") {
|
||||||
Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?"
|
Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?"
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" }
|
||||||
} else {
|
} else {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" }
|
||||||
Write-Warning "Unable to Install $feature due to unhandled exception"
|
Write-Warning "Unable to Install $feature due to unhandled exception"
|
||||||
Write-Warning $psitem.Exception.StackTrace
|
Write-Warning $CheckBox.Exception.StackTrace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$X++
|
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$CheckBox.Count) })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
function Invoke-WinUtilGPU {
|
|
||||||
$gpuInfo = Get-CimInstance Win32_VideoController
|
|
||||||
|
|
||||||
# GPUs to blacklist from using Demanding Theming
|
|
||||||
$lowPowerGPUs = (
|
|
||||||
"*NVIDIA GeForce*M*",
|
|
||||||
"*NVIDIA GeForce*Laptop*",
|
|
||||||
"*NVIDIA GeForce*GT*",
|
|
||||||
"*AMD Radeon(TM)*",
|
|
||||||
"*Intel(R) HD Graphics*",
|
|
||||||
"*UHD*"
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
foreach ($gpu in $gpuInfo) {
|
|
||||||
foreach ($gpuPattern in $lowPowerGPUs) {
|
|
||||||
if ($gpu.Name -like $gpuPattern) {
|
|
||||||
return $false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $true
|
|
||||||
}
|
|
||||||
@@ -14,11 +14,15 @@ function Set-WinUtilProgressbar{
|
|||||||
[int]$Percent
|
[int]$Percent
|
||||||
)
|
)
|
||||||
|
|
||||||
$sync.form.Dispatcher.Invoke([action]{$sync.progressBarTextBlock.Text = $label})
|
if($PARAM_NOUI) {
|
||||||
$sync.form.Dispatcher.Invoke([action]{$sync.progressBarTextBlock.ToolTip = $label})
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.Text = $label}
|
||||||
|
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.ToolTip = $label}
|
||||||
if ($percent -lt 5 ) {
|
if ($percent -lt 5 ) {
|
||||||
$percent = 5 # Ensure the progress bar is not empty, as it looks weird
|
$percent = 5 # Ensure the progress bar is not empty, as it looks weird
|
||||||
}
|
}
|
||||||
$sync.form.Dispatcher.Invoke([action]{ $sync.ProgressBar.Value = $percent})
|
Invoke-WPFUIThread -ScriptBlock { $sync.ProgressBar.Value = $percent}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ function Show-WPFInstallAppBusy {
|
|||||||
param (
|
param (
|
||||||
$text = "Installing apps..."
|
$text = "Installing apps..."
|
||||||
)
|
)
|
||||||
$sync.form.Dispatcher.Invoke([action]{
|
Invoke-WPFUIThread -ScriptBlock {
|
||||||
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Visible
|
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Visible
|
||||||
$sync.InstallAppAreaOverlay.Width = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
|
$sync.InstallAppAreaOverlay.Width = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
|
||||||
$sync.InstallAppAreaOverlay.Height = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
|
$sync.InstallAppAreaOverlay.Height = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
|
||||||
$sync.InstallAppAreaOverlayText.Text = $text
|
$sync.InstallAppAreaOverlayText.Text = $text
|
||||||
$sync.InstallAppAreaBorder.IsEnabled = $false
|
$sync.InstallAppAreaBorder.IsEnabled = $false
|
||||||
$sync.InstallAppAreaScrollViewer.Effect.Radius = 5
|
$sync.InstallAppAreaScrollViewer.Effect.Radius = 5
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,31 @@ function Invoke-WPFButton {
|
|||||||
Set-WinUtilProgressBar -label "" -percent 0
|
Set-WinUtilProgressBar -label "" -percent 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check if button is defined in feature config with function or InvokeScript
|
||||||
|
if ($sync.configs.feature.$Button) {
|
||||||
|
$buttonConfig = $sync.configs.feature.$Button
|
||||||
|
|
||||||
|
# If button has a function defined, call it
|
||||||
|
if ($buttonConfig.function) {
|
||||||
|
$functionName = $buttonConfig.function
|
||||||
|
if (Get-Command $functionName -ErrorAction SilentlyContinue) {
|
||||||
|
& $functionName
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# If button has InvokeScript defined, execute the scripts
|
||||||
|
if ($buttonConfig.InvokeScript -and $buttonConfig.InvokeScript.Count -gt 0) {
|
||||||
|
foreach ($script in $buttonConfig.InvokeScript) {
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($script)) {
|
||||||
|
Invoke-Expression $script
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fallback to hard-coded switch for buttons not in feature.json
|
||||||
Switch -Wildcard ($Button) {
|
Switch -Wildcard ($Button) {
|
||||||
"WPFTab?BT" {Invoke-WPFTab $Button}
|
"WPFTab?BT" {Invoke-WPFTab $Button}
|
||||||
"WPFInstall" {Invoke-WPFInstall}
|
"WPFInstall" {Invoke-WPFInstall}
|
||||||
@@ -34,34 +59,14 @@ function Invoke-WPFButton {
|
|||||||
"WPFAddUltPerf" {Invoke-WPFUltimatePerformance -State "Enable"}
|
"WPFAddUltPerf" {Invoke-WPFUltimatePerformance -State "Enable"}
|
||||||
"WPFRemoveUltPerf" {Invoke-WPFUltimatePerformance -State "Disable"}
|
"WPFRemoveUltPerf" {Invoke-WPFUltimatePerformance -State "Disable"}
|
||||||
"WPFundoall" {Invoke-WPFundoall}
|
"WPFundoall" {Invoke-WPFundoall}
|
||||||
"WPFFeatureInstall" {Invoke-WPFFeatureInstall}
|
|
||||||
"WPFPanelDISM" {Invoke-WPFSystemRepair}
|
|
||||||
"WPFPanelAutologin" {Invoke-WPFPanelAutologin}
|
|
||||||
"WPFPanelComputer" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelControl" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelNetwork" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelPower" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelPrinter" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelRegion" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelRestore" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelSound" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelSystem" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelTimedate" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelUser" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFUpdatesdefault" {Invoke-WPFUpdatesdefault}
|
"WPFUpdatesdefault" {Invoke-WPFUpdatesdefault}
|
||||||
"WPFFixesUpdate" {Invoke-WPFFixesUpdate}
|
|
||||||
"WPFFixesWinget" {Invoke-WPFFixesWinget}
|
|
||||||
"WPFRunAdobeCCCleanerTool" {Invoke-WPFRunAdobeCCCleanerTool}
|
"WPFRunAdobeCCCleanerTool" {Invoke-WPFRunAdobeCCCleanerTool}
|
||||||
"WPFFixesNetwork" {Invoke-WPFFixesNetwork}
|
|
||||||
"WPFUpdatesdisable" {Invoke-WPFUpdatesdisable}
|
"WPFUpdatesdisable" {Invoke-WPFUpdatesdisable}
|
||||||
"WPFUpdatessecurity" {Invoke-WPFUpdatessecurity}
|
"WPFUpdatessecurity" {Invoke-WPFUpdatessecurity}
|
||||||
"WPFWinUtilShortcut" {Invoke-WPFShortcut -ShortcutToAdd "WinUtil" -RunAsAdmin $true}
|
"WPFWinUtilShortcut" {Invoke-WPFShortcut -ShortcutToAdd "WinUtil" -RunAsAdmin $true}
|
||||||
"WPFGetInstalled" {Invoke-WPFGetInstalled -CheckBox "winget"}
|
"WPFGetInstalled" {Invoke-WPFGetInstalled -CheckBox "winget"}
|
||||||
"WPFGetInstalledTweaks" {Invoke-WPFGetInstalled -CheckBox "tweaks"}
|
"WPFGetInstalledTweaks" {Invoke-WPFGetInstalled -CheckBox "tweaks"}
|
||||||
"WPFCloseButton" {Invoke-WPFCloseButton}
|
"WPFCloseButton" {$sync.Form.Close(); Write-Host "Bye bye!"}
|
||||||
"WPFWinUtilInstallPSProfile" {Invoke-WinUtilInstallPSProfile}
|
|
||||||
"WPFWinUtilUninstallPSProfile" {Invoke-WinUtilUninstallPSProfile}
|
|
||||||
"WPFWinUtilSSHServer" {Invoke-WPFSSHServer}
|
|
||||||
"WPFselectedAppsButton" {$sync.selectedAppsPopup.IsOpen = -not $sync.selectedAppsPopup.IsOpen}
|
"WPFselectedAppsButton" {$sync.selectedAppsPopup.IsOpen = -not $sync.selectedAppsPopup.IsOpen}
|
||||||
"WPFToggleFOSSHighlight" {
|
"WPFToggleFOSSHighlight" {
|
||||||
if ($sync.WPFToggleFOSSHighlight.IsChecked) {
|
if ($sync.WPFToggleFOSSHighlight.IsChecked) {
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
function Invoke-WPFCloseButton {
|
|
||||||
|
|
||||||
<#
|
|
||||||
|
|
||||||
.SYNOPSIS
|
|
||||||
Close application
|
|
||||||
|
|
||||||
.PARAMETER Button
|
|
||||||
#>
|
|
||||||
$sync["Form"].Close()
|
|
||||||
Write-Host "Bye bye!"
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
function Invoke-WPFControlPanel {
|
|
||||||
<#
|
|
||||||
|
|
||||||
.SYNOPSIS
|
|
||||||
Opens the requested legacy panel
|
|
||||||
|
|
||||||
.PARAMETER Panel
|
|
||||||
The panel to open
|
|
||||||
|
|
||||||
#>
|
|
||||||
param($Panel)
|
|
||||||
|
|
||||||
switch ($Panel) {
|
|
||||||
"WPFPanelControl" {control}
|
|
||||||
"WPFPanelComputer" {compmgmt.msc}
|
|
||||||
"WPFPanelNetwork" {ncpa.cpl}
|
|
||||||
"WPFPanelPower" {powercfg.cpl}
|
|
||||||
"WPFPanelPrinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
|
|
||||||
"WPFPanelRegion" {intl.cpl}
|
|
||||||
"WPFPanelRestore" {rstrui.exe}
|
|
||||||
"WPFPanelSound" {mmsys.cpl}
|
|
||||||
"WPFPanelSystem" {sysdm.cpl}
|
|
||||||
"WPFPanelTimedate" {timedate.cpl}
|
|
||||||
"WPFPanelUser" {control userpasswords2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,21 +12,25 @@ function Invoke-WPFFeatureInstall {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$handle = Invoke-WPFRunspace -ScriptBlock {
|
||||||
$Features = $sync.selectedFeatures
|
$Features = $sync.selectedFeatures
|
||||||
|
|
||||||
Invoke-WPFRunspace -ArgumentList $Features -DebugPreference $DebugPreference -ScriptBlock {
|
|
||||||
param($Features, $DebugPreference)
|
|
||||||
$sync.ProcessRunning = $true
|
$sync.ProcessRunning = $true
|
||||||
if ($Features.count -eq 1) {
|
if ($Features.count -eq 1) {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }
|
||||||
} else {
|
} else {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }
|
||||||
}
|
}
|
||||||
|
|
||||||
Invoke-WinUtilFeatureInstall $Features
|
$x = 0
|
||||||
|
|
||||||
|
$Features | ForEach-Object {
|
||||||
|
Invoke-WinUtilFeatureInstall $Feature
|
||||||
|
$X++
|
||||||
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($x/$CheckBox.Count) }
|
||||||
|
}
|
||||||
|
|
||||||
$sync.ProcessRunning = $false
|
$sync.ProcessRunning = $false
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
|
||||||
|
|
||||||
Write-Host "==================================="
|
Write-Host "==================================="
|
||||||
Write-Host "--- Features are Installed ---"
|
Write-Host "--- Features are Installed ---"
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ function Invoke-WPFGetInstalled {
|
|||||||
}
|
}
|
||||||
$managerPreference = $sync["ManagerPreference"]
|
$managerPreference = $sync["ManagerPreference"]
|
||||||
|
|
||||||
Invoke-WPFRunspace -ParameterList @(("managerPreference", $managerPreference),("checkbox", $checkbox)) -DebugPreference $DebugPreference -ScriptBlock {
|
Invoke-WPFRunspace -ParameterList @(("managerPreference", $managerPreference),("checkbox", $checkbox)) -ScriptBlock {
|
||||||
param (
|
param (
|
||||||
[string]$checkbox,
|
[string]$checkbox,
|
||||||
[PackageManagers]$managerPreference
|
[PackageManagers]$managerPreference
|
||||||
)
|
)
|
||||||
$sync.ProcessRunning = $true
|
$sync.ProcessRunning = $true
|
||||||
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "Indeterminate" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" }
|
||||||
|
|
||||||
if ($checkbox -eq "winget") {
|
if ($checkbox -eq "winget") {
|
||||||
Write-Host "Getting Installed Programs..."
|
Write-Host "Getting Installed Programs..."
|
||||||
@@ -48,6 +48,6 @@ function Invoke-WPFGetInstalled {
|
|||||||
|
|
||||||
Write-Host "Done..."
|
Write-Host "Done..."
|
||||||
$sync.ProcessRunning = $false
|
$sync.ProcessRunning = $false
|
||||||
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "None" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,9 +71,11 @@ function Invoke-WPFImpex {
|
|||||||
# $flattenedJson = $jsonFile.PSObject.Properties.Where({ $_.Name -ne "Install" }).ForEach({ $_.Value })
|
# $flattenedJson = $jsonFile.PSObject.Properties.Where({ $_.Name -ne "Install" }).ForEach({ $_.Value })
|
||||||
$flattenedJson = $jsonFile
|
$flattenedJson = $jsonFile
|
||||||
Update-WinUtilSelections -flatJson $flattenedJson
|
Update-WinUtilSelections -flatJson $flattenedJson
|
||||||
# TODO test with toggles
|
|
||||||
|
if (!$PARAM_NOUI) {
|
||||||
Reset-WPFCheckBoxes -doToggles $true
|
Reset-WPFCheckBoxes -doToggles $true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
Write-Error "An error occurred while importing: $_"
|
Write-Error "An error occurred while importing: $_"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
function Invoke-WPFInstall {
|
function Invoke-WPFInstall {
|
||||||
param (
|
|
||||||
[Parameter(Mandatory=$false)]
|
|
||||||
[PSObject[]]$PackagesToInstall = $($sync.selectedApps | Foreach-Object { $sync.configs.applicationsHashtable.$_ })
|
|
||||||
)
|
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Installs the selected programs using winget, if one or more of the selected programs are already installed on the system, winget will try and perform an upgrade if there's a newer version to install.
|
Installs the selected programs using winget, if one or more of the selected programs are already installed on the system, winget will try and perform an upgrade if there's a newer version to install.
|
||||||
#>
|
#>
|
||||||
|
|
||||||
|
$PackagesToInstall = $sync.selectedApps | Foreach-Object { $sync.configs.applicationsHashtable.$_ }
|
||||||
|
|
||||||
|
|
||||||
if($sync.ProcessRunning) {
|
if($sync.ProcessRunning) {
|
||||||
$msg = "[Invoke-WPFInstall] An Install process is currently running."
|
$msg = "[Invoke-WPFInstall] An Install process is currently running."
|
||||||
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
||||||
@@ -22,8 +21,8 @@ function Invoke-WPFInstall {
|
|||||||
|
|
||||||
$ManagerPreference = $sync["ManagerPreference"]
|
$ManagerPreference = $sync["ManagerPreference"]
|
||||||
|
|
||||||
Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -DebugPreference $DebugPreference -ScriptBlock {
|
$handle = Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -ScriptBlock {
|
||||||
param($PackagesToInstall, $ManagerPreference, $DebugPreference)
|
param($PackagesToInstall, $ManagerPreference)
|
||||||
|
|
||||||
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToInstall -Preference $ManagerPreference
|
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToInstall -Preference $ManagerPreference
|
||||||
|
|
||||||
@@ -45,12 +44,12 @@ function Invoke-WPFInstall {
|
|||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
Write-Host "-- Installs have finished ---"
|
Write-Host "-- Installs have finished ---"
|
||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
|
||||||
} catch {
|
} catch {
|
||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
Write-Host "Error: $_"
|
Write-Host "Error: $_"
|
||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" -overlay "warning" }
|
||||||
}
|
}
|
||||||
$sync.ProcessRunning = $False
|
$sync.ProcessRunning = $False
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ function Invoke-WPFRunspace {
|
|||||||
Param (
|
Param (
|
||||||
$ScriptBlock,
|
$ScriptBlock,
|
||||||
$ArgumentList,
|
$ArgumentList,
|
||||||
$ParameterList,
|
$ParameterList
|
||||||
$DebugPreference
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create a PowerShell instance
|
# Create a PowerShell instance
|
||||||
@@ -41,7 +40,7 @@ function Invoke-WPFRunspace {
|
|||||||
foreach ($parameter in $ParameterList) {
|
foreach ($parameter in $ParameterList) {
|
||||||
$script:powershell.AddParameter($parameter[0], $parameter[1])
|
$script:powershell.AddParameter($parameter[0], $parameter[1])
|
||||||
}
|
}
|
||||||
$script:powershell.AddArgument($DebugPreference) # Pass DebugPreference to the script block
|
|
||||||
$script:powershell.RunspacePool = $sync.runspace
|
$script:powershell.RunspacePool = $sync.runspace
|
||||||
|
|
||||||
# Execute the RunspacePool
|
# Execute the RunspacePool
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ function Invoke-WPFSSHServer {
|
|||||||
|
|
||||||
#>
|
#>
|
||||||
|
|
||||||
Invoke-WPFRunspace -DebugPreference $DebugPreference -ScriptBlock {
|
Invoke-WPFRunspace -ScriptBlock {
|
||||||
|
|
||||||
Invoke-WinUtilSSHServer
|
Invoke-WinUtilSSHServer
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,15 @@ function Invoke-WPFSystemRepair {
|
|||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Checks for system corruption using SFC, and DISM
|
Checks for system corruption using SFC, and DISM
|
||||||
|
Checks for disk failure using Chkdsk
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
1. SFC - Fixes system file corruption, and fixes DISM if it was corrupted
|
1. Chkdsk - Checks for disk errors, which can cause system file corruption and notifies of early disk failure
|
||||||
2. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
|
2. SFC - scans protected system files for corruption and fixes them
|
||||||
3. Chkdsk - Checks for disk errors, which can cause system file corruption and notifies of early disk failure
|
3. DISM - Repair a corrupted Windows operating system image
|
||||||
#>
|
#>
|
||||||
Start-Process cmd.exe -ArgumentList "/c chkdsk.exe /scan /perf" -NoNewWindow -Wait
|
|
||||||
|
Start-Process cmd.exe -ArgumentList "/c chkdsk /scan /perf" -NoNewWindow -Wait
|
||||||
Start-Process cmd.exe -ArgumentList "/c sfc /scannow" -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
|
Start-Process cmd.exe -ArgumentList "/c dism /online /cleanup-image /restorehealth" -NoNewWindow -Wait
|
||||||
|
|
||||||
|
|||||||
21
functions/public/Invoke-WPFUIThread.ps1
Normal file
21
functions/public/Invoke-WPFUIThread.ps1
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
function Invoke-WPFUIThread {
|
||||||
|
<#
|
||||||
|
|
||||||
|
.SYNOPSIS
|
||||||
|
Creates and runs a task on Winutil's WPF Forms thread.
|
||||||
|
|
||||||
|
.PARAMETER ScriptBlock
|
||||||
|
The scriptblock to invoke in the thread
|
||||||
|
#>
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param (
|
||||||
|
$ScriptBlock
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($PARAM_NOUI) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sync.form.Dispatcher.Invoke([action]$ScriptBlock)
|
||||||
|
}
|
||||||
@@ -32,8 +32,8 @@ function Invoke-WPFUnInstall {
|
|||||||
|
|
||||||
$ManagerPreference = $sync["ManagerPreference"]
|
$ManagerPreference = $sync["ManagerPreference"]
|
||||||
|
|
||||||
Invoke-WPFRunspace -ParameterList @(("PackagesToUninstall", $PackagesToUninstall),("ManagerPreference", $ManagerPreference)) -DebugPreference $DebugPreference -ScriptBlock {
|
Invoke-WPFRunspace -ParameterList @(("PackagesToUninstall", $PackagesToUninstall),("ManagerPreference", $ManagerPreference)) -ScriptBlock {
|
||||||
param($PackagesToUninstall, $ManagerPreference, $DebugPreference)
|
param($PackagesToUninstall, $ManagerPreference)
|
||||||
|
|
||||||
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToUninstall -Preference $ManagerPreference
|
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToUninstall -Preference $ManagerPreference
|
||||||
$packagesWinget = $packagesSorted[[PackageManagers]::Winget]
|
$packagesWinget = $packagesSorted[[PackageManagers]::Winget]
|
||||||
@@ -54,12 +54,12 @@ function Invoke-WPFUnInstall {
|
|||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
Write-Host "-- Uninstalls have finished ---"
|
Write-Host "-- Uninstalls have finished ---"
|
||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
|
||||||
} catch {
|
} catch {
|
||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
Write-Host "Error: $_"
|
Write-Host "Error: $_"
|
||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" -overlay "warning" }
|
||||||
}
|
}
|
||||||
$sync.ProcessRunning = $False
|
$sync.ProcessRunning = $False
|
||||||
|
|
||||||
|
|||||||
@@ -25,30 +25,27 @@ function Invoke-WPFtweaksbutton {
|
|||||||
Write-Debug "Number of tweaks to process: $($Tweaks.Count)"
|
Write-Debug "Number of tweaks to process: $($Tweaks.Count)"
|
||||||
|
|
||||||
# The leading "," in the ParameterList is necessary because we only provide one argument and powershell cannot be convinced that we want a nested loop with only one argument otherwise
|
# The leading "," in the ParameterList is necessary because we only provide one argument and powershell cannot be convinced that we want a nested loop with only one argument otherwise
|
||||||
Invoke-WPFRunspace -ParameterList @(,("tweaks",$tweaks)) -DebugPreference $DebugPreference -ScriptBlock {
|
$handle = Invoke-WPFRunspace -ParameterList @(,("tweaks",$tweaks)) -ScriptBlock {
|
||||||
param(
|
param($tweaks)
|
||||||
$tweaks,
|
|
||||||
$DebugPreference
|
|
||||||
)
|
|
||||||
Write-Debug "Inside Number of tweaks to process: $($Tweaks.Count)"
|
Write-Debug "Inside Number of tweaks to process: $($Tweaks.Count)"
|
||||||
|
|
||||||
$sync.ProcessRunning = $true
|
$sync.ProcessRunning = $true
|
||||||
|
|
||||||
if ($Tweaks.count -eq 1) {
|
if ($Tweaks.count -eq 1) {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }
|
||||||
} else {
|
} else {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
|
Invoke-WPFUIThread -ScriptBlock{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }
|
||||||
}
|
}
|
||||||
# Execute other selected tweaks
|
# Execute other selected tweaks
|
||||||
|
|
||||||
for ($i = 0; $i -lt $Tweaks.Count; $i++) {
|
for ($i = 0; $i -lt $Tweaks.Count; $i++) {
|
||||||
Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($i / $tweaks.Count * 100)
|
Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($i / $tweaks.Count * 100)
|
||||||
Invoke-WinUtilTweaks $tweaks[$i]
|
Invoke-WinUtilTweaks $tweaks[$i]
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i/$Tweaks.Count) })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($i/$Tweaks.Count) }
|
||||||
}
|
}
|
||||||
Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100
|
Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100
|
||||||
$sync.ProcessRunning = $false
|
$sync.ProcessRunning = $false
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
|
||||||
Write-Host "================================="
|
Write-Host "================================="
|
||||||
Write-Host "-- Tweaks are Finished ---"
|
Write-Host "-- Tweaks are Finished ---"
|
||||||
Write-Host "================================="
|
Write-Host "================================="
|
||||||
|
|||||||
@@ -20,26 +20,26 @@ function Invoke-WPFundoall {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Invoke-WPFRunspace -ArgumentList $tweaks -DebugPreference $DebugPreference -ScriptBlock {
|
Invoke-WPFRunspace -ArgumentList $tweaks -ScriptBlock {
|
||||||
param($tweaks, $DebugPreference)
|
param($tweaks)
|
||||||
|
|
||||||
$sync.ProcessRunning = $true
|
$sync.ProcessRunning = $true
|
||||||
if ($tweaks.count -eq 1) {
|
if ($tweaks.count -eq 1) {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }
|
||||||
} else {
|
} else {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for ($i = 0; $i -lt $tweaks.Count; $i++) {
|
for ($i = 0; $i -lt $tweaks.Count; $i++) {
|
||||||
Set-WinUtilProgressBar -Label "Undoing $($tweaks[$i])" -Percent ($i / $tweaks.Count * 100)
|
Set-WinUtilProgressBar -Label "Undoing $($tweaks[$i])" -Percent ($i / $tweaks.Count * 100)
|
||||||
Invoke-WinUtiltweaks $tweaks[$i] -undo $true
|
Invoke-WinUtiltweaks $tweaks[$i] -undo $true
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i/$tweaks.Count) })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($i/$tweaks.Count) }
|
||||||
}
|
}
|
||||||
|
|
||||||
Set-WinUtilProgressBar -Label "Undo Tweaks Finished" -Percent 100
|
Set-WinUtilProgressBar -Label "Undo Tweaks Finished" -Percent 100
|
||||||
$sync.ProcessRunning = $false
|
$sync.ProcessRunning = $false
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
|
||||||
Write-Host "=================================="
|
Write-Host "=================================="
|
||||||
Write-Host "--- Undo Tweaks are Finished ---"
|
Write-Host "--- Undo Tweaks are Finished ---"
|
||||||
Write-Host "=================================="
|
Write-Host "=================================="
|
||||||
|
|||||||
48
functions/public/Invoke-WinUtilAutoRun.ps1
Normal file
48
functions/public/Invoke-WinUtilAutoRun.ps1
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
function Invoke-WinUtilAutoRun {
|
||||||
|
<#
|
||||||
|
|
||||||
|
.SYNOPSIS
|
||||||
|
Runs Install, Tweaks, and Features with optional UI invocation.
|
||||||
|
#>
|
||||||
|
|
||||||
|
function BusyWait {
|
||||||
|
Start-Sleep -Seconds 5
|
||||||
|
while ($sync.ProcessRunning) {
|
||||||
|
Start-Sleep -Seconds 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BusyWait
|
||||||
|
|
||||||
|
Write-Host "Applying tweaks..."
|
||||||
|
Invoke-WPFtweaksbutton
|
||||||
|
BusyWait
|
||||||
|
|
||||||
|
Write-Host "Applying toggles..."
|
||||||
|
$handle = Invoke-WPFRunspace -ScriptBlock {
|
||||||
|
$Toggles = $sync.selectedToggles
|
||||||
|
Write-Debug "Inside Number of toggles to process: $($Toggles.Count)"
|
||||||
|
|
||||||
|
$sync.ProcessRunning = $true
|
||||||
|
|
||||||
|
for ($i = 0; $i -lt $Tweaks.Count; $i++) {
|
||||||
|
Invoke-WinUtilTweaks $Toggles[$i]
|
||||||
|
}
|
||||||
|
|
||||||
|
$sync.ProcessRunning = $false
|
||||||
|
Write-Host "================================="
|
||||||
|
Write-Host "-- Toggles are Finished ---"
|
||||||
|
Write-Host "================================="
|
||||||
|
}
|
||||||
|
BusyWait
|
||||||
|
|
||||||
|
Write-Host "Applying features..."
|
||||||
|
Invoke-WPFFeatureInstall
|
||||||
|
BusyWait
|
||||||
|
|
||||||
|
Write-Host "Installing applications..."
|
||||||
|
Invoke-WPFInstall
|
||||||
|
BusyWait
|
||||||
|
|
||||||
|
Write-Host "Done."
|
||||||
|
}
|
||||||
@@ -13,10 +13,14 @@ $maxthreads = [int]$env:NUMBER_OF_PROCESSORS
|
|||||||
|
|
||||||
# Create a new session state for parsing variables into our runspace
|
# Create a new session state for parsing variables into our runspace
|
||||||
$hashVars = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'sync',$sync,$Null
|
$hashVars = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'sync',$sync,$Null
|
||||||
|
$debugVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'DebugPreference',$DebugPreference,$Null
|
||||||
|
$uiVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'PARAM_NOUI',$PARAM_NOUI,$Null
|
||||||
$InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
|
$InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
|
||||||
|
|
||||||
# Add the variable to the session state
|
# Add the variable to the session state
|
||||||
$InitialSessionState.Variables.Add($hashVars)
|
$InitialSessionState.Variables.Add($hashVars)
|
||||||
|
$InitialSessionState.Variables.Add($debugVar)
|
||||||
|
$InitialSessionState.Variables.Add($uiVar)
|
||||||
|
|
||||||
# Get every private function and add them to the session state
|
# Get every private function and add them to the session state
|
||||||
$functions = Get-ChildItem function:\ | Where-Object { $_.Name -imatch 'winutil|WPF' }
|
$functions = Get-ChildItem function:\ | Where-Object { $_.Name -imatch 'winutil|WPF' }
|
||||||
@@ -55,6 +59,42 @@ class GenericException : Exception {
|
|||||||
GenericException($Message) : base($Message) {}
|
GenericException($Message) : base($Message) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Load the configuration files
|
||||||
|
|
||||||
|
$sync.configs.applicationsHashtable = @{}
|
||||||
|
$sync.configs.applications.PSObject.Properties | ForEach-Object {
|
||||||
|
$sync.configs.applicationsHashtable[$_.Name] = $_.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-PackageManagerPreference
|
||||||
|
|
||||||
|
if ($PARAM_NOUI) {
|
||||||
|
Show-CTTLogo
|
||||||
|
if ($PARAM_CONFIG -and -not [string]::IsNullOrWhiteSpace($PARAM_CONFIG)) {
|
||||||
|
Write-Host "Running config file tasks..."
|
||||||
|
Invoke-WPFImpex -type "import" -Config $PARAM_CONFIG
|
||||||
|
if ($PARAM_RUN) {
|
||||||
|
Invoke-WinUtilAutoRun
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "Did you forget to add '--Run'?";
|
||||||
|
}
|
||||||
|
$sync.runspace.Dispose()
|
||||||
|
$sync.runspace.Close()
|
||||||
|
[System.GC]::Collect()
|
||||||
|
Stop-Transcript
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "Cannot automatically run without a config file provided."
|
||||||
|
$sync.runspace.Dispose()
|
||||||
|
$sync.runspace.Close()
|
||||||
|
[System.GC]::Collect()
|
||||||
|
Stop-Transcript
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window'
|
$inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window'
|
||||||
|
|
||||||
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
|
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
|
||||||
@@ -115,12 +155,7 @@ $sync.Form.Add_Loaded({
|
|||||||
})
|
})
|
||||||
|
|
||||||
Invoke-WinutilThemeChange -init $true
|
Invoke-WinutilThemeChange -init $true
|
||||||
# Load the configuration files
|
|
||||||
|
|
||||||
$sync.configs.applicationsHashtable = @{}
|
|
||||||
$sync.configs.applications.PSObject.Properties | ForEach-Object {
|
|
||||||
$sync.configs.applicationsHashtable[$_.Name] = $_.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
# Now call the function with the final merged config
|
# Now call the function with the final merged config
|
||||||
Invoke-WPFUIElements -configVariable $sync.configs.appnavigation -targetGridName "appscategory" -columncount 1
|
Invoke-WPFUIElements -configVariable $sync.configs.appnavigation -targetGridName "appscategory" -columncount 1
|
||||||
@@ -144,7 +179,6 @@ $xaml.SelectNodes("//*[@Name]") | ForEach-Object {$sync["$("$($psitem.Name)")"]
|
|||||||
#Persist Package Manager preference across winutil restarts
|
#Persist Package Manager preference across winutil restarts
|
||||||
$sync.ChocoRadioButton.Add_Checked({Set-PackageManagerPreference Choco})
|
$sync.ChocoRadioButton.Add_Checked({Set-PackageManagerPreference Choco})
|
||||||
$sync.WingetRadioButton.Add_Checked({Set-PackageManagerPreference Winget})
|
$sync.WingetRadioButton.Add_Checked({Set-PackageManagerPreference Winget})
|
||||||
Set-PackageManagerPreference
|
|
||||||
|
|
||||||
switch ($sync["ManagerPreference"]) {
|
switch ($sync["ManagerPreference"]) {
|
||||||
"Choco" {$sync.ChocoRadioButton.IsChecked = $true; break}
|
"Choco" {$sync.ChocoRadioButton.IsChecked = $true; break}
|
||||||
@@ -341,45 +375,11 @@ $sync["Form"].Add_ContentRendered({
|
|||||||
|
|
||||||
$sync["Form"].Focus()
|
$sync["Form"].Focus()
|
||||||
|
|
||||||
# maybe this is not the best place to load and execute config file?
|
|
||||||
# maybe community can help?
|
|
||||||
if ($PARAM_CONFIG -and -not [string]::IsNullOrWhiteSpace($PARAM_CONFIG)) {
|
if ($PARAM_CONFIG -and -not [string]::IsNullOrWhiteSpace($PARAM_CONFIG)) {
|
||||||
|
Write-Host "Running config file tasks..."
|
||||||
Invoke-WPFImpex -type "import" -Config $PARAM_CONFIG
|
Invoke-WPFImpex -type "import" -Config $PARAM_CONFIG
|
||||||
if ($PARAM_RUN) {
|
if ($PARAM_RUN) {
|
||||||
# Wait for any existing process to complete before starting
|
Invoke-WinUtilAutoRun
|
||||||
while ($sync.ProcessRunning) {
|
|
||||||
Start-Sleep -Seconds 5
|
|
||||||
}
|
|
||||||
Start-Sleep -Seconds 5
|
|
||||||
|
|
||||||
Write-Host "Applying tweaks..."
|
|
||||||
if (-not $sync.ProcessRunning) {
|
|
||||||
Invoke-WPFtweaksbutton
|
|
||||||
while ($sync.ProcessRunning) {
|
|
||||||
Start-Sleep -Seconds 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Start-Sleep -Seconds 5
|
|
||||||
|
|
||||||
Write-Host "Installing features..."
|
|
||||||
if (-not $sync.ProcessRunning) {
|
|
||||||
Invoke-WPFFeatureInstall
|
|
||||||
while ($sync.ProcessRunning) {
|
|
||||||
Start-Sleep -Seconds 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Start-Sleep -Seconds 5
|
|
||||||
|
|
||||||
Write-Host "Installing applications..."
|
|
||||||
if (-not $sync.ProcessRunning) {
|
|
||||||
Invoke-WPFInstall
|
|
||||||
while ($sync.ProcessRunning) {
|
|
||||||
Start-Sleep -Seconds 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Start-Sleep -Seconds 5
|
|
||||||
|
|
||||||
Write-Host "Done."
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,16 +7,11 @@
|
|||||||
#>
|
#>
|
||||||
|
|
||||||
param (
|
param (
|
||||||
[switch]$Debug,
|
|
||||||
[string]$Config,
|
[string]$Config,
|
||||||
[switch]$Run
|
[switch]$Run,
|
||||||
|
[switch]$Noui
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set DebugPreference based on the -Debug switch
|
|
||||||
if ($Debug) {
|
|
||||||
$DebugPreference = "Continue"
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($Config) {
|
if ($Config) {
|
||||||
$PARAM_CONFIG = $Config
|
$PARAM_CONFIG = $Config
|
||||||
}
|
}
|
||||||
@@ -24,10 +19,14 @@ if ($Config) {
|
|||||||
$PARAM_RUN = $false
|
$PARAM_RUN = $false
|
||||||
# Handle the -Run switch
|
# Handle the -Run switch
|
||||||
if ($Run) {
|
if ($Run) {
|
||||||
Write-Host "Running config file tasks..."
|
|
||||||
$PARAM_RUN = $true
|
$PARAM_RUN = $true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$PARAM_NOUI = $false
|
||||||
|
if ($Noui) {
|
||||||
|
$PARAM_NOUI = $true
|
||||||
|
}
|
||||||
|
|
||||||
# Load DLLs
|
# Load DLLs
|
||||||
Add-Type -AssemblyName PresentationFramework
|
Add-Type -AssemblyName PresentationFramework
|
||||||
Add-Type -AssemblyName System.Windows.Forms
|
Add-Type -AssemblyName System.Windows.Forms
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<#
|
<#
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Generates Hugo-compatible markdown files for the development documentation
|
Generates Hugo markdown docs from config/tweaks.json and config/feature.json.
|
||||||
based on config/tweaks.json and config/feature.json.
|
Run by the GitHub Actions docs workflow before Hugo build.
|
||||||
Each JSON entry gets its own .md file with the raw JSON snippet or PowerShell function embedded.
|
|
||||||
Called by the GitHub Actions docs workflow before Hugo build.
|
|
||||||
#>
|
#>
|
||||||
|
|
||||||
function Update-Progress {
|
function Update-Progress {
|
||||||
@@ -18,11 +16,7 @@ function Update-Progress {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Get-RawJsonBlock {
|
function Get-RawJsonBlock {
|
||||||
<#
|
# Returns the raw JSON text and 1-based start line for an item, excluding the "link" property.
|
||||||
.SYNOPSIS
|
|
||||||
Extracts the raw JSON text for a specific item from a JSON file's lines.
|
|
||||||
Returns the line number and raw text, excluding the "link" property and closing brace.
|
|
||||||
#>
|
|
||||||
param (
|
param (
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
[string]$ItemName,
|
[string]$ItemName,
|
||||||
@@ -35,7 +29,6 @@ function Get-RawJsonBlock {
|
|||||||
$startIndex = -1
|
$startIndex = -1
|
||||||
$startIndent = ""
|
$startIndent = ""
|
||||||
|
|
||||||
# Find the line containing "ItemName": {
|
|
||||||
for ($i = 0; $i -lt $JsonLines.Count; $i++) {
|
for ($i = 0; $i -lt $JsonLines.Count; $i++) {
|
||||||
if ($JsonLines[$i] -match "^(\s*)`"$escapedName`"\s*:\s*\{") {
|
if ($JsonLines[$i] -match "^(\s*)`"$escapedName`"\s*:\s*\{") {
|
||||||
$startIndex = $i
|
$startIndex = $i
|
||||||
@@ -49,7 +42,6 @@ function Get-RawJsonBlock {
|
|||||||
return $null
|
return $null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Find the closing } at the same indentation level
|
|
||||||
$escapedIndent = [regex]::Escape($startIndent)
|
$escapedIndent = [regex]::Escape($startIndent)
|
||||||
$endIndex = -1
|
$endIndex = -1
|
||||||
for ($i = ($startIndex + 1); $i -lt $JsonLines.Count; $i++) {
|
for ($i = ($startIndex + 1); $i -lt $JsonLines.Count; $i++) {
|
||||||
@@ -64,7 +56,7 @@ function Get-RawJsonBlock {
|
|||||||
return $null
|
return $null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Walk backwards from closing brace to exclude "link" property and empty lines
|
# Strip trailing "link" property and blank lines before returning
|
||||||
$lastContentIndex = $endIndex - 1
|
$lastContentIndex = $endIndex - 1
|
||||||
while ($lastContentIndex -gt $startIndex) {
|
while ($lastContentIndex -gt $startIndex) {
|
||||||
$trimmed = $JsonLines[$lastContentIndex].Trim()
|
$trimmed = $JsonLines[$lastContentIndex].Trim()
|
||||||
@@ -75,28 +67,21 @@ function Get-RawJsonBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$rawLines = $JsonLines[$startIndex..$lastContentIndex]
|
|
||||||
$rawText = $rawLines -join "`r`n"
|
|
||||||
|
|
||||||
return @{
|
return @{
|
||||||
LineNumber = $startIndex + 1 # 1-based
|
LineNumber = $startIndex + 1
|
||||||
RawText = $rawText
|
RawText = ($JsonLines[$startIndex..$lastContentIndex] -join "`r`n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Get-ButtonFunctionMapping {
|
function Get-ButtonFunctionMapping {
|
||||||
<#
|
# Parses Invoke-WPFButton.ps1 and returns a hashtable of button name -> function name.
|
||||||
.SYNOPSIS
|
|
||||||
Parses Invoke-WPFButton.ps1 to build a hashtable mapping button names to function names.
|
|
||||||
#>
|
|
||||||
param (
|
param (
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
[string]$ButtonFilePath
|
[string]$ButtonFilePath
|
||||||
)
|
)
|
||||||
|
|
||||||
$mapping = @{}
|
$mapping = @{}
|
||||||
$lines = Get-Content -Path $ButtonFilePath
|
foreach ($line in (Get-Content -Path $ButtonFilePath)) {
|
||||||
foreach ($line in $lines) {
|
|
||||||
if ($line -match '^\s*"(\w+)"\s*\{(Invoke-\w+)') {
|
if ($line -match '^\s*"(\w+)"\s*\{(Invoke-\w+)') {
|
||||||
$mapping[$matches[1]] = $matches[2]
|
$mapping[$matches[1]] = $matches[2]
|
||||||
}
|
}
|
||||||
@@ -105,11 +90,8 @@ function Get-ButtonFunctionMapping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Add-LinkAttributeToJson {
|
function Add-LinkAttributeToJson {
|
||||||
<#
|
# Updates only the "link" property for each entry in a JSON config file.
|
||||||
.SYNOPSIS
|
# Reads via ConvertFrom-Json for metadata, then edits lines directly to avoid reformatting.
|
||||||
Updates the "link" property on each top-level entry in a JSON config file
|
|
||||||
to point to the corresponding documentation page URL.
|
|
||||||
#>
|
|
||||||
param (
|
param (
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
[string]$JsonFilePath,
|
[string]$JsonFilePath,
|
||||||
@@ -119,32 +101,74 @@ function Add-LinkAttributeToJson {
|
|||||||
[string]$ItemNameToCut
|
[string]$ItemNameToCut
|
||||||
)
|
)
|
||||||
|
|
||||||
$jsonText = Get-Content -Path $JsonFilePath -Raw
|
$jsonData = Get-Content -Path $JsonFilePath -Raw | ConvertFrom-Json
|
||||||
$jsonData = $jsonText | ConvertFrom-Json
|
$lines = [System.Collections.Generic.List[string]](Get-Content -Path $JsonFilePath)
|
||||||
|
|
||||||
foreach ($item in $jsonData.PSObject.Properties) {
|
foreach ($item in $jsonData.PSObject.Properties) {
|
||||||
$itemName = $item.Name
|
$itemName = $item.Name
|
||||||
$itemDetails = $item.Value
|
$category = $item.Value.category -replace '[^a-zA-Z0-9]', '-'
|
||||||
$category = $itemDetails.category -replace '[^a-zA-Z0-9]', '-'
|
|
||||||
$displayName = $itemName -replace $ItemNameToCut, ''
|
$displayName = $itemName -replace $ItemNameToCut, ''
|
||||||
$docLink = "$UrlPrefix/$($category.ToLower())/$($displayName.ToLower())"
|
$newLink = "$UrlPrefix/$($category.ToLower())/$($displayName.ToLower())"
|
||||||
|
$escapedName = [regex]::Escape($itemName)
|
||||||
|
|
||||||
$itemDetails | Add-Member -NotePropertyName "link" -NotePropertyValue $docLink -Force
|
# Find item start line
|
||||||
|
$startIdx = -1
|
||||||
|
for ($i = 0; $i -lt $lines.Count; $i++) {
|
||||||
|
if ($lines[$i] -match "^\s*`"$escapedName`"\s*:\s*\{") {
|
||||||
|
$startIdx = $i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($startIdx -eq -1) { continue }
|
||||||
|
|
||||||
|
# Derive indentation: propIndent is one level deeper than the item start.
|
||||||
|
# Used to target only top-level properties and skip nested object braces.
|
||||||
|
$null = $lines[$startIdx] -match '^(\s*)'
|
||||||
|
$propIndent = $matches[1] + ' '
|
||||||
|
$propIndentLen = $propIndent.Length
|
||||||
|
$escapedPropIndent = [regex]::Escape($propIndent)
|
||||||
|
|
||||||
|
# Scan forward: update existing "link" or find the closing brace to insert one.
|
||||||
|
# Closing brace is matched by indent <= propIndentLen to handle inconsistent formatting.
|
||||||
|
$linkUpdated = $false
|
||||||
|
$closeBraceIdx = -1
|
||||||
|
for ($j = $startIdx + 1; $j -lt $lines.Count; $j++) {
|
||||||
|
if ($lines[$j] -match "^$escapedPropIndent`"link`"\s*:") {
|
||||||
|
$lines[$j] = $lines[$j] -replace '"link"\s*:\s*"[^"]*"', "`"link`": `"$newLink`""
|
||||||
|
$linkUpdated = $true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if ($lines[$j] -match '^\s*\}') {
|
||||||
|
$null = $lines[$j] -match '^(\s*)'
|
||||||
|
if ($matches[1].Length -le $propIndentLen) {
|
||||||
|
$closeBraceIdx = $j
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$jsonText = ($jsonData | ConvertTo-Json -Depth 100).replace('\n', "`n").replace('\r', "`r")
|
if (-not $linkUpdated -and $closeBraceIdx -ne -1) {
|
||||||
Set-Content -Path $JsonFilePath -Value $jsonText -Encoding utf8
|
# Insert "link" before the closing brace
|
||||||
|
$prevPropIdx = $closeBraceIdx - 1
|
||||||
|
while ($prevPropIdx -gt $startIdx -and $lines[$prevPropIdx].Trim() -eq '') { $prevPropIdx-- }
|
||||||
|
|
||||||
|
if ($lines[$prevPropIdx] -notmatch ',\s*$') {
|
||||||
|
$lines[$prevPropIdx] = $lines[$prevPropIdx].TrimEnd() + ','
|
||||||
|
}
|
||||||
|
$lines.Insert($closeBraceIdx, "$propIndent`"link`": `"$newLink`"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-Content -Path $JsonFilePath -Value $lines -Encoding utf8
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# Main Script
|
# Main
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# Use PSScriptRoot if available (running as a script file), otherwise assume CWD is tools/
|
|
||||||
$scriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { (Get-Location).Path }
|
$scriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { (Get-Location).Path }
|
||||||
$repoRoot = Resolve-Path "$scriptDir/.."
|
$repoRoot = Resolve-Path "$scriptDir/.."
|
||||||
|
|
||||||
# Paths
|
|
||||||
$tweaksJsonPath = "$repoRoot/config/tweaks.json"
|
$tweaksJsonPath = "$repoRoot/config/tweaks.json"
|
||||||
$featuresJsonPath = "$repoRoot/config/feature.json"
|
$featuresJsonPath = "$repoRoot/config/feature.json"
|
||||||
$tweaksOutputDir = "$repoRoot/docs/content/dev/tweaks"
|
$tweaksOutputDir = "$repoRoot/docs/content/dev/tweaks"
|
||||||
@@ -155,7 +179,7 @@ $privateFunctionsDir = "$repoRoot/functions/private"
|
|||||||
$itemnametocut = 'WPF(WinUtil|Toggle|Features?|Tweaks?|Panel|Fix(es)?)?'
|
$itemnametocut = 'WPF(WinUtil|Toggle|Features?|Tweaks?|Panel|Fix(es)?)?'
|
||||||
$baseUrl = "https://winutil.christitus.com"
|
$baseUrl = "https://winutil.christitus.com"
|
||||||
|
|
||||||
# Categories that should have generated documentation
|
# Categories with generated docs
|
||||||
$documentedCategories = @(
|
$documentedCategories = @(
|
||||||
"Essential Tweaks",
|
"Essential Tweaks",
|
||||||
"z__Advanced Tweaks - CAUTION",
|
"z__Advanced Tweaks - CAUTION",
|
||||||
@@ -163,49 +187,44 @@ $documentedCategories = @(
|
|||||||
"Performance Plans",
|
"Performance Plans",
|
||||||
"Features",
|
"Features",
|
||||||
"Fixes",
|
"Fixes",
|
||||||
"Legacy Windows Panels"
|
"Legacy Windows Panels",
|
||||||
|
"Powershell Profile Powershell 7+ Only",
|
||||||
|
"Remote Access"
|
||||||
)
|
)
|
||||||
|
|
||||||
# --- Load data ---
|
# Categories where Button entries embed a PS function instead of raw JSON
|
||||||
|
$functionEmbedCategories = @(
|
||||||
|
"Fixes",
|
||||||
|
"Powershell Profile Powershell 7+ Only",
|
||||||
|
"Remote Access"
|
||||||
|
)
|
||||||
|
|
||||||
Update-Progress "Loading JSON files" 10
|
Update-Progress "Loading JSON files" 10
|
||||||
$tweaks = Get-Content -Path $tweaksJsonPath -Raw | ConvertFrom-Json
|
$tweaks = Get-Content -Path $tweaksJsonPath -Raw | ConvertFrom-Json
|
||||||
$features = Get-Content -Path $featuresJsonPath -Raw | ConvertFrom-Json
|
$features = Get-Content -Path $featuresJsonPath -Raw | ConvertFrom-Json
|
||||||
|
|
||||||
# --- Load function files (content + relative path) ---
|
|
||||||
|
|
||||||
Update-Progress "Loading function files" 20
|
Update-Progress "Loading function files" 20
|
||||||
$functionFiles = @{}
|
$functionFiles = @{}
|
||||||
Get-ChildItem -Path $publicFunctionsDir -Filter *.ps1 | ForEach-Object {
|
Get-ChildItem -Path $publicFunctionsDir -Filter *.ps1 | ForEach-Object {
|
||||||
$functionFiles[$_.BaseName] = @{
|
$functionFiles[$_.BaseName] = @{ Content = (Get-Content -Path $_.FullName -Raw).TrimEnd(); RelativePath = "functions/public/$($_.Name)" }
|
||||||
Content = (Get-Content -Path $_.FullName -Raw).TrimEnd()
|
|
||||||
RelativePath = "functions/public/$($_.Name)"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Get-ChildItem -Path $privateFunctionsDir -Filter *.ps1 | ForEach-Object {
|
Get-ChildItem -Path $privateFunctionsDir -Filter *.ps1 | ForEach-Object {
|
||||||
$functionFiles[$_.BaseName] = @{
|
$functionFiles[$_.BaseName] = @{ Content = (Get-Content -Path $_.FullName -Raw).TrimEnd(); RelativePath = "functions/private/$($_.Name)" }
|
||||||
Content = (Get-Content -Path $_.FullName -Raw).TrimEnd()
|
|
||||||
RelativePath = "functions/private/$($_.Name)"
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# --- Build button-to-function mapping ---
|
|
||||||
|
|
||||||
Update-Progress "Building button-to-function mapping" 30
|
Update-Progress "Building button-to-function mapping" 30
|
||||||
$buttonFunctionMap = Get-ButtonFunctionMapping -ButtonFilePath "$publicFunctionsDir/Invoke-WPFButton.ps1"
|
$buttonFunctionMap = Get-ButtonFunctionMapping -ButtonFilePath "$publicFunctionsDir/Invoke-WPFButton.ps1"
|
||||||
|
|
||||||
# --- Update link attributes in JSON files ---
|
|
||||||
|
|
||||||
Update-Progress "Updating documentation links in JSON" 40
|
Update-Progress "Updating documentation links in JSON" 40
|
||||||
Add-LinkAttributeToJson -JsonFilePath $tweaksJsonPath -UrlPrefix "$baseUrl/dev/tweaks" -ItemNameToCut $itemnametocut
|
Add-LinkAttributeToJson -JsonFilePath $tweaksJsonPath -UrlPrefix "$baseUrl/dev/tweaks" -ItemNameToCut $itemnametocut
|
||||||
Add-LinkAttributeToJson -JsonFilePath $featuresJsonPath -UrlPrefix "$baseUrl/dev/features" -ItemNameToCut $itemnametocut
|
Add-LinkAttributeToJson -JsonFilePath $featuresJsonPath -UrlPrefix "$baseUrl/dev/features" -ItemNameToCut $itemnametocut
|
||||||
|
|
||||||
# Reload JSON lines after link update (so line numbers are accurate)
|
# Reload lines after link update so line numbers in docs are accurate
|
||||||
$tweaksLines = Get-Content -Path $tweaksJsonPath
|
$tweaksLines = Get-Content -Path $tweaksJsonPath
|
||||||
$featuresLines = Get-Content -Path $featuresJsonPath
|
$featuresLines = Get-Content -Path $featuresJsonPath
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# Clean up old generated .md files (keep _index.md)
|
# Clean up old generated .md files (preserve _index.md)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
Update-Progress "Cleaning up old generated docs" 45
|
Update-Progress "Cleaning up old generated docs" 45
|
||||||
@@ -236,16 +255,12 @@ foreach ($itemName in $tweakNames) {
|
|||||||
$categoryDir = "$tweaksOutputDir/$category"
|
$categoryDir = "$tweaksOutputDir/$category"
|
||||||
$filename = "$categoryDir/$displayName.md"
|
$filename = "$categoryDir/$displayName.md"
|
||||||
|
|
||||||
if (-Not (Test-Path -Path $categoryDir)) {
|
if (-Not (Test-Path -Path $categoryDir)) { New-Item -ItemType Directory -Path $categoryDir | Out-Null }
|
||||||
New-Item -ItemType Directory -Path $categoryDir | Out-Null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Hugo frontmatter
|
|
||||||
$title = $item.Content -replace '"', '\"'
|
$title = $item.Content -replace '"', '\"'
|
||||||
$content = "---`r`ntitle: `"$title`"`r`ndescription: `"`"`r`n---`r`n`r`n"
|
$content = "---`r`ntitle: `"$title`"`r`ndescription: `"`"`r`n---`r`n`r`n"
|
||||||
|
|
||||||
if ($item.Type -eq "Button") {
|
if ($item.Type -eq "Button") {
|
||||||
# Button-type tweak: embed the mapped PowerShell function
|
|
||||||
$funcName = $buttonFunctionMap[$itemName]
|
$funcName = $buttonFunctionMap[$itemName]
|
||||||
if ($funcName -and $functionFiles.ContainsKey($funcName)) {
|
if ($funcName -and $functionFiles.ContainsKey($funcName)) {
|
||||||
$func = $functionFiles[$funcName]
|
$func = $functionFiles[$funcName]
|
||||||
@@ -254,7 +269,6 @@ foreach ($itemName in $tweakNames) {
|
|||||||
$content += "```````r`n"
|
$content += "```````r`n"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
# Standard tweak: embed raw JSON block
|
|
||||||
$jsonBlock = Get-RawJsonBlock -ItemName $itemName -JsonLines $tweaksLines
|
$jsonBlock = Get-RawJsonBlock -ItemName $itemName -JsonLines $tweaksLines
|
||||||
if ($jsonBlock) {
|
if ($jsonBlock) {
|
||||||
$content += "``````json {filename=`"config/tweaks.json`",linenos=inline,linenostart=$($jsonBlock.LineNumber)}`r`n"
|
$content += "``````json {filename=`"config/tweaks.json`",linenos=inline,linenostart=$($jsonBlock.LineNumber)}`r`n"
|
||||||
@@ -262,27 +276,16 @@ foreach ($itemName in $tweakNames) {
|
|||||||
$content += "```````r`n"
|
$content += "```````r`n"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Registry Changes section
|
|
||||||
if ($item.registry) {
|
if ($item.registry) {
|
||||||
$content += "`r`n## Registry Changes`r`n`r`n"
|
$content += "`r`n## Registry Changes`r`n`r`n"
|
||||||
$content += "Applications and System Components store and retrieve configuration data to modify windows settings, so we can use the registry to change many settings in one place.`r`n`r`n"
|
$content += "Applications and System Components store and retrieve configuration data to modify windows settings, so we can use the registry to change many settings in one place.`r`n`r`n"
|
||||||
$content += "You can find information about the registry on [Wikipedia](https://www.wikiwand.com/en/Windows_Registry) and [Microsoft's Website](https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry).`r`n"
|
$content += "You can find information about the registry on [Wikipedia](https://www.wikiwand.com/en/Windows_Registry) and [Microsoft's Website](https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry).`r`n"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Service function reference
|
|
||||||
if ($item.service -and $functionFiles.ContainsKey("Set-WinUtilService")) {
|
|
||||||
$svcFunc = $functionFiles["Set-WinUtilService"]
|
|
||||||
$content += "#Function`r`n"
|
|
||||||
$content += "``````powershell {filename=`"$($svcFunc.RelativePath)`",linenos=inline,linenostart=1}`r`n"
|
|
||||||
$content += $svcFunc.Content + "`r`n"
|
|
||||||
$content += "```````r`n"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Set-Content -Path $filename -Value $content -Encoding utf8 -NoNewline
|
Set-Content -Path $filename -Value $content -Encoding utf8 -NoNewline
|
||||||
|
|
||||||
$percent = 50 + [int](($tweakCount / $totalTweaks) * 20)
|
$percent = [Math]::Min(70, 50 + [int](($tweakCount / $totalTweaks) * 20))
|
||||||
if ($percent -gt 70) { $percent = 70 }
|
|
||||||
Update-Progress "Generating tweak documentation ($tweakCount/$totalTweaks)" $percent
|
Update-Progress "Generating tweak documentation ($tweakCount/$totalTweaks)" $percent
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,8 +304,6 @@ foreach ($itemName in $featureNames) {
|
|||||||
$featureCount++
|
$featureCount++
|
||||||
|
|
||||||
if ($item.category -notin $documentedCategories) { continue }
|
if ($item.category -notin $documentedCategories) { continue }
|
||||||
|
|
||||||
# Skip pure UI buttons that don't need docs
|
|
||||||
if ($itemName -eq "WPFFeatureInstall") { continue }
|
if ($itemName -eq "WPFFeatureInstall") { continue }
|
||||||
|
|
||||||
$category = $item.category -replace '[^a-zA-Z0-9]', '-'
|
$category = $item.category -replace '[^a-zA-Z0-9]', '-'
|
||||||
@@ -310,16 +311,13 @@ foreach ($itemName in $featureNames) {
|
|||||||
$categoryDir = "$featuresOutputDir/$category"
|
$categoryDir = "$featuresOutputDir/$category"
|
||||||
$filename = "$categoryDir/$displayName.md"
|
$filename = "$categoryDir/$displayName.md"
|
||||||
|
|
||||||
if (-Not (Test-Path -Path $categoryDir)) {
|
if (-Not (Test-Path -Path $categoryDir)) { New-Item -ItemType Directory -Path $categoryDir | Out-Null }
|
||||||
New-Item -ItemType Directory -Path $categoryDir | Out-Null
|
|
||||||
}
|
|
||||||
|
|
||||||
$title = $item.Content -replace '"', '\"'
|
$title = $item.Content -replace '"', '\"'
|
||||||
$content = "---`r`ntitle: `"$title`"`r`ndescription: `"`"`r`n---`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") {
|
if ($item.category -in $functionEmbedCategories) {
|
||||||
# Embed the PowerShell function file
|
$funcName = if ($item.function) { $item.function } else { $buttonFunctionMap[$itemName] }
|
||||||
$funcName = $buttonFunctionMap[$itemName]
|
|
||||||
if ($funcName -and $functionFiles.ContainsKey($funcName)) {
|
if ($funcName -and $functionFiles.ContainsKey($funcName)) {
|
||||||
$func = $functionFiles[$funcName]
|
$func = $functionFiles[$funcName]
|
||||||
$content += "``````powershell {filename=`"$($func.RelativePath)`",linenos=inline,linenostart=1}`r`n"
|
$content += "``````powershell {filename=`"$($func.RelativePath)`",linenos=inline,linenostart=1}`r`n"
|
||||||
@@ -327,7 +325,6 @@ foreach ($itemName in $featureNames) {
|
|||||||
$content += "```````r`n"
|
$content += "```````r`n"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
# Features category: embed raw JSON block
|
|
||||||
$jsonBlock = Get-RawJsonBlock -ItemName $itemName -JsonLines $featuresLines
|
$jsonBlock = Get-RawJsonBlock -ItemName $itemName -JsonLines $featuresLines
|
||||||
if ($jsonBlock) {
|
if ($jsonBlock) {
|
||||||
$content += "``````json {filename=`"config/feature.json`",linenos=inline,linenostart=$($jsonBlock.LineNumber)}`r`n"
|
$content += "``````json {filename=`"config/feature.json`",linenos=inline,linenostart=$($jsonBlock.LineNumber)}`r`n"
|
||||||
@@ -338,8 +335,7 @@ foreach ($itemName in $featureNames) {
|
|||||||
|
|
||||||
Set-Content -Path $filename -Value $content -Encoding utf8 -NoNewline
|
Set-Content -Path $filename -Value $content -Encoding utf8 -NoNewline
|
||||||
|
|
||||||
$percent = 70 + [int](($featureCount / $totalFeatures) * 20)
|
$percent = [Math]::Min(90, 70 + [int](($featureCount / $totalFeatures) * 20))
|
||||||
if ($percent -gt 90) { $percent = 90 }
|
|
||||||
Update-Progress "Generating feature documentation ($featureCount/$totalFeatures)" $percent
|
Update-Progress "Generating feature documentation ($featureCount/$totalFeatures)" $percent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user