Compare commits

..

15 Commits

Author SHA1 Message Date
d23e6f92fd Fix typo (#3104) 2024-12-14 07:44:45 +01:00
2466b903f6 Merge branch 'main' into microwin-2025-preparation 2024-12-14 07:44:07 +01:00
2f8eaf4f18 Add VirtIO functionality and more enhancements
- Added the ability to grab VirtIO Guest Tools
- Modified the description of the Copy ISO files function because it basically had nonsense
2024-12-06 08:55:02 +01:00
aa717838b2 Merge branch 'main' into microwin-2025-preparation 2024-12-06 06:58:24 +01:00
40c7a1b8d5 Merge branch 'main' into microwin-2025-preparation 2024-12-02 21:47:49 +01:00
3cfc7c92b4 Improve copy operation to Ventoy drives
This change may fix the issues where there's a conflict between both Ventoy's and MicroWin's unattended answer files, causing target images to stop working as expected during OOBE
2024-12-02 21:46:38 +01:00
9979a02a30 Merge branch 'main' into microwin-2025-preparation 2024-12-01 19:15:49 +01:00
759d8f6878 Exclude Windows Photo Viewer from dir removal 2024-12-01 18:03:32 +01:00
2c4cf504fc Package exclusion improvements
- Removed AppX packages from OS package exclusion list
- Added exclusion of PowerShell ISE (source: Discord server - yes, some people still use the PowerShell ISE)
2024-12-01 18:02:52 +01:00
cc7b3d7836 Remove jargon of scratch directory options 2024-12-01 18:01:38 +01:00
8e647e8c49 Update comment
It reflects my feelings towards Microsoft when it comes to security a lot better
2024-11-24 18:16:55 +01:00
c5968243eb Fix name of excluded package 2024-11-24 13:37:06 +01:00
706f65f631 Obscure passwords with Base64 and fix indentation
Fixes #3064
2024-11-24 12:52:59 +01:00
9dcf8dd50e Exclude Windows Hello stuff from package removal 2024-11-24 12:51:53 +01:00
a45402e9d8 Set Boot Manager entry timeout to 0
Fixes #2562
2024-11-22 18:24:00 +01:00
73 changed files with 1387 additions and 2634 deletions

30
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,30 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'bug'
assignees: ''
---
## Describe the bug
<!-- A clear and concise description of what the bug is. -->
## Steps to reproduce
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See the error.
## Expected behavior
<!-- A clear and concise description of what you expected to happen. -->
## Screenshots
<!-- If applicable, add screenshots to help explain your problem. -->
## Additional context
<!-- Add any other context about the problem here. -->
## Issue validation
- [ ] I checked for duplicate issues.
- [ ] I checked for already existing discussions.
- [ ] I checked for an already existing pull request addressing the issue.

View File

@ -1,62 +0,0 @@
name: "Bug report"
description: "Report a bug to help us identify and fix issues in the project."
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
# 🐞 **Issue Report**
Thank you for taking the time to report an issue! Please provide as much detail as possible to help us address the problem efficiently.
## ⚠️ **IMPORTANT**
- 🛠️ **Supported environments only:** We only support Windows 11. Custom ISOs that are not made using Microwin are not supported.
- 💡 For general questions, use the [Discussions section](https://github.com/Christitustech/winutil/discussions) or join our Community-driven [Discord Server](https://discord.gg/RUbZUZyByQ).
- type: checkboxes
attributes:
label: ⚙️ Issue Checklist
options:
- label: I have read the guidelines.
- label: I checked for duplicate issues.
- label: I searched for existing discussions.
- label: I checked for an existing pull request that addresses this issue.
validations:
required: true
- type: input
id: affected_part
attributes:
label: 📜 What part of Winutil are you having issues with?
placeholder: "e.g., Microwin, Tweaks, etc."
validations:
required: true
- type: textarea
id: issue_description
attributes:
label: 📝 Provide a clear and concise description of the issue.
validations:
required: true
- type: textarea
id: steps_to_reproduce
attributes:
label: 🔄 Steps to reproduce the issue.
placeholder: "e.g., Step 1: ..., Step 2: ..."
validations:
required: true
- type: textarea
id: error_output
attributes:
label: ❌ Paste the full error output (if available).
placeholder: "Include any relevant logs or error messages."
- type: textarea
id: additional_context
attributes:
label: 🖼️ Additional context.
placeholder: "Include screenshots, code blocks (use triple backticks ```), or any other relevant information."
validations:
required: false

View File

@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: 💻 Community Discord
url: https://discord.gg/RUbZUZyByQ
about: Join our Community Discord server to chat with other users in the Winutil community.

View File

@ -0,0 +1,24 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'enhancement'
assignees: ''
---
## Is your feature request related to a problem? Please describe
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
## Describe the solution you'd like
<!-- A clear and concise description of what you want to happen. -->
## Describe alternatives you've considered
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
## Additional context
<!-- Add any other context or screenshots about the feature request here. -->
## Issue validation
- [ ] I checked for duplicate issues.
- [ ] I checked for already existing discussions.
- [ ] I checked for an already existing pull request addressing the issue.

View File

@ -1,57 +0,0 @@
name: "Feature request"
description: "Suggest a new feature or improvement for the project."
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
# ✨ **Feature request**
Thank you for taking the time to suggest a feature! Please provide as much detail as possible to help us understand and evaluate your request.
## ⚠️ **IMPORTANT**
- 🛠️ **Supported environments only:** We only support Windows 11.
- 💡 For general questions, use the [Discussions section](https://github.com/Christitustech/winutil/discussions) or join our Community-driven [Discord Server](https://discord.gg/RUbZUZyByQ).
- type: checkboxes
attributes:
label: ⚙️ Issue Checklist
options:
- label: I have read the guidelines.
- label: I checked for duplicate issues.
- label: I searched for existing discussions.
- label: I checked for an existing pull request that addresses this request.
validations:
required: true
- type: textarea
id: problem_statement
attributes:
label: ❓ Is your feature request related to a problem?
placeholder: "Provide a clear and concise description of the issue you're facing. Example: 'I'm always frustrated when [...]'"
validations:
required: false
- type: textarea
id: proposed_solution
attributes:
label: 💡 Describe the solution you'd like
placeholder: "Provide a clear and concise description of what you want to happen."
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: 🔄 Describe alternatives you've considered
placeholder: "Provide details on any alternative solutions or features you've thought about."
validations:
required: false
- type: textarea
id: additional_context
attributes:
label: 🖼️ Additional context
placeholder: "Include screenshots, code blocks (use triple backticks ```), or any other relevant information."
validations:
required: false

View File

@ -15,7 +15,7 @@ gitdb==4.0.11
GitPython==3.1.43
htmlmin2==0.1.13
idna==3.7
Jinja2==3.1.5
Jinja2==3.1.4
jsmin==3.0.1
Markdown==3.6
MarkupSafe==2.1.5

View File

@ -60,7 +60,7 @@ jobs:
run: |
$cert = Get-ChildItem -Path Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1
if ($null -eq $cert) { throw "Code signing certificate not found" }
Set-AuthenticodeSignature -FilePath ./winutil.ps1 -Certificate $cert -TimeStampServer "http://timestamp.digicert.com"
Set-AuthenticodeSignature -FilePath ./winutil.ps1 -Certificate $cert
- name: Verify code signature
shell: pwsh

7
.gitignore vendored
View File

@ -2,7 +2,6 @@
# Configuration folder
.vscode/
.idea/
### Visual Studio ###
@ -11,9 +10,6 @@
winutil.pdb
### Preprocessor Hashes ###
.preprocessor_hashes.json
### Windows ###
# Folder config file
@ -50,7 +46,4 @@ True
test.ps1
winutil.ps1
# temporary excludes for docs
.github/site/
binary/

View File

@ -1,6 +1,7 @@
param (
[switch]$Debug,
[switch]$Run,
[switch]$SkipPreprocessing,
[string]$Arguments
)
@ -44,16 +45,17 @@ $header = @"
################################################################################################################
"@
if (-NOT $SkipPreprocessing) {
Update-Progress "Pre-req: Running Preprocessor..." 0
Update-Progress "Pre-req: Running Preprocessor..." 0
# Dot source the 'Invoke-Preprocessing' Function from 'tools/Invoke-Preprocessing.ps1' Script
$preprocessingFilePath = ".\tools\Invoke-Preprocessing.ps1"
. $preprocessingFilePath
# Dot source the 'Invoke-Preprocessing' Function from 'tools/Invoke-Preprocessing.ps1' Script
$preprocessingFilePath = ".\tools\Invoke-Preprocessing.ps1"
. $preprocessingFilePath
$excludedFiles = @('.\.git\', '.\.gitignore', '.\.gitattributes', '.\.github\CODEOWNERS', '.\LICENSE', "$preprocessingFilePath", '*.png', '*.exe','.\.preprocessor_hashes.json')
$msg = "Pre-req: Code Formatting"
Invoke-Preprocessing -WorkingDir "$workingdir" -ExcludedFiles $excludedFiles -ProgressStatusMessage $msg
$excludedFiles = @('.\.git\', '.\.gitignore', '.\.gitattributes', '.\.github\CODEOWNERS', '.\LICENSE', "$preprocessingFilePath", '*.png', '*.exe')
$msg = "Pre-req: Code Formatting"
Invoke-Preprocessing -WorkingDir "$workingdir" -ExcludedFiles $excludedFiles -ProgressStatusMessage $msg -ThrowExceptionOnEmptyFilesList
}
# Create the script in memory.
Update-Progress "Pre-req: Allocating Memory" 0

View File

@ -3,7 +3,6 @@
[![Version](https://img.shields.io/github/v/release/ChrisTitusTech/winutil?color=%230567ff&label=Latest%20Release&style=for-the-badge)](https://github.com/ChrisTitusTech/winutil/releases/latest)
![GitHub Downloads (specific asset, all releases)](https://img.shields.io/github/downloads/ChrisTitusTech/winutil/winutil.ps1?label=Total%20Downloads&style=for-the-badge)
[![](https://dcbadge.limes.pink/api/server/https://discord.gg/RUbZUZyByQ?theme=default-inverted&style=for-the-badge)](https://discord.gg/RUbZUZyByQ)
[![Static Badge](https://img.shields.io/badge/Documentation-_?style=for-the-badge&logo=bookstack&color=grey)](https://winutil.christitus.com/)
This utility is a compilation of Windows tasks I perform on each Windows system I use. It is meant to streamline *installs*, debloat with *tweaks*, troubleshoot with *config*, and fix Windows *updates*. I am extremely picky about any contributions to keep this project clean and efficient.
@ -35,11 +34,11 @@ irm "https://christitus.com/win" | iex
irm "https://christitus.com/windev" | iex
```
If you have Issues, refer to [Known Issues](https://winutil.christitus.com/knownissues/)
If you have Issues, refer to [Known Issues](https://christitustech.github.io/winutil/KnownIssues/)
## 🎓 Documentation
### [WinUtil Official Documentation](https://winutil.christitus.com/)
### [WinUtil Official Documentation](https://christitustech.github.io/winutil/)
### [YouTube Tutorial](https://www.youtube.com/watch?v=6UQZ5oQg8XA)
@ -53,7 +52,7 @@ If you have Issues, refer to [Known Issues](https://winutil.christitus.com/known
These are the sponsors that help keep this project alive with monthly contributions.
<!-- sponsors --><a href="https://github.com/TriHydera"><img src="https:&#x2F;&#x2F;github.com&#x2F;TriHydera.png" width="60px" alt="User avatar: TriHydera" /></a><a href="https://github.com/DelDongo"><img src="https:&#x2F;&#x2F;github.com&#x2F;DelDongo.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/markamos"><img src="https:&#x2F;&#x2F;github.com&#x2F;markamos.png" width="60px" alt="User avatar: Mark Amos" /></a><a href="https://github.com/dwelfusius"><img src="https:&#x2F;&#x2F;github.com&#x2F;dwelfusius.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/mews-se"><img src="https:&#x2F;&#x2F;github.com&#x2F;mews-se.png" width="60px" alt="User avatar: Martin Stockzell" /></a><a href="https://github.com/jdiegmueller"><img src="https:&#x2F;&#x2F;github.com&#x2F;jdiegmueller.png" width="60px" alt="User avatar: Jason A. Diegmueller" /></a><a href="https://github.com/altugtekiner"><img src="https:&#x2F;&#x2F;github.com&#x2F;altugtekiner.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/robertsandrock"><img src="https:&#x2F;&#x2F;github.com&#x2F;robertsandrock.png" width="60px" alt="User avatar: RMS" /></a><a href="https://github.com/KenichiQaz"><img src="https:&#x2F;&#x2F;github.com&#x2F;KenichiQaz.png" width="60px" alt="User avatar: Stefan" /></a><a href="https://github.com/paulsheets"><img src="https:&#x2F;&#x2F;github.com&#x2F;paulsheets.png" width="60px" alt="User avatar: Paul" /></a><a href="https://github.com/djones369"><img src="https:&#x2F;&#x2F;github.com&#x2F;djones369.png" width="60px" alt="User avatar: Dave J. - WhamGeek" /></a><a href="https://github.com/anthonymendez"><img src="https:&#x2F;&#x2F;github.com&#x2F;anthonymendez.png" width="60px" alt="User avatar: Anthony Mendez" /></a><a href="https://github.com/claudemods"><img src="https:&#x2F;&#x2F;github.com&#x2F;claudemods.png" width="60px" alt="User avatar: claudemods" /></a><a href="https://github.com/FatBastard0"><img src="https:&#x2F;&#x2F;github.com&#x2F;FatBastard0.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/Ascent7910"><img src="https:&#x2F;&#x2F;github.com&#x2F;Ascent7910.png" width="60px" alt="User avatar: Max" /></a><a href="https://github.com/DursleyGuy"><img src="https:&#x2F;&#x2F;github.com&#x2F;DursleyGuy.png" width="60px" alt="User avatar: DursleyGuy" /></a><a href="https://github.com/realmuddy"><img src="https:&#x2F;&#x2F;github.com&#x2F;realmuddy.png" width="60px" alt="User avatar: Phillip Waters" /></a><a href="https://github.com/quaszi"><img src="https:&#x2F;&#x2F;github.com&#x2F;quaszi.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DwayneTheRockLobster1"><img src="https:&#x2F;&#x2F;github.com&#x2F;DwayneTheRockLobster1.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/KieraKujisawa"><img src="https:&#x2F;&#x2F;github.com&#x2F;KieraKujisawa.png" width="60px" alt="User avatar: Kiera Meredith" /></a><!-- sponsors -->
<!-- sponsors --><a href="https://github.com/TriHydera"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;39857764?u&#x3D;5dbda638f45530582eee1703b4473f2a5e229e28&amp;v&#x3D;4" width="60px" alt="TriHydera" /></a><a href="https://github.com/jozozovko"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;3272468?u&#x3D;4391ed4655e4fd8b56e23b4169e44e2ac9b6cd97&amp;v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/DelDongo"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;127976398?v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/markamos"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;9561861?u&#x3D;3cca179dcff0413538591e57a3abea116d65ce56&amp;v&#x3D;4" width="60px" alt="Mark Amos" /></a><a href="https://github.com/dwelfusius"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;54533224?u&#x3D;a49ea000a8f52adb31382ea69a1a7501b27fefdd&amp;v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/mews-se"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;58894405?v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/jdiegmueller"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;18660571?u&#x3D;601d0a23040a271c86b5d40339f899a6dbf27086&amp;v&#x3D;4" width="60px" alt="Jason A. Diegmueller" /></a><a href="https://github.com/AlanTristar"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;105566568?v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/zepled112"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;65176625?v&#x3D;4" width="60px" alt="wyatt" /></a><a href="https://github.com/altugtekiner"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;105917451?u&#x3D;ee73ff639c7bd9feb4708ab4ba7b14eff80196f7&amp;v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/robertsandrock"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;12015331?u&#x3D;76849d3cb36b420922d235299558e00a09f2f8b4&amp;v&#x3D;4" width="60px" alt="RMS" /></a><a href="https://github.com/mmomega"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;71956566?v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/KenichiQaz"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;31177857?u&#x3D;efdbae734a4c60a7bb95df4659d0535e60a6fd57&amp;v&#x3D;4" width="60px" alt="Stefan" /></a><a href="https://github.com/paulsheets"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;45240946?u&#x3D;d4db66f8e8d7a2606fe7a5521daf48ca9f097105&amp;v&#x3D;4" width="60px" alt="Paul" /></a><a href="https://github.com/djones369"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;4107092?v&#x3D;4" width="60px" alt="Dave Jones" /></a><a href="https://github.com/anthonymendez"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;19240897?u&#x3D;f82b4be098cac65c8421421b70ebd2d1da85c67e&amp;v&#x3D;4" width="60px" alt="Anthony Mendez" /></a><a href="https://github.com/claudemods"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;73653396?u&#x3D;d64c656fb8db24ef56bb000197532df9b618d06c&amp;v&#x3D;4" width="60px" alt="Claudemods" /></a><a href="https://github.com/FatBastard0"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;173957728?v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/Ascent7910"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;118260621?v&#x3D;4" width="60px" alt="Max" /></a><a href="https://github.com/DursleyGuy"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;140165544?v&#x3D;4" width="60px" alt="DursleyGuy" /></a><a href="https://github.com/YamiSandman616"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;183505690?u&#x3D;c3bd20157058b6215e28f7568d4f8c4fbbe92838&amp;v&#x3D;4" width="60px" alt="Sandman616" /></a><a href="https://github.com/realmuddy"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;30978236?v&#x3D;4" width="60px" alt="Phillip Waters" /></a><a href="https://github.com/quaszi"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;51266738?u&#x3D;2e3185214607e51239c5969c866ddd5eb1bdee48&amp;v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/Psyhackological"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;47569716?u&#x3D;66dc5e86731eaf8c6bc78a1bff34420ed2e5402b&amp;v&#x3D;4" width="60px" alt="Konrad Konieczny" /></a><!-- sponsors -->
## 🏅 Thanks to all Contributors
Thanks a lot for spending your time helping Winutil grow. Thanks a lot! Keep rocking 🍻.

View File

@ -1,6 +1,5 @@
# Import the function (adjust the path according to your setup)
. "./functions/private/Install-WinUtilWinget.ps1"
. "./functions/private/Test-WinUtilPackageManager.ps1"
. "./functions/private/Get-WinUtilWingetLatest.ps1"
# Set up Information stream to be visible
$InformationPreference = "Continue"
@ -8,7 +7,20 @@ $InformationPreference = "Continue"
Write-Host "Starting Winget installation test..." -ForegroundColor Cyan
try {
Install-WinUtilWinget
# Test the function with verbose output
Write-Host "Attempting to run Get-WinUtilWingetLatest..." -ForegroundColor Cyan
Get-WinUtilWingetLatest -Verbose
# Verify Winget is working
if (Get-Command winget -ErrorAction SilentlyContinue) {
Write-Host "Success! Winget is installed and accessible." -ForegroundColor Green
# Display Winget version
Write-Host "`nWinget version:" -ForegroundColor Cyan
winget --version
} else {
Write-Host "Warning: Winget is installed but not accessible in the current session. You may need to restart your terminal." -ForegroundColor Yellow
}
} catch {
Write-Host "Error occurred during testing: $($_.Exception.Message)" -ForegroundColor Red
Write-Host "Stack Trace:" -ForegroundColor Red

View File

@ -527,6 +527,14 @@
"link": "https://espanso.org/",
"winget": "Espanso.Espanso"
},
"etcher": {
"category": "Utilities",
"choco": "etcher",
"content": "Etcher USB Creator",
"description": "Etcher is a powerful tool for creating bootable USB drives with ease.",
"link": "https://www.balena.io/etcher/",
"winget": "Balena.Etcher"
},
"falkon": {
"category": "Browsers",
"choco": "falkon",
@ -675,9 +683,9 @@
"category": "Multimedia Tools",
"choco": "fxsound",
"content": "FxSound",
"description": "FxSound is free open-source software to boost sound quality, volume, and bass. Including an equalizer, effects, and presets for customized audio.",
"description": "FxSound is a cutting-edge audio enhancement software that elevates your listening experience across all media.",
"link": "https://www.fxsound.com/",
"winget": "FxSound.FxSound"
"winget": "FxSoundLLC.FxSound"
},
"fzf": {
"category": "Utilities",
@ -701,7 +709,7 @@
"content": "GIMP (Image Editor)",
"description": "GIMP is a versatile open-source raster graphics editor used for tasks such as photo retouching, image editing, and image composition.",
"link": "https://www.gimp.org/",
"winget": "GIMP.GIMP.3"
"winget": "GIMP.GIMP"
},
"git": {
"category": "Development",
@ -908,7 +916,7 @@
"choco": "imgburn",
"content": "ImgBurn",
"description": "ImgBurn is a lightweight CD, DVD, HD-DVD, and Blu-ray burning application with advanced features for creating and burning disc images.",
"link": "https://www.imgburn.com/",
"link": "http://www.imgburn.com/",
"winget": "LIGHTNINGUK.ImgBurn"
},
"inkscape": {
@ -980,7 +988,7 @@
"choco": "jdownloader",
"content": "JDownloader",
"description": "JDownloader is a feature-rich download manager with support for various file hosting services.",
"link": "https://jdownloader.org/",
"link": "http://jdownloader.org/",
"winget": "AppWork.JDownloader"
},
"jellyfinmediaplayer": {
@ -1372,7 +1380,7 @@
"choco": "na",
"content": "nGlide (3dfx compatibility)",
"description": "nGlide is a 3Dfx Voodoo Glide wrapper. It allows you to play games that use Glide API on modern graphics cards without the need for a 3Dfx Voodoo graphics card.",
"link": "https://www.zeus-software.com/downloads/nglide",
"link": "http://www.zeus-software.com/downloads/nglide",
"winget": "ZeusSoftware.nGlide"
},
"nmap": {
@ -1503,6 +1511,14 @@
"link": "https://github.com/namazso/OpenHashTab/",
"winget": "namazso.OpenHashTab"
},
"openoffice": {
"category": "Document",
"choco": "openoffice",
"content": "Apache OpenOffice",
"description": "Apache OpenOffice is an open-source office software suite for word processing, spreadsheets, presentations, and more.",
"link": "https://www.openoffice.org/",
"winget": "Apache.OpenOffice"
},
"openrgb": {
"category": "Utilities",
"choco": "openrgb",
@ -1683,7 +1699,7 @@
"category": "Games",
"choco": "prismlauncher",
"content": "Prism Launcher",
"description": "Prism Launcher is an Open Source Minecraft launcher with the ability to manage multiple instances, accounts and mods.",
"description": "Prism Launcher is a game launcher and manager designed to provide a clean and intuitive interface for organizing and launching your games.",
"link": "https://prismlauncher.org/",
"winget": "PrismLauncher.PrismLauncher"
},
@ -2188,7 +2204,7 @@
"choco": "na",
"content": "Thorium Browser AVX2",
"description": "Browser built for speed over vanilla chromium. It is built with AVX2 optimizations and is the fastest browser on the market.",
"link": "https://thorium.rocks/",
"link": "http://thorium.rocks/",
"winget": "Alex313031.Thorium.AVX2"
},
"thunderbird": {
@ -2445,7 +2461,7 @@
"content": "UniGetUI",
"description": "UniGetUI is a GUI for Winget, Chocolatey, and other Windows CLI package managers.",
"link": "https://www.marticliment.com/wingetui/",
"winget": "MartiCliment.UniGetUI"
"winget": "SomePythonThings.WingetUIStore"
},
"winmerge": {
"category": "Document",
@ -2918,13 +2934,5 @@
"description": "Fork - a fast and friendly git client.",
"link": "https://git-fork.com/",
"winget": "Fork.Fork"
},
"ZenBrowser": {
"category": "Browsers",
"choco": "na",
"content": "Zen Browser",
"description": "The modern, privacy-focused, performance-driven browser built on Firefox",
"link": "https://zen-browser.app/",
"winget": "Zen-Team.Zen-Browser"
}
}

View File

@ -1,48 +0,0 @@
{
"WPFToggleView": {
"Content": ["Expanded View", "Compact View"],
"Category": "____Actions",
"Type": "ToggleButton",
"Order": "1",
"Description": "Toggle between a list and a compact grid like view"
},
"WPFSelectedFilter": {
"Content": [ "Show All", "Show Selected"],
"Category": "____Actions",
"Type": "ToggleButton",
"Order": "2",
"Description": "Toggle between showing all or only the selected applications"
},
"WPFClearInstallSelection": {
"Content": "Clear Selection",
"Category": "____Actions",
"Type": "Button",
"Order": "3",
"Description": "Clear the selection of applications"
},
"WPFGetInstalled": {
"Content": "Get Installed",
"Category": "____Actions",
"Type": "Button",
"Order": "4",
"Description": "Show installed applications"
},
"WingetRadioButton": {
"Content": "Winget",
"Category": "__Package Manager",
"Type": "RadioButton",
"GroupName": "PackageManagerGroup",
"Checked": true,
"Order": "1",
"Description": "Use Winget for package management"
},
"ChocoRadioButton": {
"Content": "Chocolatey",
"Category": "__Package Manager",
"Type": "RadioButton",
"GroupName": "PackageManagerGroup",
"Checked": false,
"Order": "2",
"Description": "Use Chocolatey for package management"
}
}

View File

@ -10,7 +10,7 @@
"NetFx3"
],
"InvokeScript": [],
"link": "https://winutil.christitus.com/dev/features/features/dotnet"
"link": "https://christitustech.github.io/winutil/dev/features/Features/dotnet"
},
"WPFFeatureshyperv": {
"Content": "HyperV Virtualization",
@ -31,7 +31,7 @@
"InvokeScript": [
"Start-Process -FilePath cmd.exe -ArgumentList '/c bcdedit /set hypervisorschedulertype classic' -Wait"
],
"link": "https://winutil.christitus.com/dev/features/features/hyperv"
"link": "https://christitustech.github.io/winutil/dev/features/Features/hyperv"
},
"WPFFeatureslegacymedia": {
"Content": "Legacy Media (WMP, DirectPlay)",
@ -46,7 +46,7 @@
"LegacyComponents"
],
"InvokeScript": [],
"link": "https://winutil.christitus.com/dev/features/features/legacymedia"
"link": "https://christitustech.github.io/winutil/dev/features/Features/legacymedia"
},
"WPFFeaturewsl": {
"Content": "Windows Subsystem for Linux",
@ -59,7 +59,7 @@
"Microsoft-Windows-Subsystem-Linux"
],
"InvokeScript": [],
"link": "https://winutil.christitus.com/dev/features/features/wsl"
"link": "https://christitustech.github.io/winutil/dev/features/Features/wsl"
},
"WPFFeaturenfs": {
"Content": "NFS - Network File System",
@ -79,7 +79,7 @@
"nfsadmin client start",
"nfsadmin client localhost config fileaccess=755 SecFlavors=+sys -krb5 -krb5i"
],
"link": "https://winutil.christitus.com/dev/features/features/nfs"
"link": "https://christitustech.github.io/winutil/dev/features/Features/nfs"
},
"WPFFeatureEnableSearchSuggestions": {
"Content": "Enable Search Box Web Suggestions in Registry(explorer restart)",
@ -97,7 +97,7 @@
Stop-Process -name explorer -force
"
],
"link": "https://winutil.christitus.com/dev/features/features/enablesearchsuggestions"
"link": "https://christitustech.github.io/winutil/dev/features/Features/EnableSearchSuggestions"
},
"WPFFeatureDisableSearchSuggestions": {
"Content": "Disable Search Box Web Suggestions in Registry(explorer restart)",
@ -115,7 +115,7 @@
Stop-Process -name explorer -force
"
],
"link": "https://winutil.christitus.com/dev/features/features/disablesearchsuggestions"
"link": "https://christitustech.github.io/winutil/dev/features/Features/DisableSearchSuggestions"
},
"WPFFeatureRegBackup": {
"Content": "Enable Daily Registry Backup Task 12.30am",
@ -133,7 +133,7 @@
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName 'AutoRegBackup' -Description 'Create System Registry Backups' -User 'System'
"
],
"link": "https://winutil.christitus.com/dev/features/features/regbackup"
"link": "https://christitustech.github.io/winutil/dev/features/Features/RegBackup"
},
"WPFFeatureEnableLegacyRecovery": {
"Content": "Enable Legacy F8 Boot Recovery",
@ -151,7 +151,7 @@
Start-Process -FilePath cmd.exe -ArgumentList '/c bcdedit /Set {Current} BootMenuPolicy Legacy' -Wait
"
],
"link": "https://winutil.christitus.com/dev/features/features/enablelegacyrecovery"
"link": "https://christitustech.github.io/winutil/dev/features/Features/EnableLegacyRecovery"
},
"WPFFeatureDisableLegacyRecovery": {
"Content": "Disable Legacy F8 Boot Recovery",
@ -169,7 +169,7 @@
Start-Process -FilePath cmd.exe -ArgumentList '/c bcdedit /Set {Current} BootMenuPolicy Standard' -Wait
"
],
"link": "https://winutil.christitus.com/dev/features/features/disablelegacyrecovery"
"link": "https://christitustech.github.io/winutil/dev/features/Features/DisableLegacyRecovery"
},
"WPFFeaturesSandbox": {
"Content": "Windows Sandbox",
@ -177,7 +177,7 @@
"panel": "1",
"Order": "a021_",
"Description": "Windows Sandbox is a lightweight virtual machine that provides a temporary desktop environment to safely run applications and programs in isolation.",
"link": "https://winutil.christitus.com/dev/features/features/sandbox"
"link": "https://christitustech.github.io/winutil/dev/features/Features/Sandbox"
},
"WPFFeatureInstall": {
"Content": "Install Features",
@ -186,7 +186,7 @@
"Order": "a060_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/features/install"
"link": "https://christitustech.github.io/winutil/dev/features/Features/Install"
},
"WPFPanelAutologin": {
"Content": "Set Up Autologin",
@ -195,7 +195,7 @@
"panel": "1",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/fixes/autologin"
"link": "https://christitustech.github.io/winutil/dev/features/Fixes/Autologin"
},
"WPFFixesUpdate": {
"Content": "Reset Windows Update",
@ -204,7 +204,7 @@
"Order": "a041_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/fixes/update"
"link": "https://christitustech.github.io/winutil/dev/features/Fixes/Update"
},
"WPFFixesNetwork": {
"Content": "Reset Network",
@ -213,7 +213,7 @@
"panel": "1",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/fixes/network"
"link": "https://christitustech.github.io/winutil/dev/features/Fixes/Network"
},
"WPFPanelDISM": {
"Content": "System Corruption Scan",
@ -222,7 +222,7 @@
"Order": "a043_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/fixes/dism"
"link": "https://christitustech.github.io/winutil/dev/features/Fixes/DISM"
},
"WPFFixesWinget": {
"Content": "WinGet Reinstall",
@ -231,7 +231,7 @@
"Order": "a044_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/fixes/winget"
"link": "https://christitustech.github.io/winutil/dev/features/Fixes/Winget"
},
"WPFRunAdobeCCCleanerTool": {
"Content": "Remove Adobe Creative Cloud",
@ -240,7 +240,7 @@
"Order": "a045_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/fixes/runadobecccleanertool"
"link": "https://christitustech.github.io/winutil/dev/features/Fixes/RunAdobeCCCleanerTool"
},
"WPFPanelnetwork": {
"Content": "Network Connections",
@ -248,7 +248,7 @@
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/network"
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/network"
},
"WPFPanelcontrol": {
"Content": "Control Panel",
@ -256,7 +256,7 @@
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/control"
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/control"
},
"WPFPanelpower": {
"Content": "Power Panel",
@ -264,7 +264,7 @@
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/power"
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/power"
},
"WPFPanelregion": {
"Content": "Region",
@ -272,7 +272,7 @@
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/region"
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/region"
},
"WPFPanelsound": {
"Content": "Sound Settings",
@ -280,7 +280,7 @@
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/sound"
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/sound"
},
"WPFPanelprinter": {
"Content": "Printer Panel",
@ -288,7 +288,7 @@
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/printer"
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/printer"
},
"WPFPanelsystem": {
"Content": "System Properties",
@ -296,7 +296,7 @@
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/system"
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/system"
},
"WPFPaneluser": {
"Content": "User Accounts",
@ -304,14 +304,7 @@
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/user"
},
"WPFPanelGodMode": {
"Content": "God Mode",
"category": "Legacy Windows Panels",
"panel": "2",
"Type": "Button",
"ButtonWidth": "300"
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/user"
},
"WPFWinUtilInstallPSProfile": {
"Content": "Install CTT PowerShell Profile",
@ -319,7 +312,8 @@
"panel": "2",
"Order": "a083_",
"Type": "Button",
"ButtonWidth": "300"
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Powershell-Profile/PSProfileInstall"
},
"WPFWinUtilUninstallPSProfile": {
"Content": "Uninstall CTT PowerShell Profile",
@ -327,7 +321,8 @@
"panel": "2",
"Order": "a084_",
"Type": "Button",
"ButtonWidth": "300"
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Powershell-Profile/PSProfileUninstall"
},
"WPFWinUtilSSHServer": {
"Content": "Enable OpenSSH Server",

View File

@ -2,7 +2,6 @@
"Standard": [
"WPFTweaksAH",
"WPFTweaksConsumerFeatures",
"WPFTweaksDisableExplorerAutoDiscovery",
"WPFTweaksDVR",
"WPFTweaksHiber",
"WPFTweaksHome",
@ -19,7 +18,6 @@
],
"Minimal": [
"WPFTweaksConsumerFeatures",
"WPFTweaksDisableExplorerAutoDiscovery",
"WPFTweaksHome",
"WPFTweaksServices",
"WPFTweaksTele"

View File

@ -7,7 +7,7 @@
"CustomDialogHeight": "200",
"FontSize": "12",
"FontFamily": "Arial",
"HeaderFontSize": "16",
"HeadingFontSize": "16",
"HeaderFontFamily": "Consolas, Monaco",
"CheckBoxBulletDecoratorSize": "14",
"CheckBoxMargin": "15,0,0,2",
@ -35,13 +35,9 @@
"CheckboxMouseOverColor": "#999999",
"ButtonBorderThickness": "1",
"ButtonMargin": "1",
"ButtonCornerRadius": "2",
"AppTileImageSize": "40"
"ButtonCornerRadius": "2"
},
"Light": {
"AppInstallUnselectedColor": "#F0F0F0",
"AppInstallHighlightedColor": "#CFCFCF",
"AppInstallSelectedColor": "#C2C2C2",
"ComboBoxForegroundColor": "#232629",
"ComboBoxBackgroundColor": "#F7F7F7",
"LabelboxForegroundColor": "#232629",
@ -77,9 +73,6 @@
},
"Dark": {
"AppInstallUnselectedColor": "#232629",
"AppInstallHighlightedColor": "#3C3C3C",
"AppInstallSelectedColor": "#4C4C4C",
"ComboBoxForegroundColor": "#F7F7F7",
"ComboBoxBackgroundColor": "#1E3747",
"LabelboxForegroundColor": "#0567ff",

View File

@ -28,7 +28,7 @@
"OriginalValue": "<RemoveEntry>"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/ah"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/AH"
},
"WPFTweaksHiber": {
"Content": "Disable Hibernation",
@ -58,7 +58,7 @@
"UndoScript": [
"powercfg.exe /hibernate on"
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/hiber"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/Hiber"
},
"WPFTweaksLaptopHibernation": {
"Content": "Set Hibernation as default (good for laptops)",
@ -106,7 +106,7 @@
Start-Process -FilePath powercfg -ArgumentList \"/change monitor-timeout-dc 15\" -NoNewWindow -Wait
"
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/laptophibernation"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/LaptopHibernation"
},
"WPFTweaksHome": {
"Content": "Disable Homegroup",
@ -126,7 +126,7 @@
"OriginalType": "Automatic"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/home"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/Home"
},
"WPFTweaksLoc": {
"Content": "Disable Location Tracking",
@ -164,7 +164,7 @@
"OriginalValue": "1"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/loc"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/Loc"
},
"WPFTweaksServices": {
"Content": "Set Services to Manual",
@ -423,6 +423,26 @@
"StartupType": "Automatic",
"OriginalType": "Automatic"
},
{
"Name": "DoSvc",
"StartupType": "AutomaticDelayedStart",
"OriginalType": "Automatic"
},
{
"Name": "DsSvc",
"StartupType": "Manual",
"OriginalType": "Manual"
},
{
"Name": "DsmSvc",
"StartupType": "Manual",
"OriginalType": "Manual"
},
{
"Name": "DusmSvc",
"StartupType": "Automatic",
"OriginalType": "Automatic"
},
{
"Name": "EFS",
"StartupType": "Manual",
@ -878,6 +898,11 @@
"StartupType": "Manual",
"OriginalType": "Manual"
},
{
"Name": "SgrmBroker",
"StartupType": "Automatic",
"OriginalType": "Automatic"
},
{
"Name": "SharedAccess",
"StartupType": "Manual",
@ -908,6 +933,11 @@
"StartupType": "Manual",
"OriginalType": "Manual"
},
{
"Name": "StateRepository",
"StartupType": "Manual",
"OriginalType": "Automatic"
},
{
"Name": "StiSvc",
"StartupType": "Manual",
@ -943,6 +973,11 @@
"StartupType": "Automatic",
"OriginalType": "Automatic"
},
{
"Name": "TextInputManagementService",
"StartupType": "Manual",
"OriginalType": "Automatic"
},
{
"Name": "Themes",
"StartupType": "Automatic",
@ -1549,7 +1584,7 @@
"OriginalType": "Manual"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/services"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/Services"
},
"WPFTweaksEdgeDebloat": {
"Content": "Debloat Edge",
@ -1685,7 +1720,7 @@
"OriginalValue": "<RemoveEntry>"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/edgedebloat"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/EdgeDebloat"
},
"WPFTweaksConsumerFeatures": {
"Content": "Disable ConsumerFeatures",
@ -1702,7 +1737,7 @@
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/consumerfeatures"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/ConsumerFeatures"
},
"WPFTweaksTele": {
"Content": "Disable Telemetry",
@ -2074,7 +2109,7 @@
Set-MpPreference -SubmitSamplesConsent 2 -ErrorAction SilentlyContinue | Out-Null
"
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/tele"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/Tele"
},
"WPFTweaksWifi": {
"Content": "Disable Wifi-Sense",
@ -2098,7 +2133,7 @@
"OriginalValue": "1"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/wifi"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/Wifi"
},
"WPFTweaksUTC": {
"Content": "Set Time to UTC (Dual Boot)",
@ -2115,7 +2150,7 @@
"OriginalValue": "0"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/utc"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/UTC"
},
"WPFTweaksRemoveHomeGallery": {
"Content": "Remove Home and Gallery from explorer",
@ -2137,7 +2172,7 @@
REG DELETE \"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\" /f /v \"LaunchTo\"
"
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/removehomegallery"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveHomeGallery"
},
"WPFTweaksDisplay": {
"Content": "Set Display for Performance",
@ -2244,7 +2279,7 @@
"UndoScript": [
"Remove-ItemProperty -Path \"HKCU:\\Control Panel\\Desktop\" -Name \"UserPreferencesMask\""
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/display"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/Display"
},
"WPFTweaksDeBloat": {
"Content": "Remove ALL MS Store Apps - NOT RECOMMENDED",
@ -2356,7 +2391,7 @@
}
"
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/debloat"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/DeBloat"
},
"WPFTweaksRestorePoint": {
"Content": "Create Restore Point",
@ -2407,7 +2442,7 @@
}
"
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/restorepoint"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/RestorePoint"
},
"WPFTweaksEndTaskOnTaskbar": {
"Content": "Enable End Task With Right Click",
@ -2441,7 +2476,7 @@
# Set the property, creating it if it doesn't exist
New-ItemProperty -Path $path -Name $name -PropertyType DWord -Value $value -Force | Out-Null"
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/endtaskontaskbar"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/EndTaskOnTaskbar"
},
"WPFTweaksPowershell7": {
"Content": "Change Windows Terminal default: PowerShell 5 -> PowerShell 7",
@ -2455,7 +2490,7 @@
"UndoScript": [
"Invoke-WPFTweakPS7 -action \"PS5\""
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/powershell7"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/Powershell7"
},
"WPFTweaksPowershell7Tele": {
"Content": "Disable Powershell 7 Telemetry",
@ -2469,7 +2504,7 @@
"UndoScript": [
"[Environment]::SetEnvironmentVariable('POWERSHELL_TELEMETRY_OPTOUT', '', 'Machine')"
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/powershell7tele"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/Powershell7Tele"
},
"WPFTweaksStorage": {
"Content": "Disable Storage Sense",
@ -2483,7 +2518,7 @@
"UndoScript": [
"Set-ItemProperty -Path \"HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\StorageSense\\Parameters\\StoragePolicy\" -Name \"01\" -Value 1 -Type Dword -Force"
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/storage"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/Storage"
},
"WPFTweaksRemoveEdge": {
"Content": "Remove Microsoft Edge",
@ -2497,7 +2532,7 @@
"UndoScript": [
"Uninstall-WinUtilEdgeBrowser -action \"Install\""
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/removeedge"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveEdge"
},
"WPFTweaksRemoveCopilot": {
"Content": "Disable Microsoft Copilot",
@ -2540,7 +2575,7 @@
dism /online /add-package /package-name:Microsoft.Windows.Copilot
"
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/removecopilot"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveCopilot"
},
"WPFTweaksRecallOff": {
"Content": "Disable Recall",
@ -2550,6 +2585,7 @@
"Order": "a011_",
"registry": [
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsAI",
"Name": "DisableAIDataAnalysis",
"Type": "DWord",
@ -2560,18 +2596,16 @@
"InvokeScript": [
"
Write-Host \"Disable Recall\"
DISM /Online /Disable-Feature /FeatureName:Recall /Quiet /NoRestart
Write-Host \"Please restart your computer in order for the changes to be fully applied.\"
DISM /Online /Disable-Feature /FeatureName:Recall
"
],
"UndoScript": [
"
Write-Host \"Enable Recall\"
DISM /Online /Enable-Feature /FeatureName:Recall /Quiet /NoRestart
Write-Host \"Please restart your computer in order for the changes to be fully applied.\"
DISM /Online /Enable-Feature /FeatureName:Recall
"
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/disablerecall"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DisableRecall"
},
"WPFTweaksDisableLMS1": {
"Content": "Disable Intel MM (vPro LMS)",
@ -2629,23 +2663,7 @@
"
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/disablelms1"
},
"WPFTweaksDisableWpbtExecution": {
"Content": "Disable Windows Platform Binary Table (WPBT)",
"Description": "If enabled then allows your computer vendor to execute a program each time it boots. It enables computer vendors to force install anti-theft software, software drivers, or a software program conveniently. This could also be a security risk.",
"category": "z__Advanced Tweaks - CAUTION",
"panel": "1",
"Order": "a027_",
"registry": [
{
"Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager",
"Name": "DisableWpbtExecution",
"Value": "1",
"OriginalValue": "<RemoveEntry>",
"Type": "DWord"
}
]
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableLMS1"
},
"WPFTweaksRemoveOnedrive": {
"Content": "Remove OneDrive",
@ -2752,7 +2770,7 @@
Start-Process -FilePath winget -ArgumentList \"install -e --accept-source-agreements --accept-package-agreements --silent Microsoft.OneDrive \" -NoNewWindow -Wait
"
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/removeonedrive"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveOnedrive"
},
"WPFTweaksRazerBlock": {
"Content": "Block Razer Software Installs",
@ -2794,7 +2812,7 @@
New-Item -Path \"C:\\Windows\\Installer\\\" -Name \"Razer\" -ItemType \"directory\"
"
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/razerblock"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/RazerBlock"
},
"WPFTweaksDisableNotifications": {
"Content": "Disable Notification Tray/Calendar",
@ -2818,7 +2836,7 @@
"OriginalValue": "1"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/disablenotifications"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableNotifications"
},
"WPFTweaksDebloatAdobe": {
"Content": "Adobe Debloat",
@ -2967,7 +2985,7 @@
"OriginalType": "Automatic"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/debloatadobe"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/DebloatAdobe"
},
"WPFTweaksBlockAdobeNet": {
"Content": "Adobe Network Block",
@ -3075,7 +3093,7 @@
}
"
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/blockadobenet"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/BlockAdobeNet"
},
"WPFTweaksRightClickMenu": {
"Content": "Set Classic Right-Click Menu ",
@ -3100,7 +3118,7 @@
Stop-Process -InputObject $process
"
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/rightclickmenu"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RightClickMenu"
},
"WPFTweaksDiskCleanup": {
"Content": "Run Disk Cleanup",
@ -3114,7 +3132,7 @@
Dism.exe /online /Cleanup-Image /StartComponentCleanup /ResetBase
"
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/diskcleanup"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DiskCleanup"
},
"WPFTweaksDeleteTempFiles": {
"Content": "Delete Temporary Files",
@ -3126,7 +3144,7 @@
"Get-ChildItem -Path \"C:\\Windows\\Temp\" *.* -Recurse | Remove-Item -Force -Recurse
Get-ChildItem -Path $env:TEMP *.* -Recurse | Remove-Item -Force -Recurse"
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/deletetempfiles"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DeleteTempFiles"
},
"WPFTweaksDVR": {
"Content": "Disable GameDVR",
@ -3171,7 +3189,7 @@
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/dvr"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DVR"
},
"WPFTweaksIPv46": {
"Content": "Prefer IPv4 over IPv6",
@ -3188,7 +3206,7 @@
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/ipv46"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/IPv46"
},
"WPFTweaksTeredo": {
"Content": "Disable Teredo",
@ -3211,7 +3229,7 @@
"UndoScript": [
"netsh interface teredo set state default"
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/teredo"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/Teredo"
},
"WPFTweaksDisableipsix": {
"Content": "Disable IPv6",
@ -3234,7 +3252,7 @@
"UndoScript": [
"Enable-NetAdapterBinding -Name \"*\" -ComponentID ms_tcpip6"
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/disableipsix"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/Disableipsix"
},
"WPFTweaksDisableBGapps": {
"Content": "Disable Background Apps",
@ -3251,7 +3269,7 @@
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/disablebgapps"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableBGapps"
},
"WPFTweaksDisableFSO": {
"Content": "Disable Fullscreen Optimizations",
@ -3268,7 +3286,7 @@
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/disablefso"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableFSO"
},
"WPFToggleDarkMode": {
"Content": "Dark Theme for Windows",
@ -3283,7 +3301,6 @@
"Name": "AppsUseLightTheme",
"Value": "0",
"OriginalValue": "1",
"DefaultState": "false",
"Type": "DWord"
},
{
@ -3291,7 +3308,6 @@
"Name": "SystemUsesLightTheme",
"Value": "0",
"OriginalValue": "1",
"DefaultState": "false",
"Type": "DWord"
}
],
@ -3311,7 +3327,7 @@
}
"
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/darkmode"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/DarkMode"
},
"WPFToggleBingSearch": {
"Content": "Bing Search in Start Menu",
@ -3326,11 +3342,10 @@
"Name": "BingSearchEnabled",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "true",
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/bingsearch"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/BingSearch"
},
"WPFToggleNumLock": {
"Content": "NumLock on Startup",
@ -3345,7 +3360,6 @@
"Name": "InitialKeyboardIndicators",
"Value": "2",
"OriginalValue": "0",
"DefaultState": "false",
"Type": "DWord"
},
{
@ -3353,11 +3367,10 @@
"Name": "InitialKeyboardIndicators",
"Value": "2",
"OriginalValue": "0",
"DefaultState": "false",
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/numlock"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/NumLock"
},
"WPFToggleVerboseLogon": {
"Content": "Verbose Messages During Logon",
@ -3372,71 +3385,17 @@
"Name": "VerboseStatus",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "false",
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/verboselogon"
},
"WPFToggleStartMenuRecommendations": {
"Content": "Recommendations in Start Menu",
"Description": "If disabled then you will not see recommendations in the Start Menu. | Enables 'iseducationenvironment' | Relogin Required.",
"category": "Customize Preferences",
"panel": "2",
"Order": "a104_",
"Type": "Toggle",
"registry": [
{
"Path": "HKLM:\\SOFTWARE\\Microsoft\\PolicyManager\\current\\device\\Start",
"Name": "HideRecommendedSection",
"Value": "0",
"OriginalValue": "1",
"DefaultState": "true",
"Type": "DWord"
},
{
"Path": "HKLM:\\SOFTWARE\\Microsoft\\PolicyManager\\current\\device\\Education",
"Name": "IsEducationEnvironment",
"Value": "0",
"OriginalValue": "1",
"DefaultState": "true",
"Type": "DWord"
},
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer",
"Name": "HideRecommendedSection",
"Value": "0",
"OriginalValue": "1",
"DefaultState": "true",
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/wpftogglestartmenurecommendations"
},
"WPFToggleHideSettingsHome": {
"Content": "Remove Settings Home Page",
"Description": "Removes the Home page in the Windows Settings app.",
"category": "Customize Preferences",
"panel": "2",
"Order": "a105_",
"Type": "Toggle",
"registry": [
{
"Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
"Name": "SettingsPageVisibility",
"Type": "String",
"Value": "hide:home",
"OriginalValue": "show:home",
"DefaultState": "false"
}
]
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/VerboseLogon"
},
"WPFToggleSnapWindow": {
"Content": "Snap Window",
"Description": "If enabled you can align windows by dragging them. | Relogin Required",
"category": "Customize Preferences",
"panel": "2",
"Order": "a106_",
"Order": "a104_",
"Type": "Toggle",
"registry": [
{
@ -3444,18 +3403,17 @@
"Name": "WindowArrangementActive",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "true",
"Type": "String"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/snapwindow"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/SnapWindow"
},
"WPFToggleSnapFlyout": {
"Content": "Snap Assist Flyout",
"Description": "If enabled then Snap preview is disabled when maximize button is hovered.",
"category": "Customize Preferences",
"panel": "2",
"Order": "a107_",
"Order": "a105_",
"Type": "Toggle",
"registry": [
{
@ -3463,7 +3421,6 @@
"Name": "EnableSnapAssistFlyout",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "true",
"Type": "DWord"
}
],
@ -3477,14 +3434,14 @@
Invoke-WinUtilExplorerUpdate -action \"restart\"
"
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/snapflyout"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/SnapFlyout"
},
"WPFToggleSnapSuggestion": {
"Content": "Snap Assist Suggestion",
"Description": "If enabled then you will get suggestions to snap other applications in the left over spaces.",
"category": "Customize Preferences",
"panel": "2",
"Order": "a108_",
"Order": "a106_",
"Type": "Toggle",
"registry": [
{
@ -3492,7 +3449,6 @@
"Name": "SnapAssist",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "true",
"Type": "DWord"
}
],
@ -3506,14 +3462,14 @@
Invoke-WinUtilExplorerUpdate -action \"restart\"
"
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/snapsuggestion"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/SnapSuggestion"
},
"WPFToggleMouseAcceleration": {
"Content": "Mouse Acceleration",
"Description": "If Enabled then Cursor movement is affected by the speed of your physical mouse movements.",
"category": "Customize Preferences",
"panel": "2",
"Order": "a109_",
"Order": "a107_",
"Type": "Toggle",
"registry": [
{
@ -3521,7 +3477,6 @@
"Name": "MouseSpeed",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "true",
"Type": "DWord"
},
{
@ -3529,7 +3484,6 @@
"Name": "MouseThreshold1",
"Value": "6",
"OriginalValue": "0",
"DefaultState": "true",
"Type": "DWord"
},
{
@ -3537,18 +3491,17 @@
"Name": "MouseThreshold2",
"Value": "10",
"OriginalValue": "0",
"DefaultState": "true",
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/mouseacceleration"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/MouseAcceleration"
},
"WPFToggleStickyKeys": {
"Content": "Sticky Keys",
"Description": "If Enabled then Sticky Keys is activated - Sticky keys is an accessibility feature of some graphical user interfaces which assists users who have physical disabilities or help users reduce repetitive strain injury.",
"category": "Customize Preferences",
"panel": "2",
"Order": "a110_",
"Order": "a108_",
"Type": "Toggle",
"registry": [
{
@ -3556,11 +3509,10 @@
"Name": "Flags",
"Value": "510",
"OriginalValue": "58",
"DefaultState": "true",
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/stickykeys"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/StickyKeys"
},
"WPFToggleHiddenFiles": {
"Content": "Show Hidden Files",
@ -3575,7 +3527,6 @@
"Name": "Hidden",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "false",
"Type": "DWord"
}
],
@ -3589,7 +3540,7 @@
Invoke-WinUtilExplorerUpdate -action \"restart\"
"
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/hiddenfiles"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/HiddenFiles"
},
"WPFToggleShowExt": {
"Content": "Show File Extensions",
@ -3604,7 +3555,6 @@
"Name": "HideFileExt",
"Value": "0",
"OriginalValue": "1",
"DefaultState": "false",
"Type": "DWord"
}
],
@ -3618,7 +3568,7 @@
Invoke-WinUtilExplorerUpdate -action \"restart\"
"
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/showext"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/ShowExt"
},
"WPFToggleTaskbarSearch": {
"Content": "Search Button in Taskbar",
@ -3633,11 +3583,10 @@
"Name": "SearchboxTaskbarMode",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "true",
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/taskbarsearch"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/TaskbarSearch"
},
"WPFToggleTaskView": {
"Content": "Task View Button in Taskbar",
@ -3652,11 +3601,10 @@
"Name": "ShowTaskViewButton",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "true",
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/taskview"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/TaskView"
},
"WPFToggleTaskbarWidgets": {
"Content": "Widgets Button in Taskbar",
@ -3671,11 +3619,10 @@
"Name": "TaskbarDa",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "true",
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/taskbarwidgets"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/TaskbarWidgets"
},
"WPFToggleTaskbarAlignment": {
"Content": "Center Taskbar Items",
@ -3690,11 +3637,10 @@
"Name": "TaskbarAl",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "true",
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/taskbaralignment"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/TaskbarAlignment"
},
"WPFToggleDetailedBSoD": {
"Content": "Detailed BSoD",
@ -3709,7 +3655,6 @@
"Name": "DisplayParameters",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "false",
"Type": "DWord"
},
{
@ -3717,11 +3662,10 @@
"Name": "DisableEmoticon",
"Value": "1",
"OriginalValue": "0",
"DefaultState": "false",
"Type": "DWord"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/detailedbsod"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Customize-Preferences/DetailedBSoD"
},
"WPFOOSUbutton": {
"Content": "Run OO Shutup 10",
@ -3729,7 +3673,7 @@
"panel": "1",
"Order": "a039_",
"Type": "Button",
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/oosubutton"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/OOSUbutton"
},
"WPFchangedns": {
"Content": "DNS",
@ -3738,7 +3682,7 @@
"Order": "a040_",
"Type": "Combobox",
"ComboItems": "Default DHCP Google Cloudflare Cloudflare_Malware Cloudflare_Malware_Adult Open_DNS Quad9 AdGuard_Ads_Trackers AdGuard_Ads_Trackers_Malware_Adult dns0.eu_Open dns0.eu_ZERO dns0.eu_KIDS",
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/changedns"
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/changedns"
},
"WPFAddUltPerf": {
"Content": "Add and Activate Ultimate Performance Profile",
@ -3747,7 +3691,7 @@
"Order": "a080_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/tweaks/performance-plans/addultperf"
"link": "https://christitustech.github.io/winutil/dev/tweaks/Performance-Plans/AddUltPerf"
},
"WPFRemoveUltPerf": {
"Content": "Remove Ultimate Performance Profile",
@ -3756,61 +3700,6 @@
"Order": "a081_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://winutil.christitus.com/dev/tweaks/performance-plans/removeultperf"
},
"WPFTweaksDisableExplorerAutoDiscovery": {
"Content": "Disable Explorer Automatic Folder Discovery",
"Description": "Windows Explorer automatically tries to guess the type of the folder based on its contents, slowing down the browsing experience.",
"category": "Essential Tweaks",
"panel": "1",
"Order": "a005_",
"InvokeScript": [
"
# Previously detected folders
$bags = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\"
# Folder types lookup table
$bagMRU = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU\"
# Flush explorer view database
Remove-Item -Path $bags -Recurse -Force
Write-Host \"Removed $bags\"
Remove-Item -Path $bagMRU -Recurse -Force
Write-Host \"Removed $bagMRU\"
# Every folder
$allFolders = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\\AllFolders\\Shell\"
if (!(Test-Path $allFolders)) {
New-Item -Path $allFolders -Force
Write-Host \"Created $allFolders\"
}
# Generic view
New-ItemProperty -Path $allFolders -Name \"FolderType\" -Value \"NotSpecified\" -PropertyType String -Force
Write-Host \"Set FolderType to NotSpecified\"
Write-Host Please sign out and back in, or restart your computer to apply the changes!
"
],
"UndoScript": [
"
# Previously detected folders
$bags = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\"
# Folder types lookup table
$bagMRU = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU\"
# Flush explorer view database
Remove-Item -Path $bags -Recurse -Force
Write-Host \"Removed $bags\"
Remove-Item -Path $bagMRU -Recurse -Force
Write-Host \"Removed $bagMRU\"
Write-Host Please sign out and back in, or restart your computer to apply the changes!
"
]
"link": "https://christitustech.github.io/winutil/dev/tweaks/Performance-Plans/RemoveUltPerf"
}
}

View File

@ -6,7 +6,7 @@
#### **Run the latest pre-release**
```ps1
irm https://christitus.com/windev | iex
irm christitus.com/windev | iex
```
!!! bug "Keep in mind"

View File

@ -6,7 +6,7 @@ Windows Security (formerly Defender) and other anti-virus software are known to
To resolve this, allow/whitelist the script in your anti-virus software settings, or temporarily disable real-time protection. Since the project is open source, you may audit the code if security is a concern.
### Download not working
If `https://christitus.com/win` is not working, or you want to download the code from GitHub directly, you can use the direct download link:
If `christitus.com/win` is not working, or you want to download the code from GitHub directly, you can use the direct download link:
```ps1
irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1 | iex
@ -34,7 +34,7 @@ If you are still having issues, try using a **VPN**, or changing your **DNS prov
2. In the PowerShell window, type this to allow unsigned code to execute and run the installation script:
```ps1
Set-ExecutionPolicy Unrestricted -Scope Process -Force
irm https://christitus.com/win | iex
irm christitus.com/win | iex
```
## Runtime Issues

View File

@ -0,0 +1,38 @@
# Install CTT PowerShell Profile
Last Updated: 2024-10-01
!!! info
The Development Documentation is auto generated for every compilation of WinUtil, meaning a part of it will always stay up-to-date. **Developers do have the ability to add custom content, which won't be updated automatically.**
<!-- BEGIN CUSTOM CONTENT -->
<!-- END CUSTOM CONTENT -->
<details>
<summary>Preview Code</summary>
```json
{
"Content": "Install CTT PowerShell Profile",
"category": "Powershell Profile",
"panel": "2",
"Order": "a083_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Powershell-Profile/PSProfileInstall"
}
```
</details>
<!-- BEGIN SECOND CUSTOM CONTENT -->
<!-- END SECOND CUSTOM CONTENT -->
[View the JSON file](https://github.com/ChrisTitusTech/winutil/tree/main/config/feature.json)

View File

@ -0,0 +1,38 @@
# Uninstall CTT PowerShell Profile
Last Updated: 2024-10-01
!!! info
The Development Documentation is auto generated for every compilation of WinUtil, meaning a part of it will always stay up-to-date. **Developers do have the ability to add custom content, which won't be updated automatically.**
<!-- BEGIN CUSTOM CONTENT -->
<!-- END CUSTOM CONTENT -->
<details>
<summary>Preview Code</summary>
```json
{
"Content": "Uninstall CTT PowerShell Profile",
"category": "Powershell Profile",
"panel": "2",
"Order": "a084_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Powershell-Profile/PSProfileUninstall"
}
```
</details>
<!-- BEGIN SECOND CUSTOM CONTENT -->
<!-- END SECOND CUSTOM CONTENT -->
[View the JSON file](https://github.com/ChrisTitusTech/winutil/tree/main/config/feature.json)

View File

@ -5,104 +5,104 @@
### Essential-Tweaks
- [Change Windows Terminal default: PowerShell 5 -> PowerShell 7](../dev/tweaks/Essential-Tweaks/Powershell7/)
- [Create Restore Point](../dev/tweaks/Essential-Tweaks/RestorePoint/)
- [Debloat Edge](../dev/tweaks/Essential-Tweaks/EdgeDebloat/)
- [Delete Temporary Files](../dev/tweaks/Essential-Tweaks/DeleteTempFiles/)
- [Disable Activity History](../dev/tweaks/Essential-Tweaks/AH/)
- [Disable ConsumerFeatures](../dev/tweaks/Essential-Tweaks/ConsumerFeatures/)
- [Disable GameDVR](../dev/tweaks/Essential-Tweaks/DVR/)
- [Disable Hibernation](../dev/tweaks/Essential-Tweaks/Hiber/)
- [Disable Homegroup](../dev/tweaks/Essential-Tweaks/Home/)
- [Disable Location Tracking](../dev/tweaks/Essential-Tweaks/Loc/)
- [Disable Powershell 7 Telemetry](../dev/tweaks/Essential-Tweaks/Powershell7Tele/)
- [Disable Storage Sense](../dev/tweaks/Essential-Tweaks/Storage/)
- [Disable Telemetry](../dev/tweaks/Essential-Tweaks/Tele/)
- [Disable Wifi-Sense](../dev/tweaks/Essential-Tweaks/Wifi/)
- [Enable End Task With Right Click](../dev/tweaks/Essential-Tweaks/EndTaskOnTaskbar/)
- [Prefer IPv4 over IPv6](../dev/tweaks/Essential-Tweaks/IPv46/)
- [Run Disk Cleanup](../dev/tweaks/Essential-Tweaks/DiskCleanup/)
- [Set Hibernation as default (good for laptops)](../dev/tweaks/Essential-Tweaks/LaptopHibernation/)
- [Set Services to Manual](../dev/tweaks/Essential-Tweaks/Services/)
- [Change Windows Terminal default: PowerShell 5 -> PowerShell 7](../docs/dev/tweaks/Essential-Tweaks/Powershell7.md)
- [Create Restore Point](../docs/dev/tweaks/Essential-Tweaks/RestorePoint.md)
- [Debloat Edge](../docs/dev/tweaks/Essential-Tweaks/EdgeDebloat.md)
- [Delete Temporary Files](../docs/dev/tweaks/Essential-Tweaks/DeleteTempFiles.md)
- [Disable Activity History](../docs/dev/tweaks/Essential-Tweaks/AH.md)
- [Disable ConsumerFeatures](../docs/dev/tweaks/Essential-Tweaks/ConsumerFeatures.md)
- [Disable GameDVR](../docs/dev/tweaks/Essential-Tweaks/DVR.md)
- [Disable Hibernation](../docs/dev/tweaks/Essential-Tweaks/Hiber.md)
- [Disable Homegroup](../docs/dev/tweaks/Essential-Tweaks/Home.md)
- [Disable Location Tracking](../docs/dev/tweaks/Essential-Tweaks/Loc.md)
- [Disable Powershell 7 Telemetry](../docs/dev/tweaks/Essential-Tweaks/Powershell7Tele.md)
- [Disable Storage Sense](../docs/dev/tweaks/Essential-Tweaks/Storage.md)
- [Disable Telemetry](../docs/dev/tweaks/Essential-Tweaks/Tele.md)
- [Disable Wifi-Sense](../docs/dev/tweaks/Essential-Tweaks/Wifi.md)
- [Enable End Task With Right Click](../docs/dev/tweaks/Essential-Tweaks/EndTaskOnTaskbar.md)
- [Prefer IPv4 over IPv6](../docs/dev/tweaks/Essential-Tweaks/IPv46.md)
- [Run Disk Cleanup](../docs/dev/tweaks/Essential-Tweaks/DiskCleanup.md)
- [Set Hibernation as default (good for laptops)](../docs/dev/tweaks/Essential-Tweaks/LaptopHibernation.md)
- [Set Services to Manual](../docs/dev/tweaks/Essential-Tweaks/Services.md)
### Shortcuts
- [Create WinUtil Shortcut](../dev/tweaks/Shortcuts/Shortcut/)
- [Create WinUtil Shortcut](../docs/dev/tweaks/Shortcuts/Shortcut.md)
### z--Advanced-Tweaks---CAUTION
- [Adobe Debloat](../dev/tweaks/z--Advanced-Tweaks---CAUTION/DebloatAdobe/)
- [Adobe Network Block](../dev/tweaks/z--Advanced-Tweaks---CAUTION/BlockAdobeNet/)
- [Disable Background Apps](../dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableBGapps/)
- [Disable Fullscreen Optimizations](../dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableFSO/)
- [Disable Intel MM (vPro LMS)](../dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableLMS1/)
- [Disable IPv6](../dev/tweaks/z--Advanced-Tweaks---CAUTION/Disableipsix/)
- [Disable Microsoft Copilot](../dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveCopilot/)
- [Disable Notification Tray/Calendar](../dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableNotifications/)
- [Disable Teredo](../dev/tweaks/z--Advanced-Tweaks---CAUTION/Teredo/)
- [DNS](../dev/tweaks/z--Advanced-Tweaks---CAUTION/changedns/)
- [Remove ALL MS Store Apps - NOT RECOMMENDED](../dev/tweaks/z--Advanced-Tweaks---CAUTION/DeBloat/)
- [Remove Home and Gallery from explorer](../dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveHomeGallery/)
- [Remove Microsoft Edge](../dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveEdge/)
- [Remove OneDrive](../dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveOnedrive/)
- [Run OO Shutup 10](../dev/tweaks/z--Advanced-Tweaks---CAUTION/OOSUbutton/)
- [Set Classic Right-Click Menu ](../dev/tweaks/z--Advanced-Tweaks---CAUTION/RightClickMenu/)
- [Set Display for Performance](../dev/tweaks/z--Advanced-Tweaks---CAUTION/Display/)
- [Set Time to UTC (Dual Boot)](../dev/tweaks/z--Advanced-Tweaks---CAUTION/UTC/)
- [Adobe Debloat](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DebloatAdobe.md)
- [Adobe Network Block](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/BlockAdobeNet.md)
- [Disable Background Apps](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableBGapps.md)
- [Disable Fullscreen Optimizations](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableFSO.md)
- [Disable Intel MM (vPro LMS)](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableLMS1.md)
- [Disable IPv6](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/Disableipsix.md)
- [Disable Microsoft Copilot](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveCopilot.md)
- [Disable Notification Tray/Calendar](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableNotifications.md)
- [Disable Teredo](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/Teredo.md)
- [DNS](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/changedns.md)
- [Remove ALL MS Store Apps - NOT RECOMMENDED](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DeBloat.md)
- [Remove Home and Gallery from explorer](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveHomeGallery.md)
- [Remove Microsoft Edge](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveEdge.md)
- [Remove OneDrive](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveOnedrive.md)
- [Run OO Shutup 10](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/OOSUbutton.md)
- [Set Classic Right-Click Menu ](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RightClickMenu.md)
- [Set Display for Performance](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/Display.md)
- [Set Time to UTC (Dual Boot)](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/UTC.md)
### Customize-Preferences
- [Bing Search in Start Menu](../dev/tweaks/Customize-Preferences/BingSearch/)
- [Center Taskbar Items](../dev/tweaks/Customize-Preferences/TaskbarAlignment/)
- [Dark Theme for Windows](../dev/tweaks/Customize-Preferences/DarkMode/)
- [Detailed BSoD](../dev/tweaks/Customize-Preferences/DetailedBSoD/)
- [Mouse Acceleration](../dev/tweaks/Customize-Preferences/MouseAcceleration/)
- [NumLock on Startup](../dev/tweaks/Customize-Preferences/NumLock/)
- [Search Button in Taskbar](../dev/tweaks/Customize-Preferences/TaskbarSearch/)
- [Show File Extensions](../dev/tweaks/Customize-Preferences/ShowExt/)
- [Show Hidden Files](../dev/tweaks/Customize-Preferences/HiddenFiles/)
- [Snap Assist Flyout](../dev/tweaks/Customize-Preferences/SnapFlyout/)
- [Snap Assist Suggestion](../dev/tweaks/Customize-Preferences/SnapSuggestion/)
- [Snap Window](../dev/tweaks/Customize-Preferences/SnapWindow/)
- [Sticky Keys](../dev/tweaks/Customize-Preferences/StickyKeys/)
- [Task View Button in Taskbar](../dev/tweaks/Customize-Preferences/TaskView/)
- [Verbose Messages During Logon](../dev/tweaks/Customize-Preferences/VerboseLogon/)
- [Widgets Button in Taskbar](../dev/tweaks/Customize-Preferences/TaskbarWidgets/)
- [Bing Search in Start Menu](../docs/dev/tweaks/Customize-Preferences/BingSearch.md)
- [Center Taskbar Items](../docs/dev/tweaks/Customize-Preferences/TaskbarAlignment.md)
- [Dark Theme for Windows](../docs/dev/tweaks/Customize-Preferences/DarkMode.md)
- [Detailed BSoD](../docs/dev/tweaks/Customize-Preferences/DetailedBSoD.md)
- [Mouse Acceleration](../docs/dev/tweaks/Customize-Preferences/MouseAcceleration.md)
- [NumLock on Startup](../docs/dev/tweaks/Customize-Preferences/NumLock.md)
- [Search Button in Taskbar](../docs/dev/tweaks/Customize-Preferences/TaskbarSearch.md)
- [Show File Extensions](../docs/dev/tweaks/Customize-Preferences/ShowExt.md)
- [Show Hidden Files](../docs/dev/tweaks/Customize-Preferences/HiddenFiles.md)
- [Snap Assist Flyout](../docs/dev/tweaks/Customize-Preferences/SnapFlyout.md)
- [Snap Assist Suggestion](../docs/dev/tweaks/Customize-Preferences/SnapSuggestion.md)
- [Snap Window](../docs/dev/tweaks/Customize-Preferences/SnapWindow.md)
- [Sticky Keys](../docs/dev/tweaks/Customize-Preferences/StickyKeys.md)
- [Task View Button in Taskbar](../docs/dev/tweaks/Customize-Preferences/TaskView.md)
- [Verbose Messages During Logon](../docs/dev/tweaks/Customize-Preferences/VerboseLogon.md)
- [Widgets Button in Taskbar](../docs/dev/tweaks/Customize-Preferences/TaskbarWidgets.md)
### Performance-Plans
- [Add and Activate Ultimate Performance Profile](../dev/tweaks/Performance-Plans/AddUltPerf/)
- [Remove Ultimate Performance Profile](../dev/tweaks/Performance-Plans/RemoveUltPerf/)
- [Add and Activate Ultimate Performance Profile](../docs/dev/tweaks/Performance-Plans/AddUltPerf.md)
- [Remove Ultimate Performance Profile](../docs/dev/tweaks/Performance-Plans/RemoveUltPerf.md)
## Features
### Fixes
- [Remove Adobe Creative Cloud](../dev/features/Fixes/RunAdobeCCCleanerTool/)
- [Reset Network](../dev/features/Fixes/Network/)
- [Reset Windows Update](../dev/features/Fixes/Update/)
- [Set Up Autologin](../dev/features/Fixes/Autologin/)
- [System Corruption Scan](../dev/features/Fixes/DISM/)
- [WinGet Reinstall](../dev/features/Fixes/Winget/)
- [Remove Adobe Creative Cloud](../docs/dev/features/Fixes/RunAdobeCCCleanerTool.md)
- [Reset Network](../docs/dev/features/Fixes/Network.md)
- [Reset Windows Update](../docs/dev/features/Fixes/Update.md)
- [Set Up Autologin](../docs/dev/features/Fixes/Autologin.md)
- [System Corruption Scan](../docs/dev/features/Fixes/DISM.md)
- [WinGet Reinstall](../docs/dev/features/Fixes/Winget.md)
### Legacy-Windows-Panels
- [Control Panel](../dev/features/Legacy-Windows-Panels/control/)
- [Network Connections](../dev/features/Legacy-Windows-Panels/network/)
- [Power Panel](../dev/features/Legacy-Windows-Panels/power/)
- [Printer Settings](../dev/features/Legacy-Windows-Panels/printer/)
- [Region](../dev/features/Legacy-Windows-Panels/region/)
- [Sound Settings](../dev/features/Legacy-Windows-Panels/sound/)
- [System Properties](../dev/features/Legacy-Windows-Panels/system/)
- [User Accounts](../dev/features/Legacy-Windows-Panels/user/)
- [Control Panel](../docs/dev/features/Legacy-Windows-Panels/control.md)
- [Network Connections](../docs/dev/features/Legacy-Windows-Panels/network.md)
- [Power Panel](../docs/dev/features/Legacy-Windows-Panels/power.md)
- [Printer Settings](../docs/dev/features/Legacy-Windows-Panels/printer.md)
- [Region](../docs/dev/features/Legacy-Windows-Panels/region.md)
- [Sound Settings](../docs/dev/features/Legacy-Windows-Panels/sound.md)
- [System Properties](../docs/dev/features/Legacy-Windows-Panels/system.md)
- [User Accounts](../docs/dev/features/Legacy-Windows-Panels/user.md)
### Features
- [All .Net Framework (2,3,4)](../dev/features/Features/dotnet/)
- [Disable Legacy F8 Boot Recovery](../dev/features/Features/DisableLegacyRecovery/)
- [Disable Search Box Web Suggestions in Registry(explorer restart)](../dev/features/Features/DisableSearchSuggestions/)
- [Enable Daily Registry Backup Task 12.30am](../dev/features/Features/RegBackup/)
- [Enable Legacy F8 Boot Recovery](../dev/features/Features/EnableLegacyRecovery/)
- [Enable Search Box Web Suggestions in Registry(explorer restart)](../dev/features/Features/EnableSearchSuggestions/)
- [HyperV Virtualization](../dev/features/Features/hyperv/)
- [Install Features](../dev/features/Features/Install/)
- [Legacy Media (WMP, DirectPlay)](../dev/features/Features/legacymedia/)
- [NFS - Network File System](../dev/features/Features/nfs/)
- [Windows Sandbox](../dev/features/Features/Sandbox/)
- [Windows Subsystem for Linux](../dev/features/Features/wsl/)
- [All .Net Framework (2,3,4)](../docs/dev/features/Features/dotnet.md)
- [Disable Legacy F8 Boot Recovery](../docs/dev/features/Features/DisableLegacyRecovery.md)
- [Disable Search Box Web Suggestions in Registry(explorer restart)](../docs/dev/features/Features/DisableSearchSuggestions.md)
- [Enable Daily Registry Backup Task 12.30am](../docs/dev/features/Features/RegBackup.md)
- [Enable Legacy F8 Boot Recovery](../docs/dev/features/Features/EnableLegacyRecovery.md)
- [Enable Search Box Web Suggestions in Registry(explorer restart)](../docs/dev/features/Features/EnableSearchSuggestions.md)
- [HyperV Virtualization](../docs/dev/features/Features/hyperv.md)
- [Install Features](../docs/dev/features/Features/Install.md)
- [Legacy Media (WMP, DirectPlay)](../docs/dev/features/Features/legacymedia.md)
- [NFS - Network File System](../docs/dev/features/Features/nfs.md)
- [Windows Sandbox](../docs/dev/features/Features/Sandbox.md)
- [Windows Subsystem for Linux](../docs/dev/features/Features/wsl.md)

View File

@ -11,7 +11,7 @@ Welcome to the official documentation for WinUtil, your go-to utility for optimi
* You will first need to start a Powershell terminal **as Admin**.
* Now you can run the following command:
```ps1
irm https://christitus.com/win | iex
irm christitus.com/win | iex
```
!!! info

View File

@ -258,6 +258,6 @@ With MicroWin, you can also configure your user before proceeding if you don't w
* On any supported Windows machine, open PowerShell **as Admin** and run the following command to automatically apply tweaks and install apps from the config file.
```ps1
iex "& { $(irm https://christitus.com/win) } -Config [path-to-your-config] -Run"
iex "& { $(irm christitus.com/win) } -Config [path-to-your-config] -Run"
```
* Have a cup of coffee! Come back when it's done.

View File

@ -111,7 +111,7 @@ public class PowerManagement {
Write-Host "Mounting Windows image. This may take a while."
Mount-WindowsImage -ImagePath "$mountDir\sources\install.wim" -Index $index -Path "$scratchDir"
if ($?) {
Write-Host "The Windows image has been mounted successfully. Continuing processing..."
Write-Host "Mounting complete! Performing removal of applications..."
} else {
Write-Host "Could not mount image. Exiting..."
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
@ -163,12 +163,12 @@ public class PowerManagement {
}
Write-Host "Remove Features from the image"
Microwin-RemoveFeatures -UseCmdlets $true
Microwin-RemoveFeatures
Write-Host "Removing features complete!"
Write-Host "Removing OS packages"
Microwin-RemovePackages -UseCmdlets $true
Microwin-RemovePackages
Write-Host "Removing Appx Bloat"
Microwin-RemoveProvisionedPackages -UseCmdlets $true
Microwin-RemoveProvisionedPackages
# Detect Windows 11 24H2 and add dependency to FileExp to prevent Explorer look from going back - thanks @WitherOrNot and @thecatontheceiling
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true) {
@ -188,8 +188,7 @@ public class PowerManagement {
}
}
catch {
# Fall back to what we used to do: delayed disablement
Enable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName "Recall"
# Do nothing
}
}
@ -286,8 +285,7 @@ public class PowerManagement {
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassTPMCheck" /t REG_DWORD /d 1 /f
reg add "HKLM\zSYSTEM\Setup\MoSetup" /v "AllowUpgradesWithUnsupportedTPMOrCPU" /t REG_DWORD /d 1 /f
# Prevent Windows Update Installing so called Expedited Apps - 24H2 and newer
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true) {
# Prevent Windows Update Installing so called Expedited Apps
@(
'EdgeUpdate',
'DevHomeUpdate',
@ -302,7 +300,6 @@ public class PowerManagement {
# When in Offline Image
reg delete "HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\$_" /f | Out-Null
}
}
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "SearchboxTaskbarMode" /t REG_DWORD /d 0 /f
Write-Host "Setting all services to start manually"
@ -338,7 +335,6 @@ public class PowerManagement {
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\SearchSettings" /v "IsDynamicSearchBoxEnabled" /t REG_DWORD /d 0 /f
reg add "HKLM\zSOFTWARE\Policies\Microsoft\Dsh" /v "AllowNewsAndInterests" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "TraySearchBoxVisible" /t REG_DWORD /d 1 /f
reg add "HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Feeds" /v "EnableFeeds" /t REG_DWORD /d 0 /f
}
} catch {

View File

@ -169,7 +169,7 @@ function Invoke-MicrowinGetIso {
try {
Write-Host "Mounting Iso. Please wait."
$mountedISO = Mount-DiskImage -PassThru "$filePath"
Write-Host "Done mounting Iso `"$($mountedISO.ImagePath)`""
Write-Host "Done mounting Iso $mountedISO"
$driveLetter = (Get-Volume -DiskImage $mountedISO).DriveLetter
Write-Host "Iso mounted to '$driveLetter'"
} catch {

View File

@ -54,7 +54,7 @@ function Microwin-NewFirstRun {
try
{
if ((Get-WindowsOptionalFeature -Online | Where-Object { $_.State -eq 'Enabled' -and $_.FeatureName -like "Recall" }).Count -gt 0)
if ((Get-WindowsOptionalFeature -Online | Where-Object { $_.FeatureName -like "Recall" }).Count -gt 0)
{
Disable-WindowsOptionalFeature -Online -FeatureName "Recall" -Remove
}
@ -79,13 +79,6 @@ function Microwin-NewFirstRun {
}
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.Suggested" /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.Suggested" /v Enabled /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.StartupApp" /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.StartupApp" /v Enabled /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Microsoft.SkyDrive.Desktop" /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Microsoft.SkyDrive.Desktop" /v Enabled /t REG_DWORD /d 0 /f
'@
$firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force
}

View File

@ -160,126 +160,134 @@ function Microwin-NewUnattend {
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>19</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins /t REG_SZ /d "{ \"pinnedList\": [] }" /f</Path>
<Path>powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\Windows\Temp\Microwin-RemovePackages.ps1' -Raw | Invoke-Expression;"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>20</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins_ProviderSet /t REG_DWORD /d 1 /f</Path>
<Path>powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\Windows\Temp\remove-caps.ps1' -Raw | Invoke-Expression;"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>21</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins_WinningProvider /t REG_SZ /d B5292708-1619-419B-9923-E5D9F3925E71 /f</Path>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins /t REG_SZ /d "{ \"pinnedList\": [] }" /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>22</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\providers\B5292708-1619-419B-9923-E5D9F3925E71\default\Device\Start" /v ConfigureStartPins /t REG_SZ /d "{ \"pinnedList\": [] }" /f</Path>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins_ProviderSet /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>23</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\providers\B5292708-1619-419B-9923-E5D9F3925E71\default\Device\Start" /v ConfigureStartPins_LastWrite /t REG_DWORD /d 1 /f</Path>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins_WinningProvider /t REG_SZ /d B5292708-1619-419B-9923-E5D9F3925E71 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>24</Order>
<Path>net.exe accounts /maxpwage:UNLIMITED</Path>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\providers\B5292708-1619-419B-9923-E5D9F3925E71\default\Device\Start" /v ConfigureStartPins /t REG_SZ /d "{ \"pinnedList\": [] }" /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>25</Order>
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\FileSystem" /v LongPathsEnabled /t REG_DWORD /d 1 /f</Path>
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\providers\B5292708-1619-419B-9923-E5D9F3925E71\default\Device\Start" /v ConfigureStartPins_LastWrite /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>26</Order>
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Power" /v HiberbootEnabled /t REG_DWORD /d 0 /f</Path>
<Path>net.exe accounts /maxpwage:UNLIMITED</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>27</Order>
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Dsh" /v AllowNewsAndInterests /t REG_DWORD /d 0 /f</Path>
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\FileSystem" /v LongPathsEnabled /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>28</Order>
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Power" /v HiberbootEnabled /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>29</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "ContentDeliveryAllowed" /t REG_DWORD /d 0 /f</Path>
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Dsh" /v AllowNewsAndInterests /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>30</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "FeatureManagementEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>31</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "OEMPreInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>32</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>33</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEverEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>34</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SilentInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>35</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SoftLandingEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>36</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContentEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>37</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-310093Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>38</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338387Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>39</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338388Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>40</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338389Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>41</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338393Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>42</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-353698Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>43</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SystemPaneSuggestionsEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>44</Order>
<Path>reg.exe unload "HKU\DefaultUser"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>45</Order>
<Path>reg.exe add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>46</Order>
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\BitLocker" /v "PreventDeviceEncryption" /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>47</Order>
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>31</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "ContentDeliveryAllowed" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>32</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "FeatureManagementEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>33</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "OEMPreInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>34</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>35</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEverEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>36</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SilentInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>37</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SoftLandingEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>38</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContentEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>39</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-310093Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>40</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338387Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>41</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338388Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>42</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338389Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>43</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338393Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>44</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-353698Enabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>45</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SystemPaneSuggestionsEnabled" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>46</Order>
<Path>reg.exe unload "HKU\DefaultUser"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>47</Order>
<Path>reg.exe add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t REG_DWORD /d 0 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>48</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Runonce" /v "ClassicContextMenu" /t REG_SZ /d "reg.exe add \"HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32\" /ve /f" /f</Path>
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\BitLocker" /v "PreventDeviceEncryption" /t REG_DWORD /d 1 /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>49</Order>
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>50</Order>
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Runonce" /v "ClassicContextMenu" /t REG_SZ /d "reg.exe add \"HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32\" /ve /f" /f</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>51</Order>
<Path>reg.exe unload "HKU\DefaultUser"</Path>
</RunSynchronousCommand>
</RunSynchronous>

View File

@ -3,21 +3,14 @@ function Microwin-RemoveFeatures() {
.SYNOPSIS
Removes certain features from ISO image
.PARAMETER UseCmdlets
Determines whether or not to use the DISM cmdlets for processing.
- If true, DISM cmdlets will be used
- If false, calls to the DISM executable will be made whilst selecting bits and pieces from the output as a string (that was how MicroWin worked before
the DISM conversion to cmdlets)
.PARAMETER Name
No Params
.EXAMPLE
Microwin-RemoveFeatures -UseCmdlets $true
Microwin-RemoveFeatures
#>
param (
[Parameter(Mandatory = $true, Position = 0)] [bool]$UseCmdlets
)
try {
if ($UseCmdlets) {
$featlist = (Get-WindowsOptionalFeature -Path "$scratchDir")
$featlist = (Get-WindowsOptionalFeature -Path $scratchDir)
$featlist = $featlist | Where-Object {
$_.FeatureName -NotLike "*Defender*" -AND
@ -31,52 +24,17 @@ function Microwin-RemoveFeatures() {
$_.FeatureName -NotLike "*RemoteDesktop*" -AND
$_.State -ne "Disabled"
}
} else {
$featList = dism /english /image="$scratchDir" /get-features | Select-String -Pattern "Feature Name : " -CaseSensitive -SimpleMatch
if ($?) {
$featList = $featList -split "Feature Name : " | Where-Object {$_}
# Exclude the same items. Note: for now, this doesn't exclude those features that are disabled.
# This will appear in the future
$featList = $featList | Where-Object {
$_ -NotLike "*Defender*" -AND
$_ -NotLike "*Printing*" -AND
$_ -NotLike "*TelnetClient*" -AND
$_ -NotLike "*PowerShell*" -AND
$_ -NotLike "*NetFx*" -AND
$_ -NotLike "*Media*" -AND
$_ -NotLike "*NFS*" -AND
$_ -NotLike "*SearchEngine*" -AND
$_ -NotLike "*RemoteDesktop*"
}
} else {
Write-Host "Features could not be obtained with DISM. MicroWin processing will continue, but features will be skipped."
return
}
}
if ($UseCmdlets) {
foreach ($feature in $featList) {
foreach($feature in $featlist) {
$status = "Removing feature $($feature.FeatureName)"
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
Write-Debug "Removing feature $($feature.FeatureName)"
Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $($feature.FeatureName) -Remove -ErrorAction SilentlyContinue -NoRestart
}
} else {
foreach ($feature in $featList) {
$status = "Removing feature $feature"
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
Write-Debug "Removing feature $feature"
dism /english /image="$scratchDir" /disable-feature /featurename=$feature /remove /quiet /norestart | Out-Null
if ($? -eq $false) {
Write-Host "Feature $feature could not be disabled."
}
}
}
Write-Progress -Activity "Removing features" -Status "Ready" -Completed
Write-Host "You can re-enable the disabled features at any time, using either Windows Update or the SxS folder in <installation media>\Sources."
} catch {
Write-Host "Unable to get information about the features. A fallback will be used..."
Write-Host "Unable to get information about the features. MicroWin processing will continue, but features will not be processed"
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
Microwin-RemoveFeatures -UseCmdlets $false
}
}

View File

@ -12,11 +12,7 @@ function Microwin-RemoveFileOrDirectory([string]$pathToDelete, [string]$mask = "
[void]$itemsToDelete.Add($pathToDelete)
} else {
Write-Debug "Adding $($pathToDelete) to array and mask is $($mask)"
if ($Directory) {
$itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse -Directory
} else {
$itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse
}
if ($Directory) { $itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse -Directory } else { $itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse }
}
foreach($itemToDelete in $itemsToDelete) {

View File

@ -1,22 +1,5 @@
function Microwin-RemovePackages {
<#
.SYNOPSIS
Removes certain packages from ISO image
.PARAMETER UseCmdlets
Determines whether or not to use the DISM cmdlets for processing.
- If true, DISM cmdlets will be used
- If false, calls to the DISM executable will be made whilst selecting bits and pieces from the output as a string (that was how MicroWin worked before
the DISM conversion to cmdlets)
.EXAMPLE
Microwin-RemovePackages -UseCmdlets $true
#>
param (
[Parameter(Mandatory = $true, Position = 0)] [bool]$UseCmdlets
)
try {
if ($useCmdlets) {
$pkglist = (Get-WindowsPackage -Path "$scratchDir").PackageName
$pkglist = $pkglist | Where-Object {
@ -35,40 +18,9 @@ function Microwin-RemovePackages {
$_ -NotLike "*VBSCRIPT*" -AND
$_ -NotLike "*License*" -AND
$_ -NotLike "*Hello-Face*" -AND
$_ -NotLike "*ISE*" -AND
$_ -NotLike "*OpenSSH*"
}
} else {
$pkgList = dism /english /image="$scratchDir" /get-packages | Select-String -Pattern "Package Identity : " -CaseSensitive -SimpleMatch
if ($?) {
$pkgList = $pkgList -split "Package Identity : " | Where-Object {$_}
# Exclude the same items.
$pkgList = $pkgList | Where-Object {
$_ -NotLike "*ApplicationModel*" -AND
$_ -NotLike "*indows-Client-LanguagePack*" -AND
$_ -NotLike "*LanguageFeatures-Basic*" -AND
$_ -NotLike "*Package_for_ServicingStack*" -AND
$_ -NotLike "*DotNet*" -AND
$_ -NotLike "*Notepad*" -AND
$_ -NotLike "*WMIC*" -AND
$_ -NotLike "*Ethernet*" -AND
$_ -NotLike "*Wifi*" -AND
$_ -NotLike "*FodMetadata*" -AND
$_ -NotLike "*Foundation*" -AND
$_ -NotLike "*LanguageFeatures*" -AND
$_ -NotLike "*VBSCRIPT*" -AND
$_ -NotLike "*License*" -AND
$_ -NotLike "*Hello-Face*" -AND
$_ -NotLike "*ISE*" -AND
$_ -NotLike "*OpenSSH*"
}
} else {
Write-Host "Packages could not be obtained with DISM. MicroWin processing will continue, but packages will be skipped."
return
}
$_ -NotLike "*ISE*"
}
if ($UseCmdlets) {
$failedCount = 0
$erroredPackages = [System.Collections.Generic.List[ErroredPackage]]::new()
@ -85,19 +37,8 @@ function Microwin-RemovePackages {
continue
}
}
} else {
foreach ($package in $pkgList) {
$status = "Removing package $package"
Write-Progress -Activity "Removing Packages" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
Write-Debug "Removing package $package"
dism /english /image="$scratchDir" /remove-package /packagename=$package /quiet /norestart | Out-Null
if ($? -eq $false) {
Write-Host "Package $package could not be removed."
}
}
}
Write-Progress -Activity "Removing Packages" -Status "Ready" -Completed
if ($UseCmdlets -and $failedCount -gt 0)
if ($failedCount -gt 0)
{
Write-Host "$failedCount package(s) could not be removed. Your image will still work fine, however. Below is information on what packages failed to be removed and why."
if ($erroredPackages.Count -gt 0)
@ -122,8 +63,7 @@ function Microwin-RemovePackages {
}
}
} catch {
Write-Host "Unable to get information about the packages. A fallback will be used..."
Write-Host "Unable to get information about the packages. MicroWin processing will continue, but packages will not be processed"
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
Microwin-RemovePackages -UseCmdlets $false
}
}

View File

@ -3,21 +3,14 @@ function Microwin-RemoveProvisionedPackages() {
.SYNOPSIS
Removes AppX packages from a Windows image during MicroWin processing
.PARAMETER UseCmdlets
Determines whether or not to use the DISM cmdlets for processing.
- If true, DISM cmdlets will be used
- If false, calls to the DISM executable will be made whilst selecting bits and pieces from the output as a string (that was how MicroWin worked before
the DISM conversion to cmdlets)
.PARAMETER Name
No Params
.EXAMPLE
Microwin-RemoveProvisionedPackages
#>
param (
[Parameter(Mandatory = $true, Position = 0)] [bool]$UseCmdlets
)
try
{
if ($UseCmdlets) {
$appxProvisionedPackages = Get-AppxProvisionedPackage -Path "$($scratchDir)" | Where-Object {
$_.PackageName -NotLike "*AppInstaller*" -AND
$_.PackageName -NotLike "*Store*" -and
@ -35,36 +28,8 @@ function Microwin-RemoveProvisionedPackages() {
$_.PackageName -NotLike "*SecHealthUI*" -and
$_.PackageName -NotLike "*ScreenSketch*"
}
} else {
$appxProvisionedPackages = dism /english /image="$scratchDir" /get-provisionedappxpackages | Select-String -Pattern "PackageName : " -CaseSensitive -SimpleMatch
if ($?) {
$appxProvisionedPackages = $appxProvisionedPackages -split "PackageName : " | Where-Object {$_}
# Exclude the same items.
$appxProvisionedPackages = $appxProvisionedPackages | Where-Object {
$_ -NotLike "*AppInstaller*" -AND
$_ -NotLike "*Store*" -and
$_ -NotLike "*Notepad*" -and
$_ -NotLike "*Printing*" -and
$_ -NotLike "*YourPhone*" -and
$_ -NotLike "*Xbox*" -and
$_ -NotLike "*WindowsTerminal*" -and
$_ -NotLike "*Calculator*" -and
$_ -NotLike "*Photos*" -and
$_ -NotLike "*VCLibs*" -and
$_ -NotLike "*Paint*" -and
$_ -NotLike "*Gaming*" -and
$_ -NotLike "*Extension*" -and
$_ -NotLike "*SecHealthUI*" -and
$_ -NotLike "*ScreenSketch*"
}
} else {
Write-Host "AppX packages could not be obtained with DISM. MicroWin processing will continue, but AppX packages will be skipped."
return
}
}
$counter = 0
if ($UseCmdlets) {
foreach ($appx in $appxProvisionedPackages) {
$status = "Removing Provisioned $($appx.PackageName)"
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100)
@ -75,22 +40,12 @@ function Microwin-RemoveProvisionedPackages() {
continue
}
}
} else {
foreach ($appx in $appxProvisionedPackages) {
$status = "Removing Provisioned $appx"
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100)
dism /english /image="$scratchDir" /remove-provisionedappxpackage /packagename=$appx /quiet /norestart | Out-Null
if ($? -eq $false) {
Write-Host "AppX package $appx could not be removed."
}
}
}
Write-Progress -Activity "Removing Provisioned Apps" -Status "Ready" -Completed
}
catch
{
Write-Host "Unable to get information about the AppX packages. A fallback will be used..."
# This can happen if getting AppX packages fails
Write-Host "Unable to get information about the AppX packages. MicroWin processing will continue, but AppX packages will not be processed"
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
Microwin-RemoveProvisionedPackages -UseCmdlets $false
}
}

View File

@ -1,50 +0,0 @@
function Add-SelectedAppsMenuItem {
<#
.SYNOPSIS
This is a helper function that generates and adds the Menu Items to the Selected Apps Popup.
.Parameter name
The actual Name of an App like "Chrome" or "Brave"
This name is contained in the "Content" property inside the applications.json
.PARAMETER key
The key which identifies an app object in applications.json
For Chrome this would be "WPFInstallchrome" because "WPFInstall" is prepended automatically for each key in applications.json
#>
param ([string]$name, [string]$key)
$selectedAppGrid = New-Object Windows.Controls.Grid
$selectedAppGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = "*"}))
$selectedAppGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = "30"}))
# Sets the name to the Content as well as the Tooltip, because the parent Popup Border has a fixed width and text could "overflow".
# With the tooltip, you can still read the whole entry on hover
$selectedAppLabel = New-Object Windows.Controls.Label
$selectedAppLabel.Content = $name
$selectedAppLabel.ToolTip = $name
$selectedAppLabel.HorizontalAlignment = "Left"
$selectedAppLabel.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
[System.Windows.Controls.Grid]::SetColumn($selectedAppLabel, 0)
$selectedAppGrid.Children.Add($selectedAppLabel)
$selectedAppRemoveButton = New-Object Windows.Controls.Button
$selectedAppRemoveButton.FontFamily = "Segoe MDL2 Assets"
$selectedAppRemoveButton.Content = [string]([char]0xE711)
$selectedAppRemoveButton.HorizontalAlignment = "Center"
$selectedAppRemoveButton.Tag = $key
$selectedAppRemoveButton.ToolTip = "Remove the App from Selection"
$selectedAppRemoveButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
$selectedAppRemoveButton.SetResourceReference([Windows.Controls.Control]::StyleProperty, "HoverButtonStyle")
# Highlight the Remove icon on Hover
$selectedAppRemoveButton.Add_MouseEnter({ $this.Foreground = "Red" })
$selectedAppRemoveButton.Add_MouseLeave({ $this.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor") })
$selectedAppRemoveButton.Add_Click({
$sync.($this.Tag).isChecked = $false # On click of the remove button, we only have to uncheck the corresponding checkbox. This will kick of all neccessary changes to update the UI
})
[System.Windows.Controls.Grid]::SetColumn($selectedAppRemoveButton, 1)
$selectedAppGrid.Children.Add($selectedAppRemoveButton)
# Add new Element to Popup
$sync.selectedAppsstackPanel.Children.Add($selectedAppGrid)
}

View File

@ -1,35 +0,0 @@
function Find-AppsByNameOrDescription {
<#
.SYNOPSIS
Searches through the Apps on the Install Tab and hides all entries that do not match the string
.PARAMETER SearchString
The string to be searched for
#>
param(
[Parameter(Mandatory=$false)]
[string]$SearchString = ""
)
# Reset the visibility if the search string is empty or the search is cleared
if ([string]::IsNullOrWhiteSpace($SearchString)) {
Set-CategoryVisibility -Category "*"
return
}
$sync.ItemsControl.Items | ForEach-Object {
# Hide all CategoryWrapPanel and ToggleButton
$_.Visibility = [Windows.Visibility]::Collapsed
if ($_.Tag -like "CategoryWrapPanel_*") {
# Search for Apps that match the search string
$_.Children | Foreach-Object {
if ($sync.configs.applicationsHashtable.$($_.Tag).Content -like "*$SearchString*") {
# Show the App and the parent CategoryWrapPanel if the string is found
$_.Visibility = [Windows.Visibility]::Visible
$_.parent.Visibility = [Windows.Visibility]::Visible
}
else {
$_.Visibility = [Windows.Visibility]::Collapsed
}
}
}
}
}

View File

@ -1,104 +0,0 @@
function Find-TweaksByNameOrDescription {
<#
.SYNOPSIS
Searches through the Tweaks on the Tweaks Tab and hides all entries that do not match the search string
.PARAMETER SearchString
The string to be searched for
#>
param(
[Parameter(Mandatory=$false)]
[string]$SearchString = ""
)
# Reset the visibility if the search string is empty or the search is cleared
if ([string]::IsNullOrWhiteSpace($SearchString)) {
# Show all categories
$tweakspanel = $sync.Form.FindName("tweakspanel")
$tweakspanel.Children | ForEach-Object {
$_.Visibility = [Windows.Visibility]::Visible
# Foreach category section, show all items
if ($_ -is [Windows.Controls.Border]) {
$_.Visibility = [Windows.Visibility]::Visible
# Find ItemsControl
$dockPanel = $_.Child
if ($dockPanel -is [Windows.Controls.DockPanel]) {
$itemsControl = $dockPanel.Children | Where-Object { $_ -is [Windows.Controls.ItemsControl] }
if ($itemsControl) {
# Show items in the category
foreach ($item in $itemsControl.Items) {
if ($item -is [Windows.Controls.Label]) {
$item.Visibility = [Windows.Visibility]::Visible
} elseif ($item -is [Windows.Controls.DockPanel] -or
$item -is [Windows.Controls.StackPanel]) {
$item.Visibility = [Windows.Visibility]::Visible
}
}
}
}
}
}
return
}
# Search for matching tweaks when search string is not null
$tweakspanel = $sync.Form.FindName("tweakspanel")
$matchFound = $false
$tweakspanel.Children | ForEach-Object {
$categoryBorder = $_
$categoryVisible = $false
if ($_ -is [Windows.Controls.Border]) {
# Find the ItemsControl
$dockPanel = $_.Child
if ($dockPanel -is [Windows.Controls.DockPanel]) {
$itemsControl = $dockPanel.Children | Where-Object { $_ -is [Windows.Controls.ItemsControl] }
if ($itemsControl) {
$categoryLabel = $null
# Process all items in the ItemsControl
for ($i = 0; $i -lt $itemsControl.Items.Count; $i++) {
$item = $itemsControl.Items[$i]
if ($item -is [Windows.Controls.Label]) {
$categoryLabel = $item
$item.Visibility = [Windows.Visibility]::Collapsed
} elseif ($item -is [Windows.Controls.DockPanel]) {
$checkbox = $item.Children | Where-Object { $_ -is [Windows.Controls.CheckBox] } | Select-Object -First 1
$label = $item.Children | Where-Object { $_ -is [Windows.Controls.Label] } | Select-Object -First 1
if ($label -and ($label.Content -like "*$SearchString*" -or $label.ToolTip -like "*$SearchString*")) {
$item.Visibility = [Windows.Visibility]::Visible
if ($categoryLabel) { $categoryLabel.Visibility = [Windows.Visibility]::Visible }
$categoryVisible = $true
} else {
$item.Visibility = [Windows.Visibility]::Collapsed
}
} elseif ($item -is [Windows.Controls.StackPanel]) {
# StackPanel which contain checkboxes or other elements
$checkbox = $item.Children | Where-Object { $_ -is [Windows.Controls.CheckBox] } | Select-Object -First 1
if ($checkbox -and ($checkbox.Content -like "*$SearchString*" -or $checkbox.ToolTip -like "*$SearchString*")) {
$item.Visibility = [Windows.Visibility]::Visible
if ($categoryLabel) { $categoryLabel.Visibility = [Windows.Visibility]::Visible }
$categoryVisible = $true
} else {
$item.Visibility = [Windows.Visibility]::Collapsed
}
}
}
}
}
# Set the visibility based on if any item matched
$categoryBorder.Visibility = if ($categoryVisible) { [Windows.Visibility]::Visible } else { [Windows.Visibility]::Collapsed }
if ($categoryVisible) {
$matchFound = $true
}
}
}
}

View File

@ -1,59 +0,0 @@
function Get-WinUtilSelectedPackages
{
<#
.SYNOPSIS
Sorts given packages based on installer preference and availability.
.OUTPUTS
Hashtable. Key = Package Manager, Value = ArrayList of packages to install
#>
param (
[Parameter(Mandatory=$true)]
$PackageList,
[Parameter(Mandatory=$true)]
[PackageManagers]$Preference
)
if ($PackageList.count -eq 1) {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
$packages = [System.Collections.Hashtable]::new()
$packagesWinget = [System.Collections.ArrayList]::new()
$packagesChoco = [System.Collections.ArrayList]::new()
$packages[[PackageManagers]::Winget] = $packagesWinget
$packages[[PackageManagers]::Choco] = $packagesChoco
Write-Debug "Checking packages using Preference '$($Preference)'"
foreach ($package in $PackageList) {
switch ($Preference) {
"Choco" {
if ($package.choco -eq "na") {
Write-Debug "$($package.content) has no Choco value."
$packagesWinget.add($package.winget)
Write-Host "Queueing $($package.winget) for Winget"
} else {
$null = $packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey"
}
break
}
"Winget" {
if ($package.winget -eq "na") {
Write-Debug "$($package.content) has no Winget value."
$packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey"
} else {
$null = $packagesWinget.add($($package.winget))
Write-Host "Queueing $($package.winget) for Winget"
}
break
}
}
}
return $packages
}

View File

@ -35,9 +35,6 @@ Function Get-WinUtilToggleStatus {
foreach ($regentry in $ToggleSwitchReg) {
try {
if (!(Test-Path $regentry.Path)) {
New-Item -Path $regentry.Path -Force | Out-Null
}
$regstate = (Get-ItemProperty -path $regentry.Path).$($regentry.Name)
if ($regstate -eq $regentry.Value) {
$count += 1
@ -45,23 +42,8 @@ Function Get-WinUtilToggleStatus {
} else {
Write-Debug "$($regentry.Name) is false (state: $regstate, value: $($regentry.Value), original: $($regentry.OriginalValue))"
}
if (!$regstate) {
switch ($regentry.DefaultState) {
"true" {
$regstate = $regentry.Value
$count += 1
}
"false" {
$regstate = $regentry.OriginalValue
}
default {
Write-Error "Entry for $($regentry.Name) does not exist and no DefaultState is defined."
$regstate = $regentry.OriginalValue
}
}
}
} catch {
Write-Error "An unexpected error occurred: $_"
Write-Error "An error occurred while accessing registry entry $($regentry.Path): $_"
}
}

View File

@ -0,0 +1,104 @@
function Get-WinUtilWingetLatest {
[CmdletBinding()]
param()
<#
.SYNOPSIS
Uses GitHub API to check for the latest release of Winget.
.DESCRIPTION
This function first attempts to update WinGet using winget itself, then falls back to manual installation if needed.
#>
$ProgressPreference = "SilentlyContinue"
$InformationPreference = 'Continue'
try {
$wingetCmd = Get-Command winget -ErrorAction Stop
Write-Information "Attempting to update WinGet using WinGet..."
$result = Start-Process -FilePath "`"$($wingetCmd.Source)`"" -ArgumentList "install -e --accept-source-agreements --accept-package-agreements Microsoft.AppInstaller" -Wait -NoNewWindow -PassThru
if ($result.ExitCode -ne 0) {
throw "WinGet update failed with exit code: $($result.ExitCode)"
}
return $true
}
catch {
Write-Information "WinGet not found or update failed. Attempting to install from Microsoft Store..."
try {
# Try to close any running WinGet processes
Get-Process -Name "DesktopAppInstaller", "winget" -ErrorAction SilentlyContinue | ForEach-Object {
Write-Information "Stopping running WinGet process..."
$_.Kill()
Start-Sleep -Seconds 2
}
# Try to load Windows Runtime assemblies more reliably
$null = [System.Runtime.WindowsRuntime.WindowsRuntimeSystemExtensions]
Add-Type -AssemblyName System.Runtime.WindowsRuntime
# Load required assemblies from Windows SDK
$null = @(
[Windows.Management.Deployment.PackageManager, Windows.Management.Deployment, ContentType = WindowsRuntime]
[Windows.Foundation.Uri, Windows.Foundation, ContentType = WindowsRuntime]
[Windows.Management.Deployment.DeploymentOptions, Windows.Management.Deployment, ContentType = WindowsRuntime]
)
# Initialize PackageManager
$packageManager = New-Object Windows.Management.Deployment.PackageManager
# Rest of the Microsoft Store installation logic
$appxPackage = "https://aka.ms/getwinget"
$uri = New-Object Windows.Foundation.Uri($appxPackage)
$deploymentOperation = $packageManager.AddPackageAsync($uri, $null, "Add")
# Add timeout check for deployment operation
$timeout = 300
$timer = [System.Diagnostics.Stopwatch]::StartNew()
while ($deploymentOperation.Status -eq 0) {
if ($timer.Elapsed.TotalSeconds -gt $timeout) {
throw "Installation timed out after $timeout seconds"
}
Start-Sleep -Milliseconds 100
}
if ($deploymentOperation.Status -eq 1) {
Write-Information "Successfully installed WinGet from Microsoft Store"
return $true
} else {
throw "Installation failed with status: $($deploymentOperation.Status)"
}
}
catch [System.Management.Automation.RuntimeException] {
Write-Information "Windows Runtime components not available. Attempting manual download..."
try {
# Try to close any running WinGet processes
Get-Process -Name "DesktopAppInstaller", "winget" -ErrorAction SilentlyContinue | ForEach-Object {
Write-Information "Stopping running WinGet process..."
$_.Kill()
Start-Sleep -Seconds 2
}
# Fallback to direct download from GitHub
$apiUrl = "https://api.github.com/repos/microsoft/winget-cli/releases/latest"
$release = Invoke-RestMethod -Uri $apiUrl
$msixBundleUrl = ($release.assets | Where-Object { $_.name -like "*.msixbundle" }).browser_download_url
$tempFile = Join-Path $env:TEMP "Microsoft.DesktopAppInstaller.msixbundle"
Invoke-WebRequest -Uri $msixBundleUrl -OutFile $tempFile
Add-AppxPackage -Path $tempFile -ErrorAction Stop
Remove-Item $tempFile -Force
Write-Information "Successfully installed WinGet from GitHub release"
return $true
}
catch {
Write-Error "Failed to install WinGet: $_"
return $false
}
}
catch {
Write-Error "Failed to install WinGet: $_"
return $false
}
}
}

View File

@ -1,136 +0,0 @@
function Initialize-InstallAppEntry {
<#
.SYNOPSIS
Creates the app entry to be placed on the isntall tab for a given app
Used to as part of the Install Tab UI generation
.PARAMETER TargetElement
The Element into which the Apps should be placed
.PARAMETER appKey
The Key of the app inside the $sync.configs.applicationsHashtable
#>
param(
[Windows.Controls.WrapPanel]$TargetElement,
$appKey
)
# Create the outer Border for the application type
$border = New-Object Windows.Controls.Border
$border.Style = $sync.Form.Resources.AppTileBorderStyle
$border.Tag = $appKey
$border.ToolTip = $Apps.$appKey.description
$border.Add_MouseUp({
if ($_.ChangedButton -eq [System.Windows.Input.MouseButton]::Right) {
Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFInstall*";
}
$childCheckbox = ($this.Child.Children | Where-Object {$_.Template.TargetType -eq [System.Windows.Controls.Checkbox]})[0]
$childCheckBox.isChecked = -not $childCheckbox.IsChecked
})
$border.Add_MouseEnter({
if (($sync.$($this.Tag).IsChecked) -eq $false) {
$this.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallHighlightedColor")
}
})
$border.Add_MouseLeave({
if (($sync.$($this.Tag).IsChecked) -eq $false) {
$this.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor")
}
})
# Create a DockPanel inside the Border
$dockPanel = New-Object Windows.Controls.DockPanel
$dockPanel.LastChildFill = $true
$border.Child = $dockPanel
# Create the CheckBox, vertically centered
$checkBox = New-Object Windows.Controls.CheckBox
$checkBox.Name = $appKey
$checkbox.Style = $sync.Form.Resources.AppTileCheckboxStyle
$checkbox.Add_Checked({
Invoke-WPFSelectedAppsUpdate -type "Add" -checkbox $this
$borderElement = $this.Parent.Parent
$borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallSelectedColor")
})
$checkbox.Add_Unchecked({
Invoke-WPFSelectedAppsUpdate -type "Remove" -checkbox $this
$borderElement = $this.Parent.Parent
$borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor")
})
# Create a StackPanel for the image and name
$imageAndNamePanel = New-Object Windows.Controls.StackPanel
$imageAndNamePanel.Orientation = "Horizontal"
$imageAndNamePanel.VerticalAlignment = "Center"
# Create the Image and set a placeholder
$image = New-Object Windows.Controls.Image
# $image.Name = "wpfapplogo" + $App.Name
$image.Style = $sync.Form.Resources.AppTileImageStyle
$image.Source = $noimage # Ensure $noimage is defined in your script
$imageAndNamePanel.Children.Add($image) | Out-Null
# Create the TextBlock for the application name
$appName = New-Object Windows.Controls.TextBlock
$appName.Style = $sync.Form.Resources.AppTileNameStyle
$appName.Text = $Apps.$appKey.content
$imageAndNamePanel.Children.Add($appName) | Out-Null
# Add the image and name panel to the Checkbox
$checkBox.Content = $imageAndNamePanel
# Add the checkbox to the DockPanel
[Windows.Controls.DockPanel]::SetDock($checkBox, [Windows.Controls.Dock]::Left)
$dockPanel.Children.Add($checkBox) | Out-Null
# Create the StackPanel for the buttons and dock it to the right
$buttonPanel = New-Object Windows.Controls.StackPanel
$buttonPanel.Style = $sync.Form.Resources.AppTileButtonPanelStyle
[Windows.Controls.DockPanel]::SetDock($buttonPanel, [Windows.Controls.Dock]::Right)
# Define the button properties
$buttons = @(
[PSCustomObject]@{ Name = "Install"; Description = "Install or Upgrade the application"; Tooltip = "Install or Upgrade the application"; Icon = [char]0xE118 },
[PSCustomObject]@{ Name = "Uninstall"; Description = "Uninstall the application"; Tooltip = "Uninstall the application"; Icon = [char]0xE74D },
[PSCustomObject]@{ Name = "Info"; Description = "Open the application's website in your default browser"; Tooltip = "Open the application's website in your default browser"; Icon = [char]0xE946 }
)
# Iterate over each button and create it
foreach ($button in $buttons) {
$newButton = New-Object Windows.Controls.Button
$newButton.Style = $sync.Form.Resources.AppTileButtonStyle
$newButton.Content = $button.Icon
$newButton.ToolTip = $button.Tooltip
$buttonPanel.Children.Add($newButton) | Out-Null
switch ($button.Name) {
"Install" {
$newButton.Add_Click({
$appKey = $this.Parent.Parent.Parent.Tag
$appObject = $sync.configs.applicationsHashtable.$appKey
Invoke-WPFInstall -PackagesToInstall $appObject
})
}
"Uninstall" {
$newButton.Add_Click({
$appKey = $this.Parent.Parent.Parent.Tag
$appObject = $sync.configs.applicationsHashtable.$appKey
Invoke-WPFUnInstall -PackagesToUninstall $appObject
})
}
"Info" {
$newButton.Add_Click({
$appKey = $this.Parent.Parent.Parent.Tag
$appObject = $sync.configs.applicationsHashtable.$appKey
Start-Process $appObject.link
})
}
}
}
# Add the button panel to the DockPanel
$dockPanel.Children.Add($buttonPanel) | Out-Null
# Add the border to the corresponding Category
$TargetElement.Children.Add($border) | Out-Null
return $checkbox
}

View File

@ -1,36 +0,0 @@
function Initialize-InstallAppArea {
<#
.SYNOPSIS
Creates a [Windows.Controls.ScrollViewer] containing a [Windows.Controls.ItemsControl] which is setup to use Virtualization to only load the visible elements for performance reasons.
This is used as the parent object for all category and app entries on the install tab
Used to as part of the Install Tab UI generation
.PARAMETER TargetElement
The element to which the AppArea shoud be added
#>
param($TargetElement)
$scrollViewer = New-Object Windows.Controls.ScrollViewer
$scrollViewer.VerticalScrollBarVisibility = 'Auto'
$scrollViewer.HorizontalAlignment = 'Stretch'
$scrollViewer.VerticalAlignment = 'Stretch'
$scrollViewer.CanContentScroll = $true
$itemsControl = New-Object Windows.Controls.ItemsControl
$itemsControl.HorizontalAlignment = 'Stretch'
$itemsControl.VerticalAlignment = 'Stretch'
$itemsPanelTemplate = New-Object Windows.Controls.ItemsPanelTemplate
$factory = New-Object Windows.FrameworkElementFactory ([Windows.Controls.VirtualizingStackPanel])
$itemsPanelTemplate.VisualTree = $factory
$itemsControl.ItemsPanel = $itemsPanelTemplate
$itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::IsVirtualizingProperty, $true)
$itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::VirtualizationModeProperty, [Windows.Controls.VirtualizationMode]::Recycling)
$scrollViewer.Content = $itemsControl
[Windows.Controls.DockPanel]::SetDock($scrollViewer, [Windows.Controls.Dock]::Bottom)
$null = $TargetElement.Children.Add($scrollViewer)
return $itemsControl
}

View File

@ -1,28 +0,0 @@
function Initialize-InstallAppsMainElement {
<#
.SYNOPSIS
Clears the given WPF Grid and creates a [Windows.Controls.Border] containing a [Windows.Controls.StackPanel]
Used to as part of the Install Tab UI generation
.PARAMETER TargetGridName
The WPF Grid name
.OUTPUTS
Returns the created [Windows.Controls.StackPanel] element
#>
param(
[Parameter(Mandatory)]
[string]$TargetGridName
)
$targetGrid = $sync.Form.FindName($TargetGridName)
$null = $targetGrid.Children.Clear()
$Border = New-Object Windows.Controls.Border
$Border.VerticalAlignment = "Stretch"
$Border.SetResourceReference([Windows.Controls.Control]::StyleProperty, "BorderStyle")
$dockPanel = New-Object Windows.Controls.DockPanel
$Border.Child = $dockPanel
$null = $targetGrid.Children.Add($Border)
return $dockPanel
}

View File

@ -1,81 +0,0 @@
function Initialize-InstallCategoryAppList {
<#
.SYNOPSIS
Clears the Target Element and sets up a "Loading" message. This is done, because loading of all apps can take a bit of time in some scenarios
Iterates through all Categories and Apps and adds them to the UI
Used to as part of the Install Tab UI generation
.PARAMETER TargetElement
The Element into which the Categories and Apps should be placed
.PARAMETER Apps
The Hashtable of Apps to be added to the UI
The Categories are also extracted from the Apps Hashtable
#>
param(
$TargetElement,
$Apps
)
function Add-Category {
param(
[string]$Category,
[Windows.Controls.ItemsControl]$TargetElement
)
$toggleButton = New-Object Windows.Controls.Primitives.ToggleButton
$toggleButton.Content = "$Category"
$toggleButton.Tag = "CategoryToggleButton"
$toggleButton.Cursor = [System.Windows.Input.Cursors]::Hand
$toggleButton.SetResourceReference([Windows.Controls.Control]::StyleProperty, "CategoryToggleButtonStyle")
$sync.Buttons.Add($toggleButton)
$toggleButton.Add_Checked({
# Clear the search bar when a category is clicked
$sync.SearchBar.Text = ""
Set-CategoryVisibility -Category $this.Content -overrideState Expand
})
$toggleButton.Add_Unchecked({
Set-CategoryVisibility -Category $this.Content -overrideState Collapse
})
$null = $TargetElement.Items.Add($toggleButton)
}
$loadingLabel = New-Object Windows.Controls.Label
$loadingLabel.Content = "Loading, please wait..."
$loadingLabel.HorizontalAlignment = "Center"
$loadingLabel.VerticalAlignment = "Center"
$loadingLabel.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "HeaderFontSize")
$loadingLabel.FontWeight = [Windows.FontWeights]::Bold
$loadingLabel.Foreground = [Windows.Media.Brushes]::Gray
$sync.LoadingLabel = $loadingLabel
$TargetElement.Items.Clear()
$null = $TargetElement.Items.Add($sync.LoadingLabel)
# Use the Dispatcher to make sure the Loading message is shown before the logic loading the apps starts, and only is removed when the loading is complete and the apps are added to the UI
$TargetElement.Dispatcher.Invoke([System.Windows.Threading.DispatcherPriority]::Background, [action]{
$TargetElement.Items.Clear() # Remove the loading message
# Pre-group apps by category
$appsByCategory = @{}
foreach ($appKey in $Apps.Keys) {
$category = $Apps.$appKey.Category
if (-not $appsByCategory.ContainsKey($category)) {
$appsByCategory[$category] = @()
}
$appsByCategory[$category] += $appKey
}
foreach ($category in $($appsByCategory.Keys | Sort-Object)) {
Add-Category -Category $category -TargetElement $TargetElement
$wrapPanel = New-Object Windows.Controls.WrapPanel
$wrapPanel.Orientation = "Horizontal"
$wrapPanel.HorizontalAlignment = "Stretch"
$wrapPanel.VerticalAlignment = "Center"
$wrapPanel.Margin = New-Object Windows.Thickness(0, 0, 0, 20)
$wrapPanel.Visibility = [Windows.Visibility]::Collapsed
$wrapPanel.Tag = "CategoryWrapPanel_$category"
$null = $TargetElement.Items.Add($wrapPanel)
$appsByCategory[$category] |Sort-Object | ForEach-Object {
$sync.$_ = $(Initialize-InstallAppEntry -TargetElement $wrapPanel -AppKey $_)
}
}
})
}

View File

@ -1,78 +0,0 @@
function Initialize-InstallHeader {
<#
.SYNOPSIS
Creates the Multi Selection Header Elements on the Install Tab
Used to as part of the Install Tab UI generation
.PARAMETER TargetElement
The Parent Element into which the Header should be placed
#>
param($TargetElement)
function New-WPFButton {
param (
[string]$Name,
[string]$Content
)
$button = New-Object Windows.Controls.Button
$button.Name = $Name
$button.Content = $Content
$button.Margin = New-Object Windows.Thickness(2)
$button.HorizontalAlignment = "Stretch"
return $button
}
$wrapPanelTop = New-Object Windows.Controls.WrapPanel
$wrapPanelTop.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "MainBackgroundColor")
$wrapPanelTop.HorizontalAlignment = "Left"
$wrapPanelTop.VerticalAlignment = "Top"
$wrapPanelTop.Orientation = "Horizontal"
$wrapPanelTop.SetResourceReference([Windows.Controls.Control]::MarginProperty, "TabContentMargin")
$buttonConfigs = @(
@{Name="WPFInstall"; Content="Install/Upgrade Selected"},
@{Name="WPFInstallUpgrade"; Content="Upgrade All"},
@{Name="WPFUninstall"; Content="Uninstall Selected"},
@{Name="WPFselectedAppsButton"; Content="Selected Apps: 0"}
)
foreach ($config in $buttonConfigs) {
$button = New-WPFButton -Name $config.Name -Content $config.Content
$null = $wrapPanelTop.Children.Add($button)
$sync[$config.Name] = $button
}
$selectedAppsPopup = New-Object Windows.Controls.Primitives.Popup
$selectedAppsPopup.IsOpen = $false
$selectedAppsPopup.PlacementTarget = $sync.WPFselectedAppsButton
$selectedAppsPopup.Placement = [System.Windows.Controls.Primitives.PlacementMode]::Bottom
$selectedAppsPopup.AllowsTransparency = $true
$selectedAppsBorder = New-Object Windows.Controls.Border
$selectedAppsBorder.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "MainBackgroundColor")
$selectedAppsBorder.SetResourceReference([Windows.Controls.Control]::BorderBrushProperty, "MainForegroundColor")
$selectedAppsBorder.SetResourceReference([Windows.Controls.Control]::BorderThicknessProperty, "ButtonBorderThickness")
$selectedAppsBorder.Width = 200
$selectedAppsBorder.Padding = 5
$selectedAppsPopup.Child = $selectedAppsBorder
$sync.selectedAppsPopup = $selectedAppsPopup
$sync.selectedAppsstackPanel = New-Object Windows.Controls.StackPanel
$selectedAppsBorder.Child = $sync.selectedAppsstackPanel
# Toggle selectedAppsPopup open/close with button
$sync.WPFselectedAppsButton.Add_Click({
$sync.selectedAppsPopup.IsOpen = -not $sync.selectedAppsPopup.IsOpen
})
# Close selectedAppsPopup when mouse leaves both button and selectedAppsPopup
$sync.WPFselectedAppsButton.Add_MouseLeave({
if (-not $sync.selectedAppsPopup.IsMouseOver) {
$sync.selectedAppsPopup.IsOpen = $false
}
})
$selectedAppsPopup.Add_MouseLeave({
if (-not $sync.WPFselectedAppsButton.IsMouseOver) {
$sync.selectedAppsPopup.IsOpen = $false
}
})
[Windows.Controls.DockPanel]::SetDock($wrapPanelTop, [Windows.Controls.Dock]::Top)
$null = $TargetElement.Children.Add($wrapPanelTop)
}

View File

@ -33,44 +33,18 @@ function Install-WinUtilWinget {
return
}
Write-Host "Attempting to install/update Winget`r"
try {
$wingetCmd = Get-Command winget -ErrorAction Stop
Write-Information "Attempting to update WinGet using WinGet..."
$result = Start-Process -FilePath "`"$($wingetCmd.Source)`"" -ArgumentList "install -e --accept-source-agreements --accept-package-agreements Microsoft.AppInstaller" -Wait -NoNewWindow -PassThru
if ($result.ExitCode -ne 0) {
throw "WinGet update failed with exit code: $($result.ExitCode)"
}
# Install Winget via GitHub method.
# Used part of my own script with some modification: ruxunderscore/windows-initialization
Write-Host "Downloading Winget and License File`r"
Get-WinUtilWingetLatest
Write-Host "Enabling NuGet and Module..."
Install-PackageProvider -Name NuGet -Force
Install-Module -Name Microsoft.WinGet.Client -Force
# Winget only needs a refresh of the environment variables to be used.
Write-Output "Refreshing Environment Variables...`n"
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
return
} catch {
Write-Information "WinGet not found or update failed. Attempting to install from Microsoft Store..."
}
try {
Write-Host "Attempting to repair WinGet using Repair-WinGetPackageManager..." -ForegroundColor Yellow
# Check if Windows version supports Repair-WinGetPackageManager (24H2 and above)
if ([System.Environment]::OSVersion.Version.Build -ge 26100) {
Repair-WinGetPackageManager -Force -Latest -Verbose
# Verify if repair was successful
$wingetCmd = Get-Command winget -ErrorAction Stop
Write-Host "WinGet repair successful!" -ForegroundColor Green
} else {
Write-Host "Repair-WinGetPackageManager is only available on Windows 24H2 and above. Your version doesn't support this method." -ForegroundColor Yellow
throw "Windows version not supported for repair method"
Write-Error "Failed to install Winget: $($_.Exception.Message)"
}
Write-Output "Refreshing Environment Variables...`n"
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
return
} catch {
Write-Error "All installation methods failed. Unable to install WinGet."
throw
}
} catch {
Write-Error "An error occurred during WinGet installation: $_"
throw
}
}

View File

@ -38,32 +38,6 @@ function Invoke-WinUtilUninstallPSProfile {
if (-not $Fonts) {
Write-Host "===> Successfully Uninstalled: Nerd Fonts. <===" -ForegroundColor Yellow
}
}
# Helper function used to uninstall a specific Nerd Fonts font corresponding registry keys.
function Uninstall-NerdFontRegKeys {
# Define the parameters block for the Uninstall-NerdFontsRegKey function.
param (
[string]$FontsRegPath = "HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts",
[string]$FontFamilyName = "CaskaydiaCove"
)
try {
# Get all properties (font registrations) from the registry path
$registryProperties = Get-ItemProperty -Path $FontsRegPath
# Filter and remove properties that match the font family name
$registryProperties.PSObject.Properties |
Where-Object { $_.Name -match $FontFamilyName } |
ForEach-Object {
If ($_.Name -like "*$FontFamilyName*") {
Remove-ItemProperty -path $FontsRegPath -Name $_.Name -ErrorAction SilentlyContinue
}
}
} catch {
Write-Host "Error removing registry keys: $($_.exception.message)" -ForegroundColor Red
}
}
# Check if Chris Titus Tech's PowerShell profile is currently available in the PowerShell profile folder.
@ -113,28 +87,11 @@ function Invoke-WinUtilUninstallPSProfile {
# Call the function used to uninstall the specified Nerd Fonts package from the system.
Uninstall-NerdFonts -FontsPath $FontsPath -FontFamilyName $FontFamilyName
} catch {
# Let the user know that an error was encountered when uninstalling Nerd Fonts.
Write-Host "Failed to uninstall Nerd Fonts. Error: $_" -ForegroundColor Red
}
# Attempt to uninstall the specified Nerd Fonts registry keys from the system.
try {
# Specify the registry path that the specified font registry keys will be uninstalled from.
[string]$FontsRegPath = "HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"
# Specify the name of the font registry keys that is to be uninstalled from the system.
[string]$FontFamilyName = "CaskaydiaCove"
# Call the function used to uninstall the specified Nerd Fonts registry keys from the system.
Uninstall-NerdFontRegKeys -FontsPath $FontsRegPath -FontFamilyName $FontFamilyName
} catch {
# Let the user know that an error was encountered when uninstalling Nerd Font registry keys.
Write-Host "Failed to uninstall Nerd Font Registry Keys. Error: $_" -ForegroundColor Red
}
# Attempt to uninstall the Terminal-Icons PowerShell module from the system.
try {
# Get the content of the backup PowerShell profile and store it in-memory.
@ -228,4 +185,3 @@ function Invoke-WinUtilUninstallPSProfile {
}
}
}

View File

@ -0,0 +1,50 @@
function Invoke-WinUtilpsProfile {
<#
.SYNOPSIS
Installs & applies the CTT Powershell Profile
#>
Invoke-WPFRunspace -Argumentlist $PROFILE -DebugPreference $DebugPreference -ScriptBlock {
param ( $psprofile)
function Invoke-PSSetup {
$url = "https://raw.githubusercontent.com/ChrisTitusTech/powershell-profile/main/Microsoft.PowerShell_profile.ps1"
$oldhash = Get-FileHash $psprofile -ErrorAction SilentlyContinue
Invoke-RestMethod $url -OutFile "$env:temp/Microsoft.PowerShell_profile.ps1"
$newhash = Get-FileHash "$env:temp/Microsoft.PowerShell_profile.ps1"
if ($newhash.Hash -ne $oldhash.Hash) {
write-host "===> Installing Profile.. <===" -ForegroundColor Yellow
# Starting new hidden shell process bc setup does not work in a runspace
Start-Process -FilePath "pwsh" -ArgumentList "-ExecutionPolicy Bypass -NoProfile -Command `"Invoke-Expression (Invoke-WebRequest `'https://github.com/ChrisTitusTech/powershell-profile/raw/main/setup.ps1`')`"" -WindowStyle Hidden -Wait
Write-Host "Profile has been installed. Please restart your shell to reflect changes!" -ForegroundColor Magenta
write-host "===> Finished <===" -ForegroundColor Yellow
} else {
Write-Host "Profile is up to date" -ForegroundColor Green
}
}
if (Get-Command "pwsh" -ErrorAction SilentlyContinue) {
if ($PSVersionTable.PSVersion.Major -ge 7) {
Invoke-PSSetup
}
else {
write-host "Profile requires Powershell 7, which is currently installed but not used!" -ForegroundColor Red
# Load the necessary assembly for Windows Forms
Add-Type -AssemblyName System.Windows.Forms
# Display the Yes/No message box
$question = [System.Windows.Forms.MessageBox]::Show("Profile requires Powershell 7, which is currently installed but not used! Do you want to install Profile for Powershell 7?", "Question",
[System.Windows.Forms.MessageBoxButtons]::YesNo,
[System.Windows.Forms.MessageBoxIcon]::Question)
# Check the result
if ($question -eq [System.Windows.Forms.DialogResult]::Yes) {
Invoke-PSSetup
}
else {
Write-Host "Not proceeding with the profile setup!"
}
}
}
else {
write-host "Profile requires Powershell 7, which is not installed!" -ForegroundColor Red
}
}
}

View File

@ -1,44 +0,0 @@
function Set-CategoryVisibility {
<#
.SYNOPSIS
Used to expand or collapse categories and corresponding apps on the install tab
.PARAMETER Category
Can eigther be a specific category name like "Browsers" OR "*" to affect all categories at once
.PARAMETER overrideState
"Expand" => expands the corresponding elements
"Collapse" => collapses the corresponding elements
N/A => if compactView is active expand, otherwise collapse elements
#>
param(
[Parameter(Mandatory=$true)]
[string]$Category,
[ValidateSet("Expand", "Collapse")]
[string]$overrideState
)
switch ($overrideState) {
"Expand" {$state = $true}
"Collapse" {$state = $false}
default {$state = $sync.CompactView}
}
# If all the Categories are affected, update the Checked state of the ToggleButtons.
# Otherwise, the state is not synced when toggling between the display modes
if ($category -eq "*") {
$items = $sync.ItemsControl.Items | Where-Object {($_.Tag -like "CategoryWrapPanel_*")}
$sync.ItemsControl.Items | Where-Object {($_.Tag -eq "CategoryToggleButton")} | Foreach-Object { $_.Visibility = [Windows.Visibility]::Visible; $_.IsChecked = $state }
} else {
$items = $sync.ItemsControl.Items | Where-Object {($_.Tag -eq "CategoryWrapPanel_$Category")}
}
$elementVisibility = if ($state -eq $true) {[Windows.Visibility]::Visible} else {[Windows.Visibility]::Collapsed}
$items | ForEach-Object {
$_.Visibility = $elementVisibility
}
$items.Children | ForEach-Object {
$_.Visibility = $elementVisibility
}
}

View File

@ -1,43 +0,0 @@
function Set-PackageManagerPreference {
<#
.SYNOPSIS
Sets the currently selected package manager to global "ManagerPreference" in sync.
Also persists preference across Winutil restarts via preference.ini.
Reads from preference.ini if no argument sent.
.PARAMETER preferedPackageManager
The PackageManager that was selected.
#>
param(
[Parameter(Position=0, Mandatory=$false)]
[PackageManagers]$preferedPackageManager
)
$preferencePath = "$env:LOCALAPPDATA\winutil\preferences.ini"
$oldChocoPath = "$env:LOCALAPPDATA\winutil\preferChocolatey.ini"
#Try loading from file if no argument given.
if ($null -eq $preferedPackageManager) {
# Backwards compat for preferChocolatey.ini
if (Test-Path -Path $oldChocoPath) {
$preferedPackageManager = [PackageManagers]::Choco
Remove-Item -Path $oldChocoPath
}
elseif (Test-Path -Path $preferencePath) {
$potential = Get-Content -Path $preferencePath -TotalCount 1
$preferedPackageManager = [PackageManagers]$potential
}
else {
Write-Debug "Creating new preference file, defaulting to winget."
$preferedPackageManager = [PackageManagers]::Winget
}
}
$sync["ManagerPreference"] = [PackageManagers]::$preferedPackageManager
Write-Debug "Manager Preference changed to '$($sync["ManagerPreference"])'"
# Write preference to file to persist across restarts.
Out-File -FilePath $preferencePath -InputObject $sync["ManagerPreference"]
}

View File

@ -47,8 +47,6 @@ function Set-WinUtilRegistry {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning $psitem.Exception.ErrorRecord
} catch [System.UnauthorizedAccessException] {
Write-Warning $psitem.Exception.Message
} catch {
Write-Warning "Unable to set $Name due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace

View File

@ -1,54 +0,0 @@
function Show-OnlyCheckedApps {
<#
.SYNOPSIS
Toggle between showing only the actively selected apps on the Install Tab and hiding everything else and displaying every app.
If no apps are selected, dont do anything
.PARAMETER appKeys
Expects a List of appKeys that are selected at the moment
If not provided, or empty, the function exits without any visual change to the ui
.EXAMPLE
Show-OnlyCheckedApps -appKeys $sync.SelectedApps
Show-OnlyCheckedApps -appKeys ("WPFInstallChrome", "WPFInstall7zip")
#>
param (
[Parameter(Mandatory=$false)]
[String[]]$appKeys
)
# If no apps are selected, do not allow switching to show only selected
if (($false -eq $sync.ShowOnlySelected) -and ($appKeys.Length -eq 0)) {
Write-Host "No apps selected"
$sync.wpfselectedfilter.IsChecked = $false
return
}
$sync.ShowOnlySelected = -not $sync.ShowOnlySelected
if ($sync.ShowOnlySelected) {
$sync.Buttons | Where-Object {$_.Name -like "ShowSelectedAppsButton"} | ForEach-Object {
$_.Content = "Show All"
}
$sync.ItemsControl.Items | Foreach-Object {
# Search for App Container and set them to visible
if ($_.Tag -like "CategoryWrapPanel_*") {
$_.Visibility = [Windows.Visibility]::Visible
# Iterate through all the apps in the container and set them to visible if they are in the appKeys array
$_.Children | ForEach-Object {
if ($appKeys -contains $_.Tag) {
$_.Visibility = [Windows.Visibility]::Visible
}
else {
$_.Visibility = [Windows.Visibility]::Collapsed
}
}
}
else {
# Set all other items to collapsed
$_.Visibility = [Windows.Visibility]::Collapsed
}
}
} else {
$sync.Buttons | Where-Object {$_.Name -like "ShowSelectedAppsButton"} | ForEach-Object {
$_.Content = "Show Selected"
}
Set-CategoryVisibility -Category "*"
}
}

View File

@ -23,15 +23,7 @@ function Test-WinUtilPackageManager {
# Check if Winget is available while getting it's Version if it's available
$wingetExists = $true
try {
$wingetInfo = winget --info
# Extract the package version from the output
$wingetVersionFull = ($wingetInfo | Select-String -Pattern 'Microsoft\.DesktopAppInstaller v\d+\.\d+\.\d+\.\d+').Matches.Value
if ($wingetVersionFull) {
$wingetVersionFull = $wingetVersionFull.Split(' ')[-1].TrimStart('v')
} else {
# Fallback in case the pattern isn't found
$wingetVersionFull = ($wingetInfo | Select-String -Pattern 'Package Manager v\d+\.\d+\.\d+').Matches.Value.Split(' ')[-1]
}
$wingetVersionFull = winget --version
} catch [System.Management.Automation.CommandNotFoundException], [System.Management.Automation.ApplicationFailedException] {
Write-Warning "Winget was not found due to un-availablity reasons"
$wingetExists = $false
@ -56,14 +48,13 @@ function Test-WinUtilPackageManager {
# Check if Winget's Version is too old.
$wingetCurrentVersion = [System.Version]::Parse($wingetVersion.Trim('v'))
# Grabs the latest release of Winget from the Github API for version check process.
$response = winget search -e Microsoft.AppInstaller --accept-source-agreements
$wingetLatestVersion = ($response | Select-String -Pattern '\d+\.\d+\.\d+\.\d+').Matches.Value
Write-Host "Latest Search Version: $wingetLatestVersion" -ForegroundColor White
Write-Host "Current Installed Version: $wingetCurrentVersion" -ForegroundColor White
$wingetOutdated = $wingetCurrentVersion -lt [System.Version]::Parse($wingetLatestVersion)
$response = Invoke-RestMethod -Uri "https://api.github.com/repos/microsoft/Winget-cli/releases/latest" -Method Get -ErrorAction Stop
$wingetLatestVersion = [System.Version]::Parse(($response.tag_name).Trim('v')) #Stores version number of latest release.
$wingetOutdated = $wingetCurrentVersion -lt $wingetLatestVersion
Write-Host "===========================================" -ForegroundColor Green
Write-Host "--- Winget is installed ---" -ForegroundColor Green
Write-Host "===========================================" -ForegroundColor Green
Write-Host "Version: $wingetVersionFull" -ForegroundColor White
if (!$wingetPreview) {
Write-Host " - Winget is a release version." -ForegroundColor Green

View File

@ -26,15 +26,14 @@ function Invoke-WPFButton {
"WPFStandard" {Invoke-WPFPresets "Standard" -checkboxfilterpattern "WPFTweak*"}
"WPFMinimal" {Invoke-WPFPresets "Minimal" -checkboxfilterpattern "WPFTweak*"}
"WPFClearTweaksSelection" {Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFTweak*"}
"WPFClearInstallSelection" {Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFInstall*"; Show-OnlyCheckedApps; $sync.wpfselectedfilter.IsChecked = $false}
"WPFSelectedFilter" {Show-OnlyCheckedApps -appKeys $sync.SelectedApps}
"WPFClearInstallSelection" {Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFInstall*"}
"WPFtweaksbutton" {Invoke-WPFtweaksbutton}
"WPFOOSUbutton" {Invoke-WPFOOSU}
"WPFAddUltPerf" {Invoke-WPFUltimatePerformance -State "Enable"}
"WPFRemoveUltPerf" {Invoke-WPFUltimatePerformance -State "Disable"}
"WPFundoall" {Invoke-WPFundoall}
"WPFFeatureInstall" {Invoke-WPFFeatureInstall}
"WPFPanelDISM" {Invoke-WPFSystemRepair}
"WPFPanelDISM" {Invoke-WPFPanelDISM}
"WPFPanelAutologin" {Invoke-WPFPanelAutologin}
"WPFPanelcontrol" {Invoke-WPFControlPanel -Panel $button}
"WPFPanelnetwork" {Invoke-WPFControlPanel -Panel $button}
@ -44,7 +43,6 @@ function Invoke-WPFButton {
"WPFPanelprinter" {Invoke-WPFControlPanel -Panel $button}
"WPFPanelsystem" {Invoke-WPFControlPanel -Panel $button}
"WPFPaneluser" {Invoke-WPFControlPanel -Panel $button}
"WPFPanelGodMode" {Invoke-WPFControlPanel -Panel $button}
"WPFUpdatesdefault" {Invoke-WPFFixesUpdate}
"WPFFixesUpdate" {Invoke-WPFFixesUpdate}
"WPFFixesWinget" {Invoke-WPFFixesWinget}
@ -61,6 +59,6 @@ function Invoke-WPFButton {
"MicrowinScratchDirBT" {Invoke-ScratchDialog}
"WPFWinUtilInstallPSProfile" {Invoke-WinUtilInstallPSProfile}
"WPFWinUtilUninstallPSProfile" {Invoke-WinUtilUninstallPSProfile}
"WPFWinUtilSSHServer" {Invoke-WPFSSHServer}
"WPFWinUtilSSHServer" {Invoke-WinUtilSSHServer}
}
}

View File

@ -19,6 +19,5 @@ function Invoke-WPFControlPanel {
"WPFPanelprinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
"WPFPanelsystem" {cmd /c sysdm.cpl}
"WPFPaneluser" {cmd /c "control userpasswords2"}
"WPFPanelGodMode" {Start-Process "shell:::{ED7BA470-8E54-465E-825C-99712043E01C}"}
}
}

View File

@ -6,7 +6,19 @@ function Invoke-WPFFixesUpdate {
Performs various tasks in an attempt to repair Windows Update
.DESCRIPTION
1. (Aggressive Only) Scans the system for corruption using the Invoke-WPFSystemRepair function
1. (Aggressive Only) Scans the system for corruption using chkdsk, SFC, and DISM
Steps:
1. Runs chkdsk /scan /perf
/scan - Runs an online scan on the volume
/perf - Uses more system resources to complete a scan as fast as possible
2. Runs SFC /scannow
/scannow - Scans integrity of all protected system files and repairs files with problems when possible
3. Runs DISM /Online /Cleanup-Image /RestoreHealth
/Online - Targets the running operating system
/Cleanup-Image - Performs cleanup and recovery operations on the image
/RestoreHealth - Scans the image for component store corruption and attempts to repair the corruption using Windows Update
4. Runs SFC /scannow
Ran twice in case DISM repaired SFC
2. Stops Windows Update Services
3. Remove the QMGR Data file, which stores BITS jobs
4. (Aggressive Only) Renames the DataStore and CatRoot2 folders
@ -34,7 +46,104 @@ function Invoke-WPFFixesUpdate {
Start-Sleep -Milliseconds 200
if ($Aggressive) {
Invoke-WPFSystemRepair
# Scan system for corruption
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Scanning for corruption..." -PercentComplete 0
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running chkdsk..." -PercentComplete 0
# 2>&1 redirects stdout, alowing iteration over the output
chkdsk.exe /scan /perf 2>&1 | ForEach-Object {
# Write stdout to the Verbose stream
Write-Verbose $_
# Get the index of the total percentage
$index = $_.IndexOf("Total:")
if (
# If the percent is found
($percent = try {(
$_.Substring(
$index + 6,
$_.IndexOf("%", $index) - $index - 6
)
).Trim()} catch {0}) `
<# And the current percentage is greater than the previous one #>`
-and $percent -gt $oldpercent
) {
# Update the progress bar
$oldpercent = $percent
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running chkdsk... ($percent%)" -PercentComplete $percent
}
}
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC..." -PercentComplete 0
$oldpercent = 0
# SFC has a bug when redirected which causes it to output only when the stdout buffer is full, causing the progress bar to move in chunks
sfc /scannow 2>&1 | ForEach-Object {
# Write stdout to the Verbose stream
Write-Verbose $_
# Filter for lines that contain a percentage that is greater than the previous one
if (
(
# Use a different method to get the percentage that accounts for SFC's Unicode output
[int]$percent = try {(
(
$_.Substring(
$_.IndexOf("n") + 2,
$_.IndexOf("%") - $_.IndexOf("n") - 2
).ToCharArray() | Where-Object {$_}
) -join ''
).TrimStart()} catch {0}
) -and $percent -gt $oldpercent
) {
# Update the progress bar
$oldpercent = $percent
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC... ($percent%)" -PercentComplete $percent
}
}
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running DISM..." -PercentComplete 0
$oldpercent = 0
DISM /Online /Cleanup-Image /RestoreHealth | ForEach-Object {
# Write stdout to the Verbose stream
Write-Verbose $_
# Filter for lines that contain a percentage that is greater than the previous one
if (
($percent = try {
[int]($_ -replace "\[" -replace "=" -replace " " -replace "%" -replace "\]")
} catch {0}) `
-and $percent -gt $oldpercent
) {
# Update the progress bar
$oldpercent = $percent
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running DISM... ($percent%)" -PercentComplete $percent
}
}
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC again..." -PercentComplete 0
$oldpercent = 0
sfc /scannow 2>&1 | ForEach-Object {
# Write stdout to the Verbose stream
Write-Verbose $_
# Filter for lines that contain a percentage that is greater than the previous one
if (
(
[int]$percent = try {(
(
$_.Substring(
$_.IndexOf("n") + 2,
$_.IndexOf("%") - $_.IndexOf("n") - 2
).ToCharArray() | Where-Object {$_}
) -join ''
).TrimStart()} catch {0}
) -and $percent -gt $oldpercent
) {
# Update the progress bar
$oldpercent = $percent
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC... ($percent%)" -PercentComplete $percent
}
}
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Completed" -PercentComplete 100
}

View File

@ -0,0 +1,36 @@
Function Invoke-WPFFormVariables {
<#
.SYNOPSIS
Prints the logo
#>
#If ($global:ReadmeDisplay -ne $true) { Write-Host "If you need to reference this display again, run Get-FormVariables" -ForegroundColor Yellow; $global:ReadmeDisplay = $true }
Write-Host ""
Write-Host " CCCCCCCCCCCCCTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT "
Write-Host " CCC::::::::::::CT:::::::::::::::::::::TT:::::::::::::::::::::T "
Write-Host "CC:::::::::::::::CT:::::::::::::::::::::TT:::::::::::::::::::::T "
Write-Host "C:::::CCCCCCCC::::CT:::::TT:::::::TT:::::TT:::::TT:::::::TT:::::T "
Write-Host "C:::::C CCCCCCTTTTTT T:::::T TTTTTTTTTTTT T:::::T TTTTTT"
Write-Host "C:::::C T:::::T T:::::T "
Write-Host "C:::::C T:::::T T:::::T "
Write-Host "C:::::C T:::::T T:::::T "
Write-Host "C:::::C T:::::T T:::::T "
Write-Host "C:::::C T:::::T T:::::T "
Write-Host "C:::::C T:::::T T:::::T "
Write-Host "C:::::C CCCCCC T:::::T T:::::T "
Write-Host "C:::::CCCCCCCC::::C TT:::::::TT TT:::::::TT "
Write-Host "CC:::::::::::::::C T:::::::::T T:::::::::T "
Write-Host "CCC::::::::::::C T:::::::::T T:::::::::T "
Write-Host " CCCCCCCCCCCCC TTTTTTTTTTT TTTTTTTTTTT "
Write-Host ""
Write-Host "====Chris Titus Tech====="
Write-Host "=====Windows Toolbox====="
#====DEBUG GUI Elements====
#Write-Host "Found the following interactable elements from our form" -ForegroundColor Cyan
#get-variable WPF*
}

View File

@ -9,51 +9,42 @@ function Invoke-WPFGetInstalled {
#>
param($checkbox)
if ($sync.ProcessRunning) {
if($sync.ProcessRunning) {
$msg = "[Invoke-WPFGetInstalled] Install process is currently running."
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
return
}
if (($sync.ChocoRadioButton.IsChecked -eq $false) -and ((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget") {
if(($sync.WPFpreferChocolatey.IsChecked -eq $false) -and ((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget") {
return
}
$managerPreference = $sync["ManagerPreference"]
$sync.ItemsControl.Dispatcher.Invoke([action] {
$sync.ItemsControl.Items | ForEach-Object { $_.Visibility = [Windows.Visibility]::Collapsed }
$null = $sync.itemsControl.Items.Add($sync.LoadingLabel)
})
Invoke-WPFRunspace -ParameterList @(("managerPreference", $managerPreference),("checkbox", $checkbox),("ShowOnlyCheckedApps", ${function:Show-OnlyCheckedApps})) -DebugPreference $DebugPreference -ScriptBlock {
param (
[string]$checkbox,
[PackageManagers]$managerPreference,
[scriptblock]$ShowOnlyCheckedApps
)
$sync.ProcessRunning = $true
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "Indeterminate" })
$preferChoco = $sync.WPFpreferChocolatey.IsChecked
Invoke-WPFRunspace -ArgumentList $checkbox, $preferChoco -DebugPreference $DebugPreference -ScriptBlock {
param($checkbox, $preferChoco, $DebugPreference)
if ($checkbox -eq "winget") {
$sync.ProcessRunning = $true
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" })
if($checkbox -eq "winget") {
Write-Host "Getting Installed Programs..."
switch ($managerPreference) {
"Choco"{$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox "choco"; break}
"Winget"{$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox; break}
}
}
elseif ($checkbox -eq "tweaks") {
if($checkbox -eq "tweaks") {
Write-Host "Getting Installed Tweaks..."
}
if ($preferChoco -and $checkbox -eq "winget") {
$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox "choco"
}
else{
$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox
}
$sync.form.Dispatcher.invoke({
foreach ($checkbox in $Checkboxes) {
foreach($checkbox in $Checkboxes) {
$sync.$checkbox.ischecked = $True
}
})
$sync.ItemsControl.Dispatcher.Invoke([action] {
$ShowOnlyCheckedApps.Invoke($sync.SelectedApps)
$sync["WPFSelectedFilter"].IsChecked = $true
$sync.ItemsControl.Items.Remove($sync.LoadingLabel)
})
Write-Host "Done..."
$sync.ProcessRunning = $false
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "None" })

View File

@ -46,7 +46,7 @@ function Invoke-WPFImpex {
if ($Config) {
$jsonFile = Get-WinUtilCheckBoxes -unCheck $false | ConvertTo-Json
$jsonFile | Out-File $Config -Force
"iex ""& { `$(irm https://christitus.com/win) } -Config '$Config'""" | Set-Clipboard
"iex ""& { `$(irm christitus.com/win) } -Config '$Config'""" | Set-Clipboard
}
} catch {
Write-Error "An error occurred while exporting: $_"

View File

@ -1,8 +1,4 @@
function Invoke-WPFInstall {
param (
[Parameter(Mandatory=$false)]
[PSObject[]]$PackagesToInstall = $($sync.selectedApps | Foreach-Object { $sync.configs.applicationsHashtable.$_ })
)
<#
.SYNOPSIS
@ -16,21 +12,47 @@ function Invoke-WPFInstall {
return
}
$PackagesToInstall = (Get-WinUtilCheckBoxes)["Install"]
Write-Host $PackagesToInstall
if ($PackagesToInstall.Count -eq 0) {
$WarningMsg = "Please select the program(s) to install or upgrade"
[System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
return
}
$ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked)
$installHandle = Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $ChocoPreference, $DebugPreference)
if ($PackagesToInstall.count -eq 1) {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
$packagesWinget, $packagesChoco = {
$packagesWinget = [System.Collections.ArrayList]::new()
$packagesChoco = [System.Collections.ArrayList]::new()
$ManagerPreference = $sync["ManagerPreference"]
Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $ManagerPreference, $DebugPreference)
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToInstall -Preference $ManagerPreference
$packagesWinget = $packagesSorted[[PackageManagers]::Winget]
$packagesChoco = $packagesSorted[[PackageManagers]::Choco]
foreach ($package in $PackagesToInstall) {
if ($ChocoPreference) {
if ($package.choco -eq "na") {
$packagesWinget.add($package.winget)
Write-Host "Queueing $($package.winget) for Winget install"
} else {
$null = $packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey install"
}
}
else {
if ($package.winget -eq "na") {
$packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey install"
} else {
$null = $packagesWinget.add($($package.winget))
Write-Host "Queueing $($package.winget) for Winget install"
}
}
}
return $packagesWinget, $packagesChoco
}.Invoke($PackagesToInstall)
try {
$sync.ProcessRunning = $true

View File

@ -5,7 +5,7 @@ function Invoke-WPFInstallUpgrade {
Invokes the function that upgrades all installed programs
#>
if ($sync.ChocoRadioButton.IsChecked) {
if ($sync.WPFpreferChocolatey.IsChecked) {
Install-WinUtilChoco
$chocoUpgradeStatus = (Start-Process "choco" -ArgumentList "upgrade all -y" -Wait -PassThru -NoNewWindow).ExitCode
if ($chocoUpgradeStatus -eq 0) {

View File

@ -0,0 +1,30 @@
function Invoke-WPFPanelDISM {
<#
.SYNOPSIS
Checks for system corruption using Chkdsk, SFC, and DISM
.DESCRIPTION
1. Chkdsk - Fixes disk and filesystem corruption
2. SFC Run 1 - Fixes system file corruption, and fixes DISM if it was corrupted
3. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
4. SFC Run 2 - Fixes system file corruption, this time with an almost guaranteed uncorrupted system image
.NOTES
Command Arguments:
1. Chkdsk
/Scan - Runs an online scan on the system drive, attempts to fix any corruption, and queues other corruption for fixing on reboot
2. SFC
/ScanNow - Performs a scan of the system files and fixes any corruption
3. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
/Online - Fixes the currently running system image
/Cleanup-Image - Performs cleanup operations on the image, could remove some unneeded temporary files
/Restorehealth - Performs a scan of the image and fixes any corruption
#>
Start-Process PowerShell -ArgumentList "Write-Host '(1/4) Chkdsk' -ForegroundColor Green; Chkdsk /scan;
Write-Host '`n(2/4) SFC - 1st scan' -ForegroundColor Green; sfc /scannow;
Write-Host '`n(3/4) DISM' -ForegroundColor Green; DISM /Online /Cleanup-Image /Restorehealth;
Write-Host '`n(4/4) SFC - 2nd scan' -ForegroundColor Green; sfc /scannow;
Read-Host '`nPress Enter to Continue'" -verb runas
}

View File

@ -1,17 +0,0 @@
function Invoke-WPFSSHServer {
<#
.SYNOPSIS
Invokes the OpenSSH Server install in a runspace
#>
Invoke-WPFRunspace -DebugPreference $DebugPreference -ScriptBlock {
Invoke-WinUtilSSHServer
Write-Host "======================================="
Write-Host "-- OpenSSH Server installed! ---"
Write-Host "======================================="
}
}

View File

@ -1,43 +0,0 @@
function Invoke-WPFSelectedAppsUpdate {
<#
.SYNOPSIS
This is a helper function that is called by the Checked and Unchecked events of the Checkboxes on the install tab.
It Updates the "Selected Apps" selectedAppLabel on the Install Tab to represent the current collection
.PARAMETER type
Eigther: Add | Remove
.PARAMETER checkbox
should contain the current instance of the checkbox that triggered the Event.
Most of the time will be the automatic variable $this
.EXAMPLE
$checkbox.Add_Unchecked({Invoke-WPFSelectedAppsUpdate -type "Remove" -checkbox $this})
OR
Invoke-WPFSelectedAppsUpdate -type "Add" -checkbox $specificCheckbox
#>
param (
$type,
$checkbox
)
$selectedAppsButton = $sync.WPFselectedAppsButton
# Get the actual Name from the selectedAppLabel inside the Checkbox
$appKey = $checkbox.Parent.Parent.Tag
if ($type -eq "Add") {
$sync.selectedApps.Add($appKey)
# The List type needs to be specified again, because otherwise Sort-Object will convert the list to a string if there is only a single entry
[System.Collections.Generic.List[pscustomobject]]$sync.selectedApps = $sync.SelectedApps | Sort-Object
}
elseif ($type -eq "Remove") {
$sync.SelectedApps.Remove($appKey)
}
else{
Write-Error "Type: $type not implemented"
}
$count = $sync.SelectedApps.Count
$selectedAppsButton.Content = "Selected Apps: $count"
# On every change, remove all entries inside the Popup Menu. This is done, so we can keep the alphabetical order even if elements are selected in a random way
$sync.selectedAppsstackPanel.Children.Clear()
$sync.SelectedApps | Foreach-Object { Add-SelectedAppsMenuItem -name $($sync.configs.applicationsHashtable.$_.Content) -key $_ }
}

View File

@ -1,124 +0,0 @@
function Invoke-WPFSystemRepair {
<#
.SYNOPSIS
Checks for system corruption using Chkdsk, SFC, and DISM
.DESCRIPTION
1. Chkdsk - Fixes disk and filesystem corruption
2. SFC Run 1 - Fixes system file corruption, and fixes DISM if it was corrupted
3. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
4. SFC Run 2 - Fixes system file corruption, this time with an almost guaranteed uncorrupted system image
#>
function Invoke-Chkdsk {
<#
.SYNOPSIS
Runs chkdsk on the system drive
.DESCRIPTION
Chkdsk /Scan - Runs an online scan on the system drive, attempts to fix any corruption, and queues other corruption for fixing on reboot
#>
param(
[int]$parentProgressId = 0
)
Write-Progress -Id 1 -ParentId $parentProgressId -Activity $childProgressBarActivity -Status "Running chkdsk..." -PercentComplete 0
$oldpercent = 0
# 2>&1 redirects stdout, allowing iteration over the output
chkdsk.exe /scan /perf 2>&1 | ForEach-Object {
Write-Debug $_
# Regex to match the total percentage regardless of windows locale (it's always the second percentage in the status output)
if ($_ -match "%.*?(\d+)%") {
[int]$percent = $matches[1]
if ($percent -gt $oldpercent) {
Write-Progress -Id 1 -Activity $childProgressBarActivity -Status "Running chkdsk... ($percent%)" -PercentComplete $percent
$oldpercent = $percent
}
}
}
Write-Progress -Id 1 -Activity $childProgressBarActivity -Status "chkdsk Completed" -PercentComplete 100 -Completed
}
function Invoke-SFC {
<#
.SYNOPSIS
Runs sfc on the system drive
.DESCRIPTION
SFC /ScanNow - Performs a scan of the system files and fixes any corruption
.NOTES
ErrorActionPreference is set locally within a script block & {...} to isolate their effects.
ErrorActionPreference suppresses false errors caused by sfc.exe output redirection.
A bug in SFC output buffering causes progress updates to appear in chunks when redirecting output
#>
param(
[int]$parentProgressId = 0
)
& {
$ErrorActionPreference = "SilentlyContinue"
Write-Progress -Id 1 -ParentId $parentProgressId -Activity $childProgressBarActivity -Status "Running SFC..." -PercentComplete 0
$oldpercent = 0
sfc.exe /scannow 2>&1 | ForEach-Object {
Write-Debug $_
if ($_ -ne "") {
# sfc.exe /scannow outputs unicode characters, so we directly remove null characters for optimization
$utf8line = $_ -replace "`0", ""
if ($utf8line -match "(\d+)\s*%") {
[int]$percent = $matches[1]
if ($percent -gt $oldpercent) {
Write-Progress -Id 1 -Activity $childProgressBarActivity -Status "Running SFC... ($percent%)" -PercentComplete $percent
$oldpercent = $percent
}
}
}
}
Write-Progress -Id 1 -Activity $childProgressBarActivity -Status "SFC Completed" -PercentComplete 100 -Completed
}
}
function Invoke-DISM {
<#
.SYNOPSIS
Runs DISM on the system drive
.DESCRIPTION
DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
/Online - Fixes the currently running system image
/Cleanup-Image - Performs cleanup operations on the image, could remove some unneeded temporary files
/Restorehealth - Performs a scan of the image and fixes any corruption
#>
param(
[int]$parentProgressId = 0
)
Write-Progress -Id 1 -ParentId $parentProgressId -Activity $childProgressBarActivity -Status "Running DISM..." -PercentComplete 0
$oldpercent = 0
DISM /Online /Cleanup-Image /RestoreHealth | ForEach-Object {
Write-Debug $_
# Filter for lines that contain a percentage that is greater than the previous one
if ($_ -match "(\d+)[.,]\d+%") {
[int]$percent = $matches[1]
if ($percent -gt $oldpercent) {
# Update the progress bar
Write-Progress -Id 1 -Activity $childProgressBarActivity -Status "Running DISM... ($percent%)" -PercentComplete $percent
$oldpercent = $percent
}
}
}
Write-Progress -Id 1 -Activity $childProgressBarActivity -Status "DISM Completed" -PercentComplete 100 -Completed
}
$childProgressBarActivity = "Scanning for corruption"
Write-Progress -Id 0 -Activity "Repairing Windows" -PercentComplete 0
# Step 1: Run chkdsk to fix disk and filesystem corruption before proceeding with system file repairs
Invoke-Chkdsk
Write-Progress -Id 0 -Activity "Repairing Windows" -PercentComplete 25
# Step 2: Run SFC to fix system file corruption and ensure DISM can operate correctly
Invoke-SFC
Write-Progress -Id 0 -Activity "Repairing Windows" -PercentComplete 50
# Step 3: Run DISM to repair the system image, which SFC relies on for accurate repairs
Invoke-DISM
Write-Progress -Id 0 -Activity "Repairing Windows" -PercentComplete 75
# Step 4: Run SFC again to ensure system files are repaired using the now-fixed system image
Invoke-SFC
Write-Progress -Id 0 -Activity "Repairing Windows" -PercentComplete 100 -Completed
}

View File

@ -28,31 +28,4 @@ function Invoke-WPFTab {
$sync.$tabNav.Items[$tabNumber].IsSelected = $true
}
}
$sync.currentTab = $sync.$tabNav.Items[$tabNumber].Header
# Always reset the filter for the current tab
if ($sync.currentTab -eq "Install") {
# Reset Install tab filter
Find-AppsByNameOrDescription -SearchString ""
} elseif ($sync.currentTab -eq "Tweaks") {
# Reset Tweaks tab filter
Find-TweaksByNameOrDescription -SearchString ""
}
# Show search bar in Install and Tweaks tabs
if ($tabNumber -eq 0 -or $tabNumber -eq 1) {
$sync.SearchBar.Visibility = "Visible"
$searchIcon = ($sync.Form.FindName("SearchBar").Parent.Children | Where-Object { $_ -is [System.Windows.Controls.TextBlock] -and $_.Text -eq [char]0xE721 })[0]
if ($searchIcon) {
$searchIcon.Visibility = "Visible"
}
} else {
$sync.SearchBar.Visibility = "Collapsed"
$searchIcon = ($sync.Form.FindName("SearchBar").Parent.Children | Where-Object { $_ -is [System.Windows.Controls.TextBlock] -and $_.Text -eq [char]0xE721 })[0]
if ($searchIcon) {
$searchIcon.Visibility = "Collapsed"
}
# Hide the clear button if it's visible
$sync.SearchBarClearButton.Visibility = "Collapsed"
}
}

View File

@ -1,22 +0,0 @@
function Invoke-WPFUIApps {
[OutputType([void])]
param(
[Parameter(Mandatory, Position = 0)]
[PSCustomObject[]]$Apps,
[Parameter(Mandatory, Position = 1)]
[string]$TargetGridName
)
switch ($TargetGridName) {
"appspanel" {
$dockPanel = Initialize-InstallAppsMainElement -TargetGridName $TargetGridName
$null = Initialize-InstallHeader -TargetElement $dockPanel
$sync.ItemsControl = Initialize-InstallAppArea -TargetElement $dockPanel
Initialize-InstallCategoryAppList -TargetElement $sync.ItemsControl -Apps $Apps
}
default {
Write-Output "$TargetGridName not yet implemented"
}
}
}

View File

@ -11,26 +11,26 @@ function Invoke-WPFUIElements {
.EXAMPLE
Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "install" -columncount 5
.NOTES
Future me/contributor: If possible, please wrap this into a runspace to make it load all panels at the same time.
Future me/contributer: If possible please wrap this into a runspace to make it load all panels at the same time.
#>
param(
[Parameter(Mandatory, Position = 0)]
[Parameter(Mandatory, position=0)]
[PSCustomObject]$configVariable,
[Parameter(Mandatory, Position = 1)]
[Parameter(Mandatory, position=1)]
[string]$targetGridName,
[Parameter(Mandatory, Position = 2)]
[Parameter(Mandatory, position=2)]
[int]$columncount
)
$window = $sync.form
$window = $sync["Form"]
$theme = $sync.Form.Resources
$borderstyle = $window.FindResource("BorderStyle")
$HoverTextBlockStyle = $window.FindResource("HoverTextBlockStyle")
$ColorfulToggleSwitchStyle = $window.FindResource("ColorfulToggleSwitchStyle")
$ToggleButtonStyle = $window.FindResource("ToggleButtonStyle")
if (!$borderstyle -or !$HoverTextBlockStyle -or !$ColorfulToggleSwitchStyle) {
throw "Failed to retrieve Styles using 'FindResource' from main window element."
@ -59,8 +59,6 @@ function Invoke-WPFUIElements {
$configHashtable[$_] = $configVariable.$_
}
$radioButtonGroups = @{}
$organizedData = @{}
# Iterate through JSON data and organize by panel and category
foreach ($entry in $configHashtable.Keys) {
@ -72,6 +70,8 @@ function Invoke-WPFUIElements {
Order = $entryInfo.order
Category = $entryInfo.Category
Content = $entryInfo.Content
Choco = $entryInfo.choco
Winget = $entryInfo.winget
Panel = if ($entryInfo.Panel) { $entryInfo.Panel } else { "0" }
Link = $entryInfo.link
Description = $entryInfo.description
@ -79,7 +79,6 @@ function Invoke-WPFUIElements {
ComboItems = $entryInfo.ComboItems
Checked = $entryInfo.Checked
ButtonWidth = $entryInfo.ButtonWidth
GroupName = $entryInfo.GroupName # Added for RadioButton groupings
}
if (-not $organizedData.ContainsKey($entryObject.Panel)) {
@ -97,13 +96,11 @@ function Invoke-WPFUIElements {
if ($targetGridName -eq "appspanel") {
$panelcount = 0
$entrycount = $configHashtable.Keys.Count + $organizedData["0"].Keys.Count
$maxcount = [Math]::Round($entrycount / $columncount + 0.5)
}
}
# Initialize panel count
$panelcount = 0
# Iterate through 'organizedData' by panel, category, and application
$count = 0
foreach ($panelKey in ($organizedData.Keys | Sort-Object)) {
@ -114,46 +111,78 @@ function Invoke-WPFUIElements {
$border.style = $borderstyle
$targetGrid.Children.Add($border) | Out-Null
# Use a DockPanel to contain the content
$dockPanelContainer = New-Object Windows.Controls.DockPanel
$border.Child = $dockPanelContainer
# Create an ItemsControl for application content
$itemsControl = New-Object Windows.Controls.ItemsControl
$itemsControl.HorizontalAlignment = 'Stretch'
$itemsControl.VerticalAlignment = 'Stretch'
# Set the ItemsPanel to a VirtualizingStackPanel
$itemsPanelTemplate = New-Object Windows.Controls.ItemsPanelTemplate
$factory = New-Object Windows.FrameworkElementFactory ([Windows.Controls.VirtualizingStackPanel])
$itemsPanelTemplate.VisualTree = $factory
$itemsControl.ItemsPanel = $itemsPanelTemplate
# Set virtualization properties
$itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::IsVirtualizingProperty, $true)
$itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::VirtualizationModeProperty, [Windows.Controls.VirtualizationMode]::Recycling)
# Add the ItemsControl directly to the DockPanel
[Windows.Controls.DockPanel]::SetDock($itemsControl, [Windows.Controls.Dock]::Bottom)
$dockPanelContainer.Children.Add($itemsControl) | Out-Null
# Create a StackPanel inside the Border
$stackPanel = New-Object Windows.Controls.StackPanel
$stackPanel.Background = [Windows.Media.Brushes]::Transparent
$stackPanel.SnapsToDevicePixels = $true
$stackPanel.VerticalAlignment = "Stretch"
$border.Child = $stackPanel
$panelcount++
# Now proceed with adding category labels and entries to $itemsControl
# Add Windows Version label if this is the updates panel
if ($targetGridName -eq "updatespanel") {
$windowsVersion = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ProductName
$versionLabel = New-Object Windows.Controls.Label
$versionLabel.Content = "Windows Version: $windowsVersion"
$versionLabel.FontSize = $theme.FontSize
$versionLabel.HorizontalAlignment = "Left"
$stackPanel.Children.Add($versionLabel) | Out-Null
}
foreach ($category in ($organizedData[$panelKey].Keys | Sort-Object)) {
$count++
if ($targetGridName -eq "appspanel" -and $columncount -gt 0) {
$panelcount2 = [Int](($count) / $maxcount - 0.5)
if ($panelcount -eq $panelcount2) {
# Create a new Border for the new column
$border = New-Object Windows.Controls.Border
$border.VerticalAlignment = "Stretch"
[System.Windows.Controls.Grid]::SetColumn($border, $panelcount)
$border.style = $borderstyle
$targetGrid.Children.Add($border) | Out-Null
# Create a new StackPanel inside the Border
$stackPanel = New-Object Windows.Controls.StackPanel
$stackPanel.Background = [Windows.Media.Brushes]::Transparent
$stackPanel.SnapsToDevicePixels = $true
$stackPanel.VerticalAlignment = "Stretch"
$border.Child = $stackPanel
$panelcount++
}
}
$label = New-Object Windows.Controls.Label
$label.Content = $category -replace ".*__", ""
$label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "HeaderFontSize")
$label.SetResourceReference([Windows.Controls.Control]::FontFamilyProperty, "HeaderFontFamily")
$itemsControl.Items.Add($label) | Out-Null
$label.FontSize = $theme.HeadingFontSize
$label.FontFamily = $theme.HeaderFontFamily
$stackPanel.Children.Add($label) | Out-Null
$sync[$category] = $label
# Sort entries by Order and then by Name
# Sort entries by Order and then by Name, but only display Name
$entries = $organizedData[$panelKey][$category] | Sort-Object Order, Name
foreach ($entryInfo in $entries) {
$count++
# Create the UI elements based on the entry type
if ($targetGridName -eq "appspanel" -and $columncount -gt 0) {
$panelcount2 = [Int](($count) / $maxcount - 0.5)
if ($panelcount -eq $panelcount2) {
# Create a new Border for the new column
$border = New-Object Windows.Controls.Border
$border.VerticalAlignment = "Stretch"
[System.Windows.Controls.Grid]::SetColumn($border, $panelcount)
$border.style = $borderstyle
$targetGrid.Children.Add($border) | Out-Null
# Create a new StackPanel inside the Border
$stackPanel = New-Object Windows.Controls.StackPanel
$stackPanel.Background = [Windows.Media.Brushes]::Transparent
$stackPanel.SnapsToDevicePixels = $true
$stackPanel.VerticalAlignment = "Stretch"
$border.Child = $stackPanel
$panelcount++
}
}
switch ($entryInfo.Type) {
"Toggle" {
$dockPanel = New-Object Windows.Controls.DockPanel
@ -167,10 +196,10 @@ function Invoke-WPFUIElements {
$label.Content = $entryInfo.Content
$label.ToolTip = $entryInfo.Description
$label.HorizontalAlignment = "Left"
$label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize")
$label.FontSize = $theme.FontSize
$label.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
$dockPanel.Children.Add($label) | Out-Null
$itemsControl.Items.Add($dockPanel) | Out-Null
$stackPanel.Children.Add($dockPanel) | Out-Null
$sync[$entryInfo.Name] = $checkBox
@ -188,29 +217,35 @@ function Invoke-WPFUIElements {
}
"ToggleButton" {
$toggleButton = New-Object Windows.Controls.Primitives.ToggleButton
$toggleButton = New-Object Windows.Controls.ToggleButton
$toggleButton.Name = $entryInfo.Name
$toggleButton.Content = $entryInfo.Content[1]
$toggleButton.ToolTip = $entryInfo.Description
$toggleButton.Name = "WPFTab" + ($stackPanel.Children.Count + 1) + "BT"
$toggleButton.HorizontalAlignment = "Left"
$toggleButton.Style = $ToggleButtonStyle
$toggleButton.Height = $theme.TabButtonHeight
$toggleButton.Width = $theme.TabButtonWidth
$toggleButton.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "ButtonInstallBackgroundColor")
$toggleButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
$toggleButton.FontWeight = [Windows.FontWeights]::Bold
$toggleButton.Tag = @{
contentOn = if ($entryInfo.Content.Count -ge 1) { $entryInfo.Content[0] } else { "" }
contentOff = if ($entryInfo.Content.Count -ge 2) { $entryInfo.Content[1] } else { $contentOn }
}
$textBlock = New-Object Windows.Controls.TextBlock
$textBlock.FontSize = $theme.TabButtonFontSize
$textBlock.Background = [Windows.Media.Brushes]::Transparent
$textBlock.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "ButtonInstallForegroundColor")
$itemsControl.Items.Add($toggleButton) | Out-Null
$underline = New-Object Windows.Documents.Underline
$underline.Inlines.Add($entryInfo.name -replace "(.).*", "`$1")
$run = New-Object Windows.Documents.Run
$run.Text = $entryInfo.name -replace "^.", ""
$textBlock.Inlines.Add($underline)
$textBlock.Inlines.Add($run)
$toggleButton.Content = $textBlock
$stackPanel.Children.Add($toggleButton) | Out-Null
$sync[$entryInfo.Name] = $toggleButton
$sync[$entryInfo.Name].Add_Checked({
$this.Content = $this.Tag.contentOn
})
$sync[$entryInfo.Name].Add_Unchecked({
$this.Content = $this.Tag.contentOff
})
}
"Combobox" {
@ -222,26 +257,26 @@ function Invoke-WPFUIElements {
$label.Content = $entryInfo.Content
$label.HorizontalAlignment = "Left"
$label.VerticalAlignment = "Center"
$label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
$label.FontSize = $theme.ButtonFontSize
$horizontalStackPanel.Children.Add($label) | Out-Null
$comboBox = New-Object Windows.Controls.ComboBox
$comboBox.Name = $entryInfo.Name
$comboBox.SetResourceReference([Windows.Controls.Control]::HeightProperty, "ButtonHeight")
$comboBox.SetResourceReference([Windows.Controls.Control]::WidthProperty, "ButtonWidth")
$comboBox.Height = $theme.ButtonHeight
$comboBox.Width = $theme.ButtonWidth
$comboBox.HorizontalAlignment = "Left"
$comboBox.VerticalAlignment = "Center"
$comboBox.SetResourceReference([Windows.Controls.Control]::MarginProperty, "ButtonMargin")
$comboBox.Margin = $theme.ButtonMargin
foreach ($comboitem in ($entryInfo.ComboItems -split " ")) {
$comboBoxItem = New-Object Windows.Controls.ComboBoxItem
$comboBoxItem.Content = $comboitem
$comboBoxItem.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
$comboBoxItem.FontSize = $theme.ButtonFontSize
$comboBox.Items.Add($comboBoxItem) | Out-Null
}
$horizontalStackPanel.Children.Add($comboBox) | Out-Null
$itemsControl.Items.Add($horizontalStackPanel) | Out-Null
$stackPanel.Children.Add($horizontalStackPanel) | Out-Null
$comboBox.SelectedIndex = 0
@ -253,50 +288,16 @@ function Invoke-WPFUIElements {
$button.Name = $entryInfo.Name
$button.Content = $entryInfo.Content
$button.HorizontalAlignment = "Left"
$button.SetResourceReference([Windows.Controls.Control]::MarginProperty, "ButtonMargin")
$button.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
$button.Margin = $theme.ButtonMargin
$button.FontSize = $theme.ButtonFontSize
if ($entryInfo.ButtonWidth) {
$button.Width = $entryInfo.ButtonWidth
}
$itemsControl.Items.Add($button) | Out-Null
$stackPanel.Children.Add($button) | Out-Null
$sync[$entryInfo.Name] = $button
}
"RadioButton" {
# Check if a container for this GroupName already exists
if (-not $radioButtonGroups.ContainsKey($entryInfo.GroupName)) {
# Create a StackPanel for this group
$groupStackPanel = New-Object Windows.Controls.StackPanel
$groupStackPanel.Orientation = "Vertical"
# Add the group container to the ItemsControl
$itemsControl.Items.Add($groupStackPanel) | Out-Null
}
else {
# Retrieve the existing group container
$groupStackPanel = $radioButtonGroups[$entryInfo.GroupName]
}
# Create the RadioButton
$radioButton = New-Object Windows.Controls.RadioButton
$radioButton.Name = $entryInfo.Name
$radioButton.GroupName = $entryInfo.GroupName
$radioButton.Content = $entryInfo.Content
$radioButton.HorizontalAlignment = "Left"
$radioButton.SetResourceReference([Windows.Controls.Control]::MarginProperty, "CheckBoxMargin")
$radioButton.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize")
$radioButton.ToolTip = $entryInfo.Description
if ($entryInfo.Checked -eq $true) {
$radioButton.IsChecked = $true
}
# Add the RadioButton to the group container
$groupStackPanel.Children.Add($radioButton) | Out-Null
$sync[$entryInfo.Name] = $radioButton
}
default {
$horizontalStackPanel = New-Object Windows.Controls.StackPanel
$horizontalStackPanel.Orientation = "Horizontal"
@ -304,9 +305,9 @@ function Invoke-WPFUIElements {
$checkBox = New-Object Windows.Controls.CheckBox
$checkBox.Name = $entryInfo.Name
$checkBox.Content = $entryInfo.Content
$checkBox.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize")
$checkBox.FontSize = $theme.FontSize
$checkBox.ToolTip = $entryInfo.Description
$checkBox.SetResourceReference([Windows.Controls.Control]::MarginProperty, "CheckBoxMargin")
$checkBox.Margin = $theme.CheckBoxMargin
if ($entryInfo.Checked -eq $true) {
$checkBox.IsChecked = $entryInfo.Checked
}
@ -324,7 +325,7 @@ function Invoke-WPFUIElements {
$sync[$textBlock.Name] = $textBlock
}
$itemsControl.Items.Add($horizontalStackPanel) | Out-Null
$stackPanel.Children.Add($horizontalStackPanel) | Out-Null
$sync[$entryInfo.Name] = $checkBox
}
}

View File

@ -1,12 +1,9 @@
function Invoke-WPFUnInstall {
param(
[Parameter(Mandatory=$false)]
[PSObject[]]$PackagesToUninstall = $($sync.selectedApps | Foreach-Object { $sync.configs.applicationsHashtable.$_ })
)
<#
.SYNOPSIS
Uninstalls the selected programs
#>
if($sync.ProcessRunning) {
@ -15,7 +12,9 @@ function Invoke-WPFUnInstall {
return
}
if ($PackagesToUninstall.Count -eq 0) {
$PackagesToInstall = (Get-WinUtilCheckBoxes)["Install"]
if ($PackagesToInstall.Count -eq 0) {
$WarningMsg = "Please select the program(s) to uninstall"
[System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
return
@ -23,26 +22,52 @@ function Invoke-WPFUnInstall {
$ButtonType = [System.Windows.MessageBoxButton]::YesNo
$MessageboxTitle = "Are you sure?"
$Messageboxbody = ("This will uninstall the following applications: `n $($PackagesToUninstall | Select-Object Name, Description| Out-String)")
$Messageboxbody = ("This will uninstall the following applications: `n $($PackagesToInstall | Format-Table | Out-String)")
$MessageIcon = [System.Windows.MessageBoxImage]::Information
$confirm = [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon)
if($confirm -eq "No") {return}
$ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked)
$ManagerPreference = $sync["ManagerPreference"]
Invoke-WPFRunspace -ArgumentList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $ChocoPreference, $DebugPreference)
if ($PackagesToInstall.count -eq 1) {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
$packagesWinget, $packagesChoco = {
$packagesWinget = [System.Collections.ArrayList]::new()
$packagesChoco = [System.Collections.ArrayList]::new()
Invoke-WPFRunspace -ArgumentList @(("PackagesToUninstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToUninstall, $ManagerPreference, $DebugPreference)
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToInstall -Preference $ManagerPreference
$packagesWinget = $packagesSorted[[PackageManagers]::Winget]
$packagesChoco = $packagesSorted[[PackageManagers]::Choco]
foreach ($package in $PackagesToInstall) {
if ($ChocoPreference) {
if ($package.choco -eq "na") {
$packagesWinget.add($package.winget)
Write-Host "Queueing $($package.winget) for Winget uninstall"
} else {
$null = $packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey uninstall"
}
}
else {
if ($package.winget -eq "na") {
$packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey uninstall"
} else {
$null = $packagesWinget.add($($package.winget))
Write-Host "Queueing $($package.winget) for Winget uninstall"
}
}
}
return $packagesWinget, $packagesChoco
}.Invoke($PackagesToInstall)
try {
$sync.ProcessRunning = $true
# Uninstall all selected programs in new window
# Install all selected programs in new window
if($packagesWinget.Count -gt 0) {
Install-WinUtilProgramWinget -Action Uninstall -Programs $packagesWinget
}

View File

@ -1,38 +0,0 @@
Function Show-CTTLogo {
<#
.SYNOPSIS
Displays the CTT logo in ASCII art.
.DESCRIPTION
This function displays the CTT logo in ASCII art format.
.PARAMETER None
No parameters are required for this function.
.EXAMPLE
Show-CTTLogo
Prints the CTT logo in ASCII art format to the console.
#>
$asciiArt = @"
CCCCCCCCCCCCCTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
CCC::::::::::::CT:::::::::::::::::::::TT:::::::::::::::::::::T
CC:::::::::::::::CT:::::::::::::::::::::TT:::::::::::::::::::::T
C:::::CCCCCCCC::::CT:::::TT:::::::TT:::::TT:::::TT:::::::TT:::::T
C:::::C CCCCCCTTTTTT T:::::T TTTTTTTTTTTT T:::::T TTTTTT
C:::::C T:::::T T:::::T
C:::::C T:::::T T:::::T
C:::::C T:::::T T:::::T
C:::::C T:::::T T:::::T
C:::::C T:::::T T:::::T
C:::::C T:::::T T:::::T
C:::::C CCCCCC T:::::T T:::::T
C:::::CCCCCCCC::::C TT:::::::TT TT:::::::TT
CC:::::::::::::::C T:::::::::T T:::::::::T
CCC::::::::::::C T:::::::::T T:::::::::T
CCCCCCCCCCCCC TTTTTTTTTTT TTTTTTTTTTT
====Chris Titus Tech=====
=====Windows Toolbox=====
"@
Write-Host $asciiArt
}

View File

@ -3,6 +3,7 @@
{% block header %}
{{ super() }}
<div style="color: red; text-align: center; padding: 10px; font-size: 20px;">
<strong>Announcement:</strong> We are currently not adding any applications to WinUtil and any apps that will be added through a PR will be declined by the maintainer.
<strong>Announcement:</strong> We are currently reworking the docs to use Hugo rather then mkdocs.
</div>
{% endblock %}

View File

@ -1,12 +1,3 @@
# Create enums
Add-Type @"
public enum PackageManagers
{
Winget,
Choco
}
"@
# SPDX-License-Identifier: MIT
# Set the maximum number of threads for the RunspacePool to the number of threads on the machine
$maxthreads = [int]$env:NUMBER_OF_PROCESSORS
@ -55,6 +46,7 @@ class GenericException : Exception {
GenericException($Message) : base($Message) {}
}
$inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window'
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
@ -116,29 +108,10 @@ $sync.Form.Add_Loaded({
Invoke-WinutilThemeChange -init $true
# Load the configuration files
$noimage = "https://images.emojiterra.com/google/noto-emoji/unicode-15/color/512px/1f4e6.png"
$noimage = [Windows.Media.Imaging.BitmapImage]::new([Uri]::new($noimage))
$sync.configs.applicationsHashtable = @{}
$sync.configs.applications.PSObject.Properties | ForEach-Object {
$sync.configs.applicationsHashtable[$_.Name] = $_.Value
}
# Now call the function with the final merged config
Invoke-WPFUIElements -configVariable $sync.configs.appnavigation -targetGridName "appscategory" -columncount 1
# Add logic to handle click to the ToggleView Button on the Install Tab
$sync.WPFToggleView.Add_Click({
$sync.CompactView = -not $sync.CompactView
Update-AppTileProperties
})
Invoke-WPFUIApps -Apps $sync.configs.applicationsHashtable -targetGridName "appspanel"
#Invoke-WPFUIElements -configVariable $sync.configs.nav -targetGridName "WPFMainGrid"
Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "appspanel" -columncount 5
Invoke-WPFUIElements -configVariable $sync.configs.tweaks -targetGridName "tweakspanel" -columncount 2
Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "featurespanel" -columncount 2
# Future implementation: Add Windows Version to updates panel
#Invoke-WPFUIElements -configVariable $sync.configs.updates -targetGridName "updatespanel" -columncount 1
@ -148,14 +121,12 @@ Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "feat
$xaml.SelectNodes("//*[@Name]") | ForEach-Object {$sync["$("$($psitem.Name)")"] = $sync["Form"].FindName($psitem.Name)}
#Persist Package Manager preference across winutil restarts
$sync.ChocoRadioButton.Add_Checked({Set-PackageManagerPreference Choco})
$sync.WingetRadioButton.Add_Checked({Set-PackageManagerPreference Winget})
Set-PackageManagerPreference
switch ($sync["ManagerPreference"]) {
"Choco" {$sync.ChocoRadioButton.IsChecked = $true; break}
"Winget" {$sync.WingetRadioButton.IsChecked = $true; break}
#Persist the Chocolatey preference across winutil restarts
$ChocoPreferencePath = "$env:LOCALAPPDATA\winutil\preferChocolatey.ini"
$sync.WPFpreferChocolatey.Add_Checked({New-Item -Path $ChocoPreferencePath -Force })
$sync.WPFpreferChocolatey.Add_Unchecked({Remove-Item $ChocoPreferencePath -Force})
if (Test-Path $ChocoPreferencePath) {
$sync.WPFpreferChocolatey.IsChecked = $true
}
$sync.keys | ForEach-Object {
@ -194,13 +165,14 @@ $sync.keys | ForEach-Object {
# Load computer information in the background
Invoke-WPFRunspace -ScriptBlock {
try {
$oldProgressPreference = $ProgressPreference
$ProgressPreference = "SilentlyContinue"
$sync.ConfigLoaded = $False
$sync.ComputerInfo = Get-ComputerInfo
$sync.ConfigLoaded = $True
}
finally{
$ProgressPreference = $oldProgressPreference
$ProgressPreference = "Continue"
}
} | Out-Null
@ -210,45 +182,7 @@ Invoke-WPFRunspace -ScriptBlock {
#===========================================================================
# Print the logo
Show-CTTLogo
$sync.CompactView = $true
$sync.Form.Resources.AppTileWidth = [double]::NaN
$sync.Form.Resources.AppTileCompactVisibility = [Windows.Visibility]::Visible
$sync.Form.Resources.AppTileFontSize = [double]16
$sync.Form.Resources.AppTileMargins = [Windows.Thickness]5
$sync.Form.Resources.AppTileBorderThickness = [Windows.Thickness]0
function Update-AppTileProperties {
if ($sync.CompactView -eq $true) {
$sync.Form.Resources.AppTileWidth = [double]::NaN
$sync.Form.Resources.AppTileCompactVisibility = [Windows.Visibility]::Collapsed
$sync.Form.Resources.AppTileFontSize = [double]12
$sync.Form.Resources.AppTileMargins = [Windows.Thickness]2
$sync.Form.Resources.AppTileBorderThickness = [Windows.Thickness]0
}
else {
# On first load, set the AppTileWidth to NaN because the Window dosnt exist yet and there is no ActuaWidth
if ($sync.ItemsControl.ActualWidth -gt 0) {
$sync.Form.Resources.AppTileWidth = $sync.ItemsControl.ActualWidth -20}
else {
$sync.Form.Resources.AppTileWidth = [double]::NaN
}
$sync.Form.Resources.AppTileCompactVisibility = [Windows.Visibility]::Visible
$sync.Form.Resources.AppTileFontSize = [double]16
$sync.Form.Resources.AppTileMargins = [Windows.Thickness]5
$sync.Form.Resources.AppTileBorderThickness = [Windows.Thickness]1
}
if ($sync.SearchBar.Text -eq "") {
Set-CategoryVisibility -Category "*"
}
}
# initialize AppTile properties
Update-AppTileProperties
# We need to update the app tile properties when the form is resized because to fill a WrapPanel update the width of the elemenmt manually (afaik)
$sync.Form.Add_SizeChanged({
Update-AppTileProperties
})
Invoke-WPFFormVariables
# Progress bar in taskbaritem > Set-WinUtilProgressbar
$sync["Form"].TaskbarItemInfo = New-Object System.Windows.Shell.TaskbarItemInfo
@ -267,42 +201,55 @@ $sync["Form"].Add_Closing({
$sync.SearchBarClearButton.Add_Click({
$sync.SearchBar.Text = ""
$sync.SearchBarClearButton.Visibility = "Collapsed"
# Focus the search bar after clearing the text
$sync.SearchBar.Focus()
$sync.SearchBar.SelectAll()
})
# add some shortcuts for people that don't like clicking
$commonKeyEvents = {
# Prevent shortcuts from executing if a process is already running
if ($sync.ProcessRunning -eq $true) {
return
}
# Handle key presses of single keys
switch ($_.Key) {
"Escape" { $sync.SearchBar.Text = "" }
if ($_.Key -eq "Escape") {
$sync.SearchBar.SelectAll()
$sync.SearchBar.Text = ""
$sync.SearchBarClearButton.Visibility = "Collapsed"
return
}
# don't ask, I know what I'm doing, just go...
if (($_.Key -eq "Q" -and $_.KeyboardDevice.Modifiers -eq "Ctrl")) {
$this.Close()
}
# Handle Alt key combinations for navigation
if ($_.KeyboardDevice.Modifiers -eq "Alt") {
$keyEventArgs = $_
switch ($_.SystemKey) {
"I" { Invoke-WPFButton "WPFTab1BT"; $keyEventArgs.Handled = $true } # Navigate to Install tab and suppress Windows Warning Sound
"T" { Invoke-WPFButton "WPFTab2BT"; $keyEventArgs.Handled = $true } # Navigate to Tweaks tab
"C" { Invoke-WPFButton "WPFTab3BT"; $keyEventArgs.Handled = $true } # Navigate to Config tab
"U" { Invoke-WPFButton "WPFTab4BT"; $keyEventArgs.Handled = $true } # Navigate to Updates tab
"M" { Invoke-WPFButton "WPFTab5BT"; $keyEventArgs.Handled = $true } # Navigate to MicroWin tab
if ($_.SystemKey -eq "I") {
Invoke-WPFButton "WPFTab1BT"
}
if ($_.SystemKey -eq "T") {
Invoke-WPFButton "WPFTab2BT"
}
if ($_.SystemKey -eq "C") {
Invoke-WPFButton "WPFTab3BT"
}
if ($_.SystemKey -eq "U") {
Invoke-WPFButton "WPFTab4BT"
}
if ($_.SystemKey -eq "M") {
Invoke-WPFButton "WPFTab5BT"
}
if ($_.SystemKey -eq "P") {
Write-Host "Your Windows Product Key: $((Get-WmiObject -query 'select * from SoftwareLicensingService').OA3xOriginalProductKey)"
}
}
# Handle Ctrl key combinations for specific actions
if ($_.KeyboardDevice.Modifiers -eq "Ctrl") {
switch ($_.Key) {
"F" { $sync.SearchBar.Focus() } # Focus on the search bar
"Q" { $this.Close() } # Close the application
# shortcut for the filter box
if ($_.Key -eq "F" -and $_.KeyboardDevice.Modifiers -eq "Ctrl") {
if ($sync.SearchBar.Text -eq "Ctrl-F to filter") {
$sync.SearchBar.SelectAll()
$sync.SearchBar.Text = ""
}
$sync.SearchBar.Focus()
}
}
$sync["Form"].Add_PreViewKeyDown($commonKeyEvents)
$sync["Form"].Add_MouseLeftButtonDown({
@ -311,8 +258,8 @@ $sync["Form"].Add_MouseLeftButtonDown({
})
$sync["Form"].Add_MouseDoubleClick({
if ($_.OriginalSource.Name -eq "NavDockPanel" -or
$_.OriginalSource.Name -eq "GridBesideNavDockPanel") {
if ($_.OriginalSource -is [System.Windows.Controls.Grid] -or
$_.OriginalSource -is [System.Windows.Controls.StackPanel]) {
if ($sync["Form"].WindowState -eq [Windows.WindowState]::Normal) {
$sync["Form"].WindowState = [Windows.WindowState]::Maximized
}
@ -328,6 +275,55 @@ $sync["Form"].Add_Deactivated({
})
$sync["Form"].Add_ContentRendered({
try {
[void][Window]
} catch {
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class Window {
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
[DllImport("user32.dll")]
public static extern int GetSystemMetrics(int nIndex);
};
public struct RECT {
public int Left; // x position of upper-left corner
public int Top; // y position of upper-left corner
public int Right; // x position of lower-right corner
public int Bottom; // y position of lower-right corner
}
"@
}
foreach ($proc in (Get-Process).where{ $_.MainWindowTitle -and $_.MainWindowTitle -like "*titus*" }) {
# Check if the process's MainWindowHandle is valid
if ($proc.MainWindowHandle -ne [System.IntPtr]::Zero) {
Write-Debug "MainWindowHandle: $($proc.Id) $($proc.MainWindowTitle) $($proc.MainWindowHandle)"
$windowHandle = $proc.MainWindowHandle
} else {
Write-Warning "Process found, but no MainWindowHandle: $($proc.Id) $($proc.MainWindowTitle)"
}
}
$rect = New-Object RECT
[Window]::GetWindowRect($windowHandle, [ref]$rect)
$width = $rect.Right - $rect.Left
$height = $rect.Bottom - $rect.Top
Write-Debug "UpperLeft:$($rect.Left),$($rect.Top) LowerBottom:$($rect.Right),$($rect.Bottom). Width:$($width) Height:$($height)"
# Load the Windows Forms assembly
Add-Type -AssemblyName System.Windows.Forms
$primaryScreen = [System.Windows.Forms.Screen]::PrimaryScreen
@ -342,12 +338,9 @@ $sync["Form"].Add_ContentRendered({
Write-Debug "Primary Monitor Height: $screenHeight pixels"
# Compare with the primary monitor size
if ($sync.Form.ActualWidth -gt $screenWidth -or $sync.Form.ActualHeight -gt $screenHeight) {
if ($width -gt $screenWidth -or $height -gt $screenHeight) {
Write-Debug "The specified width and/or height is greater than the primary monitor size."
$sync.Form.Left = 0
$sync.Form.Top = 0
$sync.Form.Width = $screenWidth
$sync.Form.Height = $screenHeight
[void][Window]::MoveWindow($windowHandle, 0, 0, $screenWidth, $screenHeight, $True)
} else {
Write-Debug "The specified width and height are within the primary monitor size limits."
}
@ -421,25 +414,73 @@ if ($sync["ISOLanguage"].Items.Count -eq 1) {
}
$sync["ISOLanguage"].SelectedIndex = 0
# Load Checkboxes and Labels outside of the Filter function only once on startup for performance reasons
$filter = Get-WinUtilVariables -Type CheckBox
$CheckBoxes = ($sync.GetEnumerator()).where{ $psitem.Key -in $filter }
$filter = Get-WinUtilVariables -Type Label
$labels = @{}
($sync.GetEnumerator()).where{$PSItem.Key -in $filter} | ForEach-Object {$labels[$_.Key] = $_.Value}
$allCategories = $checkBoxes.Name | ForEach-Object {$sync.configs.applications.$_} | Select-Object -Unique -ExpandProperty category
$sync["SearchBar"].Add_TextChanged({
if ($sync.SearchBar.Text -ne "") {
$sync.SearchBarClearButton.Visibility = "Visible"
} else {
$sync.SearchBarClearButton.Visibility = "Collapsed"
}
switch ($sync.currentTab) {
"Install" {
Find-AppsByNameOrDescription -SearchString $sync.SearchBar.Text
$activeApplications = @()
$textToSearch = $sync.SearchBar.Text.ToLower()
foreach ($CheckBox in $CheckBoxes) {
# Skip if the checkbox is null, it doesn't have content or it is the prefer Choco checkbox
if ($CheckBox -eq $null -or $CheckBox.Value -eq $null -or $CheckBox.Value.Content -eq $null -or $CheckBox.Name -eq "WPFpreferChocolatey") {
continue
}
"Tweaks" {
Find-TweaksByNameOrDescription -SearchString $sync.SearchBar.Text
$checkBoxName = $CheckBox.Key
$textBlockName = $checkBoxName + "Link"
# Retrieve the corresponding text block based on the generated name
$textBlock = $sync[$textBlockName]
if ($CheckBox.Value.Content.ToString().ToLower().Contains($textToSearch)) {
$CheckBox.Value.Visibility = "Visible"
$activeApplications += $sync.configs.applications.$checkboxName
# Set the corresponding text block visibility
if ($textBlock -ne $null -and $textBlock -is [System.Windows.Controls.TextBlock]) {
$textBlock.Visibility = "Visible"
}
} else {
$CheckBox.Value.Visibility = "Collapsed"
# Set the corresponding text block visibility
if ($textBlock -ne $null -and $textBlock -is [System.Windows.Controls.TextBlock]) {
$textBlock.Visibility = "Collapsed"
}
}
}
$activeCategories = $activeApplications | Select-Object -ExpandProperty category -Unique
foreach ($category in $activeCategories) {
$sync[$category].Visibility = "Visible"
}
if ($activeCategories) {
$inactiveCategories = Compare-Object -ReferenceObject $allCategories -DifferenceObject $activeCategories -PassThru
} else {
$inactiveCategories = $allCategories
}
foreach ($category in $inactiveCategories) {
$sync[$category].Visibility = "Collapsed"
}
})
$sync["Form"].Add_Loaded({
param($e)
$sync.Form.MinWidth = "1000"
$sync["Form"].MaxWidth = [Double]::PositiveInfinity
$sync["Form"].MaxHeight = [Double]::PositiveInfinity
})
@ -473,36 +514,44 @@ $sync["Form"].Add_Activated({
$sync["ThemeButton"].Add_Click({
Write-Debug "ThemeButton clicked"
Invoke-WPFPopup -PopupActionTable @{ "Settings" = "Hide"; "Theme" = "Toggle" }
$_.Handled = $false
})
$sync["AutoThemeMenuItem"].Add_Click({
Write-Debug "About clicked"
Invoke-WPFPopup -Action "Hide" -Popups @("Theme")
Invoke-WinutilThemeChange -theme "Auto"
$_.Handled = $false
})
$sync["DarkThemeMenuItem"].Add_Click({
Write-Debug "Dark Theme clicked"
Invoke-WPFPopup -Action "Hide" -Popups @("Theme")
Invoke-WinutilThemeChange -theme "Dark"
$_.Handled = $false
})
$sync["LightThemeMenuItem"].Add_Click({
Write-Debug "Light Theme clicked"
Invoke-WPFPopup -Action "Hide" -Popups @("Theme")
Invoke-WinutilThemeChange -theme "Light"
$_.Handled = $false
})
$sync["SettingsButton"].Add_Click({
Write-Debug "SettingsButton clicked"
Invoke-WPFPopup -PopupActionTable @{ "Settings" = "Toggle"; "Theme" = "Hide" }
$_.Handled = $false
})
$sync["ImportMenuItem"].Add_Click({
Write-Debug "Import clicked"
Invoke-WPFPopup -Action "Hide" -Popups @("Settings")
Invoke-WPFImpex -type "import"
$_.Handled = $false
})
$sync["ExportMenuItem"].Add_Click({
Write-Debug "Export clicked"
Invoke-WPFPopup -Action "Hide" -Popups @("Settings")
Invoke-WPFImpex -type "export"
$_.Handled = $false
})
$sync["AboutMenuItem"].Add_Click({
Write-Debug "About clicked"

View File

@ -37,16 +37,7 @@ $sync = [Hashtable]::Synchronized(@{})
$sync.PSScriptRoot = $PSScriptRoot
$sync.version = "#{replaceme}"
$sync.configs = @{}
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
$sync.ProcessRunning = $false
$sync.selectedApps = [System.Collections.Generic.List[string]]::new()
$sync.ShowOnlySeleced = $false
$sync.currentTab = "Install"
$sync.CompactView = $true
$sync.ShowOnlySelected = $false
$sync.selectedAppsStackPanel
$sync.selectedAppsPopup
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Output "Winutil needs to be run as Administrator. Attempting to relaunch."
@ -55,27 +46,21 @@ if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]:
$PSBoundParameters.GetEnumerator() | ForEach-Object {
$argList += if ($_.Value -is [switch] -and $_.Value) {
"-$($_.Key)"
} elseif ($_.Value -is [array]) {
"-$($_.Key) $($_.Value -join ',')"
} elseif ($_.Value) {
"-$($_.Key) '$($_.Value)'"
"-$($_.Key) `"$($_.Value)`""
}
}
$script = if ($PSCommandPath) {
"& { & `'$($PSCommandPath)`' $($argList -join ' ') }"
$script = if ($MyInvocation.MyCommand.Path) {
"& { & '$($MyInvocation.MyCommand.Path)' $argList }"
} else {
"&([ScriptBlock]::Create((irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1))) $($argList -join ' ')"
"iex '& { $(irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1) } $argList'"
}
$powershellCmd = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" }
$processCmd = if (Get-Command wt.exe -ErrorAction SilentlyContinue) { "wt.exe" } else { "$powershellCmd" }
$powershellcmd = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" }
$processCmd = if (Get-Command wt.exe -ErrorAction SilentlyContinue) { "wt.exe" } else { $powershellcmd }
if ($processCmd -eq "wt.exe") {
Start-Process $processCmd -ArgumentList "$powershellCmd -ExecutionPolicy Bypass -NoProfile -Command `"$script`"" -Verb RunAs
} else {
Start-Process $processCmd -ArgumentList "-ExecutionPolicy Bypass -NoProfile -Command `"$script`"" -Verb RunAs
}
Start-Process $processCmd -ArgumentList "$powershellcmd -ExecutionPolicy Bypass -NoProfile -Command $script" -Verb RunAs
break
}

View File

@ -3,9 +3,15 @@ function Invoke-Preprocessing {
.SYNOPSIS
A function that does Code Formatting using RegEx, useful when trying to force specific coding standard(s) to a project.
.PARAMETER ThrowExceptionOnEmptyFilesList
A switch which'll throw an exception upon not finding any files inside the provided 'WorkingDir'.
.PARAMETER SkipExcludedFilesValidation
A switch to stop file path validation on 'ExcludedFiles' list.
.PARAMETER ExcludedFiles
A list of file paths which're *relative to* 'WorkingDir' Folder, every item in the list can be pointing to File (doesn't end with '\') or Directory (ends with '\') or None-Existing File/Directory.
By default, it checks if everyitem exists, and throws an exception if one or more are not found (None-Existing).
By default, it checks if everyitem exists, and throws an exception if one or more are not found (None-Existing), if you want to skip this validation, please consider providing the '-SkipExcludedFilesValidation' switch to skip this check.
.PARAMETER WorkingDir
The folder to search inside recursively for files which're going to be Preprocessed (Code Formatted), unless they're found in 'ExcludedFiles' List.
@ -30,23 +36,35 @@ function Invoke-Preprocessing {
Same as Example No. 1, but uses 'ProgressActivity' which's used in Progress Bar.
.EXAMPLE
Invoke-Preprocessing -ThrowExceptionOnEmptyFilesList -WorkingDir "DRIVE:\Path\To\Folder\" -ExcludedFiles @('file.txt', '.\.git\', '*.png') -ProgressStatusMessage "Doing Preprocessing"
Same as Example No. 1, but uses '-ThrowExceptionOnEmptyFilesList', which's an optional parameter that'll make 'Invoke-Preprocessing' throw an exception when no files are found in 'WorkingDir' (not including the ExcludedFiles, of course), useful when you want to double check your parameters & you're sure there's files to process in the 'WorkingDir'.
.EXAMPLE
Invoke-Preprocessing -Skip -WorkingDir "DRIVE:\Path\To\Folder\" -ExcludedFiles @('file.txt', '.\.git\', '*.png') -ProgressStatusMessage "Doing Preprocessing"
Same as Example No. 1, but uses '-SkipExcludedFilesValidation', which'll skip the validation step for 'ExcludedFiles' list. This can be useful when 'ExcludedFiles' list is generated from another function, or from unreliable source (you can't guarantee every item in list is a valid path), but you want to silently continue through the function.
#>
param (
[Parameter(Mandatory, position=1)]
[Parameter(position=0)]
[switch]$SkipExcludedFilesValidation,
[Parameter(position=1)]
[switch]$ThrowExceptionOnEmptyFilesList,
[Parameter(Mandatory, position=2)]
[ValidateScript({[System.IO.Path]::IsPathRooted($_)})]
[string]$WorkingDir,
[Parameter(position=2)]
[Parameter(position=3)]
[string[]]$ExcludedFiles,
[Parameter(Mandatory, position=3)]
[Parameter(Mandatory, position=4)]
[string]$ProgressStatusMessage,
[Parameter(position=4)]
[Parameter(position=5)]
[string]$ProgressActivity = "Preprocessing"
)
@ -59,7 +77,8 @@ function Invoke-Preprocessing {
$InternalExcludedFiles.Add($excludedFile) | Out-Null
}
# Validate the ExcludedItems List before continuing on
# Validate the ExcludedItems List before continuing on,
# that's if there's a list in the first place, and '-SkipInternalExcludedFilesValidation' was not provided.
if ($ExcludedFiles.Count -gt 0) {
ForEach ($excludedFile in $ExcludedFiles) {
$filePath = "$(($WorkingDir -replace ('\\$', '')) + '\' + ($excludedFile -replace ('\.\\', '')))"
@ -71,8 +90,8 @@ function Invoke-Preprocessing {
} else { $failedFilesList += "'$filePath', " }
}
$failedFilesList = $failedFilesList -replace (',\s*$', '')
if ((-not $failedFilesList -eq "")) {
Write-Warning "[Invoke-Preprocessing] One or more File Paths and/or File Patterns were not found: $failedFilesList"
if ((-not $failedFilesList -eq "") -and (-not $SkipExcludedFilesValidation)) {
throw "[Invoke-Preprocessing] One or more File Paths and/or File Patterns were not found, you can use '-SkipExcludedFilesValidation' switch to skip this check, the failed to validate are: $failedFilesList"
}
}
@ -92,45 +111,14 @@ function Invoke-Preprocessing {
if ($index -ge 0) { $files.RemoveAt($index) }
}
# Define a path to store the file hashes
$hashFilePath = Join-Path -Path $WorkingDir -ChildPath ".preprocessor_hashes.json"
# Load existing hashes if the file exists
$existingHashes = @{}
if (Test-Path -Path $hashFilePath) {
# intentionally dosn't use ConvertFrom-Json -AsHashtable as it isn't supported on old powershell versions
$file_content = Get-Content -Path $hashFilePath | ConvertFrom-Json
foreach ($property in $file_content.PSObject.Properties) {
$existingHashes[$property.Name] = $property.Value
}
}
$newHashes = @{}
$changedFiles = @()
$hashingAlgorithm = "MD5"
foreach ($file in $files){
# Calculate the hash of the file
$hash = Get-FileHash -Path $file -Algorithm $hashingAlgorithm | Select-Object -ExpandProperty Hash
$newHashes[$file] = $hash
# Check if the hash already exists in the existing hashes
if (($existingHashes.ContainsKey($file) -and $existingHashes[$file] -eq $hash)) {
# Skip processing this file as it hasn't changed
continue;
}
else {
# If the hash doesn't exist or has changed, add it to the changed files list
$changedFiles += $file
}
}
$files = $changedFiles
$numOfFiles = $files.Count
Write-Debug "[Invoke-Preprocessing] Files Changed: $numOfFiles"
if ($numOfFiles -eq 0){
Write-Debug "[Invoke-Preprocessing] Found 0 Files to Preprocess inside 'WorkingDir' Directory : '$WorkingDir'."
return
if ($numOfFiles -eq 0) {
if ($ThrowExceptionOnEmptyFilesList) {
throw "[Invoke-Preprocessing] Found 0 Files to Preprocess inside 'WorkingDir' Directory and '-ThrowExceptionOnEmptyFilesList' Switch is provided, value of 'WorkingDir': '$WorkingDir'."
} else {
return # Do an early return, there's nothing else to do
}
}
for ($i = 0; $i -lt $numOfFiles; $i++) {
@ -151,13 +139,9 @@ function Invoke-Preprocessing {
-replace ('\}\s*Catch\s*(?<exceptions>\[.*?\])\s*\{', '} catch ${exceptions} {') `
-replace ('(?<parameter_type>\[[^$0-9]+\])\s*(?<str_after_type>\$.*?)', '${parameter_type}${str_after_type}') `
| Set-Content "$fullFileName"
$newHashes[$fullFileName] = Get-FileHash -Path $fullFileName -Algorithm $hashingAlgorithm | Select-Object -ExpandProperty Hash
Write-Progress -Activity $ProgressActivity -Status "$ProgressStatusMessage - Finished $i out of $numOfFiles" -PercentComplete (($i/$numOfFiles)*100)
}
Write-Progress -Activity $ProgressActivity -Status "$ProgressStatusMessage - Finished Task Successfully" -Completed
# Save the new hashes to the file
$newHashes | ConvertTo-Json -Depth 10 | Set-Content -Path $hashFilePath
}

View File

@ -67,82 +67,6 @@
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="AppTileBorderStyle" TargetType="Border">
<Setter Property="BorderBrush" Value="Gray"/>
<Setter Property="BorderThickness" Value="{DynamicResource AppTileBorderThickness}"/>
<Setter Property="CornerRadius" Value="5"/>
<Setter Property="Padding" Value="{DynamicResource AppTileMargins}"/>
<Setter Property="Width" Value="{DynamicResource AppTileWidth}"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="Margin" Value="{DynamicResource AppTileMargins}"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Background" Value="{DynamicResource AppInstallUnselectedColor}"/>
</Style>
<Style x:Key="AppTileCheckboxStyle" TargetType="CheckBox">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="{DynamicResource AppTileMargins}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<ContentPresenter Content="{TemplateBinding Content}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="{TemplateBinding Padding}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="AppTileImageStyle" TargetType="Image">
<Setter Property="Width" Value="{DynamicResource AppTileImageSize}"/>
<Setter Property="Height" Value="{DynamicResource AppTileImageSize}"/>
<Setter Property="Margin">
<Setter.Value>
<Thickness Left="0" Top="0" Right="10" Bottom="0"/>
</Setter.Value>
</Setter>
<Setter Property="Clip">
<Setter.Value>
<RectangleGeometry Rect="0,0,40,40" RadiusX="5" RadiusY="5"/>
</Setter.Value>
</Setter>
<Setter Property="Visibility" Value="{DynamicResource AppTileCompactVisibility}"/>
</Style>
<Style x:Key="AppTileNameStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="{DynamicResource AppTileFontSize}"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="{DynamicResource MainForegroundColor}"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="{DynamicResource AppTileMargins}"/>
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style x:Key="AppTileButtonPanelStyle" TargetType="StackPanel">
<Setter Property="Orientation" Value="Horizontal"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="{DynamicResource AppTileMargins}"/>
<Setter Property="Visibility" Value="{DynamicResource AppTileCompactVisibility}"/>
</Style>
<Style x:Key="AppTileButtonStyle" TargetType="Button">
<Setter Property="Width" Value="45"/>
<Setter Property="Height" Value="35"/>
<Setter Property="Margin" Value="0,0,10,0"/>
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundColor}"/>
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundColor}"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" FontFamily="Segoe MDL2 Assets" FontSize="20"
Foreground="{DynamicResource MainForegroundColor}"
Background="Transparent" HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Button" x:Key="HoverButtonStyle">
<Setter Property="Foreground" Value="{DynamicResource MainForegroundColor}" />
@ -273,45 +197,6 @@
<Setter Property="Background" Value="{DynamicResource LabelBackgroundColor}"/>
<Setter Property="FontFamily" Value="{DynamicResource FontFamily}"/>
</Style>
<!-- Category Toggle Button Style for the Apps Window-->
<Style x:Key="CategoryToggleButtonStyle" TargetType="ToggleButton">
<Setter Property="Foreground" Value="{DynamicResource LabelboxForegroundColor}"/>
<Setter Property="Background" Value="{DynamicResource MainBackgroundColor}"/>
<Setter Property="FontFamily" Value="{DynamicResource HeaderFontFamily}"/>
<Setter Property="FontSize" Value="{DynamicResource HeaderFontSize}"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Padding" Value="10,2,10,2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Background="{TemplateBinding Background}"
BorderBrush="{DynamicResource BorderColor}"
BorderThickness="0"
CornerRadius="{DynamicResource ButtonCornerRadius}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}">
<TextBlock x:Name="PrefixTextBlock"/>
<ContentPresenter Content="{TemplateBinding Content}" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="PrefixTextBlock" Property="Text" Value="[-] "/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="PrefixTextBlock" Property="Text" Value="[+] "/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundMouseoverColor}"/>
</Trigger>
</Style.Triggers>
</Style>
<!-- TextBlock template -->
<Style TargetType="TextBlock">
@ -413,103 +298,6 @@
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ToggleButtonStyle" TargetType="ToggleButton">
<Setter Property="Margin" Value="{DynamicResource ButtonMargin}"/>
<Setter Property="Foreground" Value="{DynamicResource ButtonForegroundColor}"/>
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundColor}"/>
<Setter Property="Height" Value="{DynamicResource ButtonHeight}"/>
<Setter Property="Width" Value="{DynamicResource ButtonWidth}"/>
<Setter Property="FontSize" Value="{DynamicResource ButtonFontSize}"/>
<Setter Property="FontFamily" Value="{DynamicResource FontFamily}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<Border x:Name="BackgroundBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{DynamicResource ButtonBorderThickness}"
CornerRadius="{DynamicResource ButtonCornerRadius}">
<Grid>
<!-- Toggle Dot Background -->
<Ellipse Width="8" Height="16"
Fill="{DynamicResource ToggleButtonOnColor}"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="0,3,5,0" />
<!-- Toggle Dot with hover grow effect -->
<Ellipse x:Name="ToggleDot"
Width="8" Height="8"
Fill="{DynamicResource ButtonForegroundColor}"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="0,3,5,0"
RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<ScaleTransform ScaleX="1" ScaleY="1"/>
</Ellipse.RenderTransform>
</Ellipse>
<!-- Content Presenter -->
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="10,2,10,2"/>
</Grid>
</Border>
</Grid>
<!-- Triggers for ToggleButton states -->
<ControlTemplate.Triggers>
<!-- Hover effect -->
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="BackgroundBorder" Property="Background" Value="{DynamicResource ButtonBackgroundMouseoverColor}"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<!-- Animation to grow the dot when hovered -->
<DoubleAnimation Storyboard.TargetName="ToggleDot"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
To="1.2" Duration="0:0:0.1"/>
<DoubleAnimation Storyboard.TargetName="ToggleDot"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
To="1.2" Duration="0:0:0.1"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<!-- Animation to shrink the dot back to original size when not hovered -->
<DoubleAnimation Storyboard.TargetName="ToggleDot"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
To="1.0" Duration="0:0:0.1"/>
<DoubleAnimation Storyboard.TargetName="ToggleDot"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
To="1.0" Duration="0:0:0.1"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<!-- IsChecked state -->
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="ToggleDot" Property="VerticalAlignment" Value="Bottom"/>
<Setter TargetName="ToggleDot" Property="Margin" Value="0,0,5,3"/>
</Trigger>
<!-- IsEnabled state -->
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="BackgroundBorder" Property="Background" Value="{DynamicResource ButtonBackgroundSelectedColor}"/>
<Setter Property="Foreground" Value="DimGray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SearchBarClearButtonStyle" TargetType="Button">
<Setter Property="FontFamily" Value="{DynamicResource FontFamily}"/>
<Setter Property="FontSize" Value="{DynamicResource SearchBarClearButtonFontSize}"/>
@ -914,7 +702,7 @@
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<DockPanel Name="NavDockPanel" HorizontalAlignment="Stretch" Background="{DynamicResource MainBackgroundColor}" SnapsToDevicePixels="True" Grid.Row="0" Width="Auto">
<DockPanel HorizontalAlignment="Stretch" Background="{DynamicResource MainBackgroundColor}" SnapsToDevicePixels="True" Grid.Row="0" Width="Auto">
<StackPanel Name="NavLogoPanel" Orientation="Horizontal" HorizontalAlignment="Left" Background="{DynamicResource MainBackgroundColor}" SnapsToDevicePixels="True" Margin="10,0,20,0">
</StackPanel>
<ToggleButton Margin="0,0,5,0" HorizontalAlignment="Left" Height="{DynamicResource TabButtonHeight}" Width="{DynamicResource TabButtonWidth}"
@ -957,7 +745,7 @@
</TextBlock>
</ToggleButton.Content>
</ToggleButton>
<Grid Name="GridBesideNavDockPanel" Background="{DynamicResource MainBackgroundColor}" ShowGridLines="False" Width="Auto" Height="Auto" HorizontalAlignment="Stretch">
<Grid Background="{DynamicResource MainBackgroundColor}" ShowGridLines="False" Width="Auto" Height="Auto" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <!-- Main content area -->
<ColumnDefinition Width="Auto"/><!-- Space for options button -->
@ -1076,6 +864,7 @@
</Border>
</Popup>
<Button Name="SettingsButton"
Style="{StaticResource HoverButtonStyle}"
Grid.Column="3" BorderBrush="Transparent"
@ -1128,18 +917,29 @@
<TabItem Header="Install" Visibility="Collapsed" Name="WPFTab1">
<Grid Background="Transparent" >
<Grid Grid.Row="0" Grid.Column="0" Margin="{DynamicResource TabContentMargin}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="225" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="45px"/>
<RowDefinition Height="0.95*"/>
</Grid.RowDefinitions>
<StackPanel Background="{DynamicResource MainBackgroundColor}" Orientation="Horizontal" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="0" Grid.ColumnSpan="3" Margin="{DynamicResource TabContentMargin}">
<Button Name="WPFInstall" Content=" Install/Upgrade Selected" Margin="2" />
<Button Name="WPFInstallUpgrade" Content=" Upgrade All" Margin="2"/>
<Button Name="WPFUninstall" Content=" Uninstall Selected" Margin="2"/>
<Button Name="WPFGetInstalled" Content=" Get Installed" Margin="2"/>
<Button Name="WPFClearInstallSelection" Content=" Clear Selection" Margin="2"/>
<CheckBox Name="WPFpreferChocolatey" VerticalAlignment="Center" VerticalContentAlignment="Center">
<TextBlock Text="Prefer Chocolatey" ToolTip="Prefers Chocolatey as Download Engine instead of Winget" VerticalAlignment="Center" />
</CheckBox>
</StackPanel>
<Grid Name="appscategory" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ScrollViewer x:Name="scrollViewer" Grid.Row="1" Grid.Column="0" Margin="{DynamicResource TabContentMargin}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
BorderBrush="Transparent" BorderThickness="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid Name="appspanel" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</Grid>
</ScrollViewer>
<Rectangle Grid.Row="1" Grid.Column="0" Width="22" Height="22" Fill="{DynamicResource MainBackgroundColor}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Style="{StaticResource ScrollVisibilityRectangle}"/>
<Grid Name="appspanel" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</Grid>
</Grid>
</Grid>
</TabItem>
<TabItem Header="Tweaks" Visibility="Collapsed" Name="WPFTab2">
@ -1466,13 +1266,7 @@
- Once complete, the target ISO file will be in the directory you have specified <LineBreak/>
- Copy this image to your Ventoy USB Stick, boot to this image, gg
<LineBreak/>
If you are injecting drivers ensure you put all your inf, sys, and dll files for each driver into a separate directory <LineBreak/><LineBreak/>
<Bold>Installing VirtIO drivers</Bold><LineBreak/>
If you plan on using your ISO on QEMU/Proxmox VE, you can bundle VirtIO drivers with your ISO to automatically install drivers. Simply tick the "Include VirtIO drivers" checkbox before starting the process. Then, follow these instructions:<LineBreak/><LineBreak/>
<TextBlock TextWrapping="WrapWithOverflow" Margin="15,0,0,0" Text="1. Proceed with Setup until you reach the disk selection screen, in which you won't see any drives" Foreground="{DynamicResource ComboBoxForegroundColor}"/><LineBreak/>
<TextBlock TextWrapping="WrapWithOverflow" Margin="15,0,0,0" Text="2. Click &quot;Load Driver&quot; and click Browse" Foreground="{DynamicResource ComboBoxForegroundColor}"/><LineBreak/>
<TextBlock TextWrapping="WrapWithOverflow" Margin="15,0,0,0" Text="3. In the folder selection dialog, point to this path: &quot;D:\VirtIO\vioscsi\w11\amd64&quot; (replace amd64 with ARM64 if you are using Windows on ARM, and &quot;D:&quot; with the drive letter of the ISO)" Foreground="{DynamicResource ComboBoxForegroundColor}"/><LineBreak/>
<TextBlock TextWrapping="WrapWithOverflow" Margin="15,0,0,0" Text="4. Select all drivers that will appear in the list box and click OK" Foreground="{DynamicResource ComboBoxForegroundColor}"/><LineBreak/>
If you are injecting drivers ensure you put all your inf, sys, and dll files for each driver into a separate directory
</TextBlock>
<TextBlock Margin="15,0,15,15"
Padding = "1"
@ -1483,7 +1277,7 @@
Foreground = "{DynamicResource ComboBoxForegroundColor}"
xml:space = "preserve"
>
<Bold>Driver structure example:</Bold>
<Bold>Example:</Bold>
C:\drivers\
|-- Driver1\
| |-- Driver1.inf