Compare commits

..
1 Commits
Author SHA1 Message Date
ChrisTitusTechandgithub-actions[bot] 9a553f4497 Update sponsors in README 2026-07-07 16:15:35 +00:00
120 changed files with 793 additions and 2989 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
name: Auto-merge Automated Update PRs name: Auto-merge Docs PRs
on: on:
pull_request: pull_request:
@@ -8,7 +8,7 @@ on:
jobs: jobs:
auto-merge: auto-merge:
if: (github.event.pull_request.head.ref == 'docs-update' || github.event.pull_request.head.ref == 'sponsors-update') && (github.event.pull_request.user.login == 'ChrisTitusTech' || github.event.pull_request.user.login == 'github-actions[bot]') if: github.event.pull_request.head.ref == 'docs-update' && (github.event.pull_request.user.login == 'ChrisTitusTech' || github.event.pull_request.user.login == 'github-actions[bot]')
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
pull-requests: write pull-requests: write
@@ -0,0 +1,77 @@
name: Issue slash commands
on:
issue_comment:
types: [created, edited]
jobs:
issueCommands:
# Skip this job if the comment was created/edited on a PR
if: ${{ !github.event.issue.pull_request }}
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: none
contents: read
steps:
- name: Process slash command
uses: actions/github-script@v9
with:
script: |
const allowedUsers = ["ChrisTitusTech", "og-mrk", "Marterich", "MyDrift-user", "Real-MullaC", "CodingWonders", "GabiNun2", "FluffyPunk"];
const commenter = context.payload.comment.user.login;
// Authorization check first — before any parsing of comment content
if (!allowedUsers.includes(commenter)) {
console.log(`User ${commenter} is not in the allowlist. Skipping.`);
return;
}
// Read comment body as data, never interpolated into shell
const body = context.payload.comment.body;
const issueNumber = context.issue.number;
const owner = context.repo.owner;
const repo = context.repo.repo;
// /label 'name' or /label name
const labelMatch = body.match(/\/label\s+'([^']+)'|\/label\s+(\S+?)(?:\s|$)/);
if (labelMatch) {
const labelName = (labelMatch[1] || labelMatch[2]).trim();
console.log(`Adding label: ${labelName}`);
await github.rest.issues.addLabels({
owner, repo, issue_number: issueNumber,
labels: [labelName],
});
}
// /unlabel 'name' or /unlabel name
const unlabelMatch = body.match(/\/unlabel\s+'([^']+)'|\/unlabel\s+(\S+?)(?:\s|$)/);
if (unlabelMatch) {
const labelName = (unlabelMatch[1] || unlabelMatch[2]).trim();
console.log(`Removing label: ${labelName}`);
await github.rest.issues.removeLabel({
owner, repo, issue_number: issueNumber,
name: labelName,
});
}
// /close (optionally with 'not planned')
if (body.includes('/close')) {
const stateReason = body.includes('not planned') ? 'not_planned' : 'completed';
console.log(`Closing issue (reason: ${stateReason})`);
await github.rest.issues.update({
owner, repo, issue_number: issueNumber,
state: 'closed',
state_reason: stateReason,
});
}
// /open or /reopen
if (body.includes('/open') || body.includes('/reopen')) {
console.log('Reopening issue');
await github.rest.issues.update({
owner, repo, issue_number: issueNumber,
state: 'open',
});
}
+1 -16
View File
@@ -109,21 +109,6 @@ jobs:
config-name: release-drafter.yml config-name: release-drafter.yml
version: ${{ env.VERSION }} version: ${{ env.VERSION }}
- name: Remove Automated Updates from Release Notes
id: filter_notes
shell: pwsh
env:
RELEASE_NOTES: ${{ steps.generate_notes.outputs.body }}
run: |
$filteredNotes = ($env:RELEASE_NOTES -split '\r?\n' | Where-Object {
$_ -notmatch '(?i)Update (Generated Dev Docs|Sponsors)'
}) -join "`n"
$delimiter = [guid]::NewGuid().ToString()
"body<<$delimiter" >> $env:GITHUB_OUTPUT
$filteredNotes >> $env:GITHUB_OUTPUT
$delimiter >> $env:GITHUB_OUTPUT
- name: Create and Upload Release - name: Create and Upload Release
id: create_release id: create_release
uses: softprops/action-gh-release@v3 uses: softprops/action-gh-release@v3
@@ -131,7 +116,7 @@ jobs:
tag_name: ${{ env.VERSION }} tag_name: ${{ env.VERSION }}
name: Pre-Release ${{ env.VERSION }} name: Pre-Release ${{ env.VERSION }}
body: | body: |
${{ steps.filter_notes.outputs.body }} ${{ steps.generate_notes.outputs.body }}
![GitHub Downloads (specific asset, specific tag)](https://img.shields.io/github/downloads/ChrisTitusTech/winutil/${{ env.VERSION }}/winutil.ps1) ![GitHub Downloads (specific asset, specific tag)](https://img.shields.io/github/downloads/ChrisTitusTech/winutil/${{ env.VERSION }}/winutil.ps1)
append_body: false append_body: false
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
id: cpr id: cpr
uses: peter-evans/create-pull-request@v8 uses: peter-evans/create-pull-request@v8
with: with:
token: ${{ secrets.AUTO_MERGE }} token: ${{ secrets.GITHUB_TOKEN }}
commit-message: 'Update sponsors in README' commit-message: 'Update sponsors in README'
title: 'chore: Update Sponsors README' title: 'chore: Update Sponsors README'
body: 'Automated update of sponsors section' body: 'Automated update of sponsors section'
+3 -12
View File
@@ -530,15 +530,6 @@
"winget": "TechPowerUp.GPU-Z", "winget": "TechPowerUp.GPU-Z",
"foss": false "foss": false
}, },
"gsudo": {
"category": "Pro Tools",
"choco": "gsudo",
"content": "gsudo",
"description": "gsudo is a sudo equivalent for Windows. It allows you to run commands with elevated administrative privileges directly within the current console window.",
"link": "https://github.com/gerardog/gsudo",
"winget": "gerardog.gsudo",
"foss": true
},
"helium": { "helium": {
"category": "Browsers", "category": "Browsers",
"choco": "helium", "choco": "helium",
@@ -1207,7 +1198,7 @@
"processmonitor": { "processmonitor": {
"category": "Microsoft Tools", "category": "Microsoft Tools",
"choco": "procexp", "choco": "procexp",
"content": "Process Monitor", "content": "SysInternals Process Monitor",
"description": "SysInternals Process Monitor is an advanced monitoring tool that shows real-time file system, registry, and process/thread activity.", "description": "SysInternals Process Monitor is an advanced monitoring tool that shows real-time file system, registry, and process/thread activity.",
"link": "https://docs.microsoft.com/en-us/sysinternals/downloads/procmon", "link": "https://docs.microsoft.com/en-us/sysinternals/downloads/procmon",
"winget": "Microsoft.Sysinternals.ProcessMonitor", "winget": "Microsoft.Sysinternals.ProcessMonitor",
@@ -1396,7 +1387,7 @@
"tcpview": { "tcpview": {
"category": "Microsoft Tools", "category": "Microsoft Tools",
"choco": "tcpview", "choco": "tcpview",
"content": "TCPView", "content": "SysInternals TCPView",
"description": "SysInternals TCPView is a network monitoring tool that displays a detailed list of all TCP and UDP endpoints on your system.", "description": "SysInternals TCPView is a network monitoring tool that displays a detailed list of all TCP and UDP endpoints on your system.",
"link": "https://docs.microsoft.com/en-us/sysinternals/downloads/tcpview", "link": "https://docs.microsoft.com/en-us/sysinternals/downloads/tcpview",
"winget": "Microsoft.Sysinternals.TCPView", "winget": "Microsoft.Sysinternals.TCPView",
@@ -1513,7 +1504,7 @@
"ungoogled": { "ungoogled": {
"category": "Browsers", "category": "Browsers",
"choco": "ungoogled-chromium", "choco": "ungoogled-chromium",
"content": "Ungoogled Chromium", "content": "Ungoogled",
"description": "Ungoogled Chromium is a version of Chromium without Google's integration for enhanced privacy and control.", "description": "Ungoogled Chromium is a version of Chromium without Google's integration for enhanced privacy and control.",
"link": "https://github.com/Eloston/ungoogled-chromium", "link": "https://github.com/Eloston/ungoogled-chromium",
"winget": "eloston.ungoogled-chromium", "winget": "eloston.ungoogled-chromium",
+30 -60
View File
@@ -4,232 +4,203 @@
"Content": "Feedback Hub", "Content": "Feedback Hub",
"Description": "Allows users to submit bug reports, feature suggestions, and diagnostic data directly to Microsoft.", "Description": "Allows users to submit bug reports, feature suggestions, and diagnostic data directly to Microsoft.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.WindowsFeedbackHub", "PackageId": "Microsoft.WindowsFeedbackHub"
"StoreId": "9NBLGGH4R32N"
}, },
"WPFAppxMicrosoft_GetHelp": { "WPFAppxMicrosoft_GetHelp": {
"Category": "Microsoft Apps", "Category": "Microsoft Apps",
"Content": "Get Help", "Content": "Get Help",
"Description": "Provides access to automated troubleshooting guides, support documentation, and direct Microsoft customer assistance.", "Description": "Provides access to automated troubleshooting guides, support documentation, and direct Microsoft customer assistance.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.GetHelp", "PackageId": "Microsoft.GetHelp"
"StoreId": "9PKDZBMV1H3T"
}, },
"WPFAppxMicrosoft_OutlookForWindows": { "WPFAppxMicrosoft_OutlookForWindows": {
"Category": "Microsoft Apps", "Category": "Microsoft Apps",
"Content": "Outlook for Windows", "Content": "Outlook for Windows",
"Description": "Provides modern email management, calendar scheduling, and contact organization features.", "Description": "Provides modern email management, calendar scheduling, and contact organization features.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.OutlookForWindows", "PackageId": "Microsoft.OutlookForWindows"
"StoreId": "9NRX63209R7B"
}, },
"WPFAppxMSTeams": { "WPFAppxMSTeams": {
"Category": "Microsoft Apps", "Category": "Microsoft Apps",
"Content": "Microsoft Teams", "Content": "Microsoft Teams",
"Description": "Facilitates instant messaging, video conferencing, file sharing, and workspace collaboration.", "Description": "Facilitates instant messaging, video conferencing, file sharing, and workspace collaboration.",
"Panel": "0", "Panel": "0",
"PackageId": "MSTeams", "PackageId": "MSTeams"
"StoreId": "XP8BT8DW290MPQ"
}, },
"WPFAppxClipchamp_Clipchamp": { "WPFAppxClipchamp_Clipchamp": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "Clipchamp", "Content": "Clipchamp",
"Description": "Provides a user-friendly video editor with built-in templates, effects, and timeline editing tools.", "Description": "Provides a user-friendly video editor with built-in templates, effects, and timeline editing tools.",
"Panel": "0", "Panel": "0",
"PackageId": "Clipchamp.Clipchamp", "PackageId": "Clipchamp.Clipchamp"
"StoreId": "9P1J8S7CCWWT"
}, },
"WPFAppxMicrosoft_MicrosoftOfficeHub": { "WPFAppxMicrosoft_MicrosoftOfficeHub": {
"Category": "Microsoft Apps", "Category": "Microsoft Apps",
"Content": "Microsoft 365", "Content": "Microsoft 365",
"Description": "Serves as a centralized launcher and dashboard for accessing cloud-based Microsoft 365 apps and recent documents.", "Description": "Serves as a centralized launcher and dashboard for accessing cloud-based Microsoft 365 apps and recent documents.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.MicrosoftOfficeHub", "PackageId": "Microsoft.MicrosoftOfficeHub"
"StoreId": "9WZDNCRD29V9"
}, },
"WPFAppxMicrosoft_ZuneMusic": { "WPFAppxMicrosoft_ZuneMusic": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "Media Player", "Content": "Media Player",
"Description": "Plays local audio and video files with modern playlist management and casting capabilities.", "Description": "Plays local audio and video files with modern playlist management and casting capabilities.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.ZuneMusic", "PackageId": "Microsoft.ZuneMusic"
"StoreId": "9WZDNCRFJ3PT"
}, },
"WPFAppxMicrosoft_BingSearch": { "WPFAppxMicrosoft_BingSearch": {
"Category": "Bing & Web Services", "Category": "Bing & Web Services",
"Content": "Bing Search", "Content": "Bing Search",
"Description": "Integrates Microsoft Bing search capabilities and web services directly into the operating system.", "Description": "Integrates Microsoft Bing search capabilities and web services directly into the operating system.",
"Panel": "1", "Panel": "1",
"PackageId": "Microsoft.BingSearch", "PackageId": "Microsoft.BingSearch"
"StoreId": "9NZBF4GT040C"
}, },
"WPFAppxMicrosoftCorporationII_QuickAssist": { "WPFAppxMicrosoftCorporationII_QuickAssist": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "Quick Assist", "Content": "Quick Assist",
"Description": "Enables secure remote technical support and screen sharing over an internet connection.", "Description": "Enables secure remote technical support and screen sharing over an internet connection.",
"Panel": "0", "Panel": "0",
"PackageId": "MicrosoftCorporationII.QuickAssist", "PackageId": "MicrosoftCorporationII.QuickAssist"
"StoreId": "9P7BP5VNWKX5"
}, },
"WPFAppxMicrosoft_WindowsDevHome": { "WPFAppxMicrosoft_WindowsDevHome": {
"Category": "Developer Tools", "Category": "Developer Tools",
"Content": "Dev Home", "Content": "Dev Home",
"Description": "Provides a specialized dashboard for software developer environment setups, repository syncing, and hardware widgets.", "Description": "Provides a specialized dashboard for software developer environment setups, repository syncing, and hardware widgets.",
"Panel": "1", "Panel": "1",
"PackageId": "Microsoft.Windows.DevHome", "PackageId": "Microsoft.Windows.DevHome"
"StoreId": "9N8MHTPHNGVV"
}, },
"WPFAppxMicrosoft_WindowsCrossDevice": { "WPFAppxMicrosoft_WindowsCrossDevice": {
"Category": "Microsoft Ecosystem", "Category": "Microsoft Ecosystem",
"Content": "Mobile Devices", "Content": "Mobile Devices",
"Description": "Manages system-level background connectivity with paired mobile devices. Removing this may disable cross-device features such as phone screen mirroring, file transfer, and mobile hotspot handoff integrated into Windows Settings.", "Description": "Manages system-level background connectivity with paired mobile devices. Removing this may disable cross-device features such as phone screen mirroring, file transfer, and mobile hotspot handoff integrated into Windows Settings.",
"Panel": "0", "Panel": "0",
"PackageId": "MicrosoftWindows.CrossDevice", "PackageId": "MicrosoftWindows.CrossDevice"
"StoreId": "9NTXGKQ8P7N0"
}, },
"WPFAppxMicrosoft_Todos": { "WPFAppxMicrosoft_Todos": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "To Do", "Content": "To Do",
"Description": "Creates, tracks, and synchronizes personal tasks, smart lists, and daily reminders.", "Description": "Creates, tracks, and synchronizes personal tasks, smart lists, and daily reminders.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.Todos", "PackageId": "Microsoft.Todos"
"StoreId": "9NBLGGH5R558"
}, },
"WPFAppxMicrosoft_PowerAutomateDesktop": { "WPFAppxMicrosoft_PowerAutomateDesktop": {
"Category": "Developer Tools", "Category": "Developer Tools",
"Content": "Power Automate", "Content": "Power Automate",
"Description": "Automates repetitive workflows and desktop tasks using low-code visual scripting.", "Description": "Automates repetitive workflows and desktop tasks using low-code visual scripting.",
"Panel": "1", "Panel": "1",
"PackageId": "Microsoft.PowerAutomateDesktop", "PackageId": "Microsoft.PowerAutomateDesktop"
"StoreId": "9NFTCH6J7FHV"
}, },
"WPFAppxMicrosoft_YourPhone": { "WPFAppxMicrosoft_YourPhone": {
"Category": "Microsoft Ecosystem", "Category": "Microsoft Ecosystem",
"Content": "Phone Link", "Content": "Phone Link",
"Description": "Synchronizes text messages, phone notifications, photos, and calls from a mobile device to the desktop.", "Description": "Synchronizes text messages, phone notifications, photos, and calls from a mobile device to the desktop.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.YourPhone", "PackageId": "Microsoft.YourPhone"
"StoreId": "9NMPJ99VJBWV"
}, },
"WPFAppxMicrosoft_MicrosoftStickyNotes": { "WPFAppxMicrosoft_MicrosoftStickyNotes": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "Sticky Notes", "Content": "Sticky Notes",
"Description": "Creates quick, floating text notes on the desktop that automatically sync across devices.", "Description": "Creates quick, floating text notes on the desktop that automatically sync across devices.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.MicrosoftStickyNotes", "PackageId": "Microsoft.MicrosoftStickyNotes"
"StoreId": "9NBLGGH4QGHW"
}, },
"WPFAppxMicrosoft_WindowsSoundRecorder": { "WPFAppxMicrosoft_WindowsSoundRecorder": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "Sound Recorder", "Content": "Sound Recorder",
"Description": "Records and trims live audio inputs with simple microphone adjustment controls.", "Description": "Records and trims live audio inputs with simple microphone adjustment controls.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.WindowsSoundRecorder", "PackageId": "Microsoft.WindowsSoundRecorder"
"StoreId": "9WZDNCRFHWKN"
}, },
"WPFAppxMicrosoft_WindowsAlarms": { "WPFAppxMicrosoft_WindowsAlarms": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "Clock", "Content": "Clock",
"Description": "Features world clocks, alarms, countdown timers, stopwatches, and dedicated focus session tracking.", "Description": "Features world clocks, alarms, countdown timers, stopwatches, and dedicated focus session tracking.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.WindowsAlarms", "PackageId": "Microsoft.WindowsAlarms"
"StoreId": "9WZDNCRFJ3PR"
}, },
"WPFAppxMicrosoft_Paint": { "WPFAppxMicrosoft_Paint": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "Paint", "Content": "Paint",
"Description": "Provides built-in digital sketching, basic image editing, and pixel-level graphic manipulation tools.", "Description": "Provides built-in digital sketching, basic image editing, and pixel-level graphic manipulation tools.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.Paint", "PackageId": "Microsoft.Paint"
"StoreId": "9PCFS5B6T72H"
}, },
"WPFAppxMicrosoft_WindowsNotepad": { "WPFAppxMicrosoft_WindowsNotepad": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "Notepad", "Content": "Notepad",
"Description": "Provides a lightweight text editor with multi-tab support for plain text files and code snippets.", "Description": "Provides a lightweight text editor with multi-tab support for plain text files and code snippets.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.WindowsNotepad", "PackageId": "Microsoft.WindowsNotepad"
"StoreId": "9MSMLRH6LZF3"
}, },
"WPFAppxMicrosoft_ScreenSketch": { "WPFAppxMicrosoft_ScreenSketch": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "Snipping Tool", "Content": "Snipping Tool",
"Description": "Captures screenshots or screen recordings with built-in markup, image cropping, and optical character recognition (OCR).", "Description": "Captures screenshots or screen recordings with built-in markup, image cropping, and optical character recognition (OCR).",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.ScreenSketch", "PackageId": "Microsoft.ScreenSketch"
"StoreId": "9MZ95KL8MR0L"
}, },
"WPFAppxMicrosoft_Copilot": { "WPFAppxMicrosoft_Copilot": {
"Category": "Bing & Web Services", "Category": "Bing & Web Services",
"Content": "Copilot", "Content": "Copilot",
"Description": "Launches the Microsoft AI companion for contextual answers, creative writing assistance, and intelligent web search.", "Description": "Launches the Microsoft AI companion for contextual answers, creative writing assistance, and intelligent web search.",
"Panel": "1", "Panel": "1",
"PackageId": "Microsoft.Copilot", "PackageId": "Microsoft.Copilot"
"StoreId": "9NHT9RB2F4HD"
}, },
"WPFAppxMicrosoft_WindowsCalculator": { "WPFAppxMicrosoft_WindowsCalculator": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "Calculator", "Content": "Calculator",
"Description": "Performs standard arithmetic, scientific operations, programming calculations, and unit conversions.", "Description": "Performs standard arithmetic, scientific operations, programming calculations, and unit conversions.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.WindowsCalculator", "PackageId": "Microsoft.WindowsCalculator"
"StoreId": "9WZDNCRFHVN5"
}, },
"WPFAppxMicrosoft_WindowsCamera": { "WPFAppxMicrosoft_WindowsCamera": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "Camera", "Content": "Camera",
"Description": "Captures photographs and records video files via connected webcams or imaging hardware.", "Description": "Captures photographs and records video files via connected webcams or imaging hardware.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.WindowsCamera", "PackageId": "Microsoft.WindowsCamera"
"StoreId": "9WZDNCRFJBBG"
}, },
"WPFAppxMicrosoft_WindowsPhotos": { "WPFAppxMicrosoft_WindowsPhotos": {
"Category": "Utilities & Productivity", "Category": "Utilities & Productivity",
"Content": "Photos", "Content": "Photos",
"Description": "Organizes, views, and crops local images with basic color adjustment and album creation tools.", "Description": "Organizes, views, and crops local images with basic color adjustment and album creation tools.",
"Panel": "0", "Panel": "0",
"PackageId": "Microsoft.Windows.Photos", "PackageId": "Microsoft.Windows.Photos"
"StoreId": "9WZDNCRFJBH4"
}, },
"WPFAppxMicrosoft_BingNews": { "WPFAppxMicrosoft_BingNews": {
"Category": "Bing & Web Services", "Category": "Bing & Web Services",
"Content": "News", "Content": "News",
"Description": "Aggregates breaking news headlines, personalized article feeds, and world current events.", "Description": "Aggregates breaking news headlines, personalized article feeds, and world current events.",
"Panel": "1", "Panel": "1",
"PackageId": "Microsoft.BingNews", "PackageId": "Microsoft.BingNews"
"StoreId": "9WZDNCRFHVFW"
}, },
"WPFAppxMicrosoft_BingWeather": { "WPFAppxMicrosoft_BingWeather": {
"Category": "Bing & Web Services", "Category": "Bing & Web Services",
"Content": "Weather", "Content": "Weather",
"Description": "Displays local real-time weather tracking, radar maps, and historical meteorological forecasts.", "Description": "Displays local real-time weather tracking, radar maps, and historical meteorological forecasts.",
"Panel": "1", "Panel": "1",
"PackageId": "Microsoft.BingWeather", "PackageId": "Microsoft.BingWeather"
"StoreId": "9WZDNCRFJ3Q2"
}, },
"WPFAppxMicrosoft_GamingApp": { "WPFAppxMicrosoft_GamingApp": {
"Category": "Xbox & Gaming", "Category": "Xbox & Gaming",
"Content": "Xbox App", "Content": "Xbox App",
"Description": "Serves as the primary gaming library manager, social community interface, and PC Game Pass dashboard.", "Description": "Serves as the primary gaming library manager, social community interface, and PC Game Pass dashboard.",
"Panel": "1", "Panel": "1",
"PackageId": "Microsoft.GamingApp", "PackageId": "Microsoft.GamingApp"
"StoreId": "9MV0B5HZVK9Z"
}, },
"WPFAppxMicrosoft_XboxGamingOverlay": { "WPFAppxMicrosoft_XboxGamingOverlay": {
"Category": "Xbox & Gaming", "Category": "Xbox & Gaming",
"Content": "Xbox Game Bar", "Content": "Xbox Game Bar",
"Description": "Provides customizable in-game status widgets, audio balancing sliders, system monitoring tools, and gameplay recording.", "Description": "Provides customizable in-game status widgets, audio balancing sliders, system monitoring tools, and gameplay recording.",
"Panel": "1", "Panel": "1",
"PackageId": "Microsoft.XboxGamingOverlay", "PackageId": "Microsoft.XboxGamingOverlay"
"StoreId": "9NZKPSTSNW4P"
}, },
"WPFAppxMicrosoft_XboxIdentityProvider": { "WPFAppxMicrosoft_XboxIdentityProvider": {
"Category": "Xbox & Gaming", "Category": "Xbox & Gaming",
"Content": "Xbox Identity Provider", "Content": "Xbox Identity Provider",
"Description": "Manages Xbox network user authentication and background account validation for connected titles. Warning: removing this may break Microsoft account sign-in for non-Xbox games and apps that rely on this authentication pipeline.", "Description": "Manages Xbox network user authentication and background account validation for connected titles. Warning: removing this may break Microsoft account sign-in for non-Xbox games and apps that rely on this authentication pipeline.",
"Panel": "1", "Panel": "1",
"PackageId": "Microsoft.XboxIdentityProvider", "PackageId": "Microsoft.XboxIdentityProvider"
"StoreId": "9WZDNCRD1HKW"
}, },
"WPFAppxMicrosoft_XboxSpeechToTextOverlay": { "WPFAppxMicrosoft_XboxSpeechToTextOverlay": {
"Category": "Xbox & Gaming", "Category": "Xbox & Gaming",
@@ -250,8 +221,7 @@
"Content": "Start Experiences App", "Content": "Start Experiences App",
"Description": "Powers the Windows Widgets board, delivering a personalized feed of news, weather, sports, and finance content.", "Description": "Powers the Windows Widgets board, delivering a personalized feed of news, weather, sports, and finance content.",
"Panel": "1", "Panel": "1",
"PackageId": "Microsoft.StartExperiencesApp", "PackageId": "Microsoft.StartExperiencesApp"
"StoreId": "9PC1H9VN18CM"
}, },
"WPFAppxMicrosoft_MicrosoftSolitaireCollection": { "WPFAppxMicrosoft_MicrosoftSolitaireCollection": {
"Category": "Xbox & Gaming", "Category": "Xbox & Gaming",
+8 -52
View File
@@ -179,17 +179,6 @@
"function": "Invoke-WPFFixesWinget", "function": "Invoke-WPFFixesWinget",
"link": "https://winutil.christitus.com/dev/features/fixes/winget" "link": "https://winutil.christitus.com/dev/features/fixes/winget"
}, },
"WPFPanelComputer": {
"Content": "Computer Management",
"category": "Legacy Windows Panels",
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"InvokeScript": [
"compmgmt.msc"
],
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/computer"
},
"WPFPanelControl": { "WPFPanelControl": {
"Content": "Control Panel", "Content": "Control Panel",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@@ -201,16 +190,16 @@
], ],
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/control" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/control"
}, },
"WPFPanelMouse": { "WPFPanelComputer": {
"Content": "Mouse Properties", "Content": "Computer Management",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
"panel": "2", "panel": "2",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"InvokeScript": [ "InvokeScript": [
"main.cpl" "compmgmt.msc"
], ],
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/mouse" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/computer"
}, },
"WPFPanelNetwork": { "WPFPanelNetwork": {
"Content": "Network Connections", "Content": "Network Connections",
@@ -245,17 +234,6 @@
], ],
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/printer" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/printer"
}, },
"WPFPanelPrograms": {
"Content": "Programs and Features",
"category": "Legacy Windows Panels",
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"InvokeScript": [
"appwiz.cpl"
],
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/programs"
},
"WPFPanelRegion": { "WPFPanelRegion": {
"Content": "Region", "Content": "Region",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@@ -267,16 +245,16 @@
], ],
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/region" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/region"
}, },
"WPFPanelSecurity": { "WPFPanelRestore": {
"Content": "Security and Maintenance", "Content": "Windows Restore",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
"panel": "2", "panel": "2",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"InvokeScript": [ "InvokeScript": [
"wscui.cpl" "rstrui.exe"
], ],
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/security" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/restore"
}, },
"WPFPanelSound": { "WPFPanelSound": {
"Content": "Sound Settings", "Content": "Sound Settings",
@@ -311,28 +289,6 @@
], ],
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/timedate" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/timedate"
}, },
"WPFPanelFirewall": {
"Content": "Windows Defender Firewall",
"category": "Legacy Windows Panels",
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"InvokeScript": [
"firewall.cpl"
],
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/firewall"
},
"WPFPanelRestore": {
"Content": "Windows Restore",
"category": "Legacy Windows Panels",
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"InvokeScript": [
"rstrui.exe"
],
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/restore"
},
"WPFWinUtilInstallPSProfile": { "WPFWinUtilInstallPSProfile": {
"Content": "CTT PowerShell Profile - Install", "Content": "CTT PowerShell Profile - Install",
"category": "Powershell Profile Powershell 7+ Only", "category": "Powershell Profile Powershell 7+ Only",
+10 -7
View File
@@ -1,10 +1,9 @@
{ {
"shared": { "shared": {
"AppEntryWidth": "220", "AppEntryWidth": "200",
"AppEntryFontSize": "13.2", "AppEntryFontSize": "11",
"AppEntryIconSize": "28", "AppEntryMargin": "1,0,1,0",
"AppEntryMargin": "3", "AppEntryBorderThickness": "0",
"AppEntryBorderThickness": "1",
"CustomDialogFontSize": "12", "CustomDialogFontSize": "12",
"CustomDialogFontSizeHeader": "14", "CustomDialogFontSizeHeader": "14",
"CustomDialogLogoSize": "25", "CustomDialogLogoSize": "25",
@@ -25,7 +24,7 @@
"IconFontSize": "14", "IconFontSize": "14",
"IconButtonSize": "35", "IconButtonSize": "35",
"SettingsIconFontSize": "18", "SettingsIconFontSize": "18",
"CloseIconFontSize": "12", "CloseIconFontSize": "18",
"GroupBorderBackgroundColor": "#232629", "GroupBorderBackgroundColor": "#232629",
"ButtonFontSize": "12", "ButtonFontSize": "12",
"ButtonFontFamily": "Arial", "ButtonFontFamily": "Arial",
@@ -46,6 +45,7 @@
"AppInstallUnselectedColor": "#F7F7F7", "AppInstallUnselectedColor": "#F7F7F7",
"AppInstallHighlightedColor": "#CFCFCF", "AppInstallHighlightedColor": "#CFCFCF",
"AppInstallSelectedColor": "#C2C2C2", "AppInstallSelectedColor": "#C2C2C2",
"AppInstallOverlayBackgroundColor": "#6A6D72",
"ComboBoxForegroundColor": "#232629", "ComboBoxForegroundColor": "#232629",
"ComboBoxBackgroundColor": "#F7F7F7", "ComboBoxBackgroundColor": "#F7F7F7",
"LabelboxForegroundColor": "#232629", "LabelboxForegroundColor": "#232629",
@@ -59,6 +59,7 @@
"ScrollBarDraggingColor": "#6A6D72", "ScrollBarDraggingColor": "#6A6D72",
"ProgressBarForegroundColor": "#2E77FF", "ProgressBarForegroundColor": "#2E77FF",
"ProgressBarBackgroundColor": "Transparent", "ProgressBarBackgroundColor": "Transparent",
"ProgressBarTextColor": "#232629",
"ButtonInstallBackgroundColor": "#F7F7F7", "ButtonInstallBackgroundColor": "#F7F7F7",
"ButtonTweaksBackgroundColor": "#F7F7F7", "ButtonTweaksBackgroundColor": "#F7F7F7",
"ButtonConfigBackgroundColor": "#F7F7F7", "ButtonConfigBackgroundColor": "#F7F7F7",
@@ -86,6 +87,7 @@
"AppInstallUnselectedColor": "#232629", "AppInstallUnselectedColor": "#232629",
"AppInstallHighlightedColor": "#3C3C3C", "AppInstallHighlightedColor": "#3C3C3C",
"AppInstallSelectedColor": "#4C4C4C", "AppInstallSelectedColor": "#4C4C4C",
"AppInstallOverlayBackgroundColor": "#2E3135",
"ComboBoxForegroundColor": "#F7F7F7", "ComboBoxForegroundColor": "#F7F7F7",
"ComboBoxBackgroundColor": "#1E3747", "ComboBoxBackgroundColor": "#1E3747",
"LabelboxForegroundColor": "#5BDCFF", "LabelboxForegroundColor": "#5BDCFF",
@@ -97,8 +99,9 @@
"ScrollBarBackgroundColor": "#2E3135", "ScrollBarBackgroundColor": "#2E3135",
"ScrollBarHoverColor": "#3B4252", "ScrollBarHoverColor": "#3B4252",
"ScrollBarDraggingColor": "#5E81AC", "ScrollBarDraggingColor": "#5E81AC",
"ProgressBarForegroundColor": "#6EFF72", "ProgressBarForegroundColor": "#222222",
"ProgressBarBackgroundColor": "Transparent", "ProgressBarBackgroundColor": "Transparent",
"ProgressBarTextColor": "#232629",
"ButtonInstallBackgroundColor": "#222222", "ButtonInstallBackgroundColor": "#222222",
"ButtonTweaksBackgroundColor": "#333333", "ButtonTweaksBackgroundColor": "#333333",
"ButtonConfigBackgroundColor": "#444444", "ButtonConfigBackgroundColor": "#444444",
+1 -17
View File
@@ -429,7 +429,7 @@
}, },
"WPFTweaksConsumerFeatures": { "WPFTweaksConsumerFeatures": {
"Content": "ConsumerFeatures - Disable", "Content": "ConsumerFeatures - Disable",
"Description": "Stops promoted app installs and reduces app suggestions from Microsoft Store content.", "Description": "Windows will not automatically install any games, third-party apps, or application links from the Windows Store for the signed-in user. Some default Apps will be inaccessible (e.g. Phone Link).",
"category": "Essential Tweaks", "category": "Essential Tweaks",
"panel": "1", "panel": "1",
"registry": [ "registry": [
@@ -944,22 +944,6 @@
], ],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/wpbt" "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/wpbt"
}, },
"WPFTweaksPreventDeviceMetadataFromNetwork": {
"Content": "Prevent Device Companion Apps",
"Description": "Prevents additional software from being installed when plugging in devices (e.g. Ads when plugging in a monitor). Poses potential security risk.",
"category": "Essential Tweaks",
"panel": "1",
"registry": [
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Device Metadata",
"Name": "PreventDeviceMetadataFromNetwork",
"Value": "1",
"Type": "DWord",
"OriginalValue": "<RemoveEntry>"
}
],
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/preventdevicemetadatafromnetwork"
},
"WPFTweaksRazerBlock": { "WPFTweaksRazerBlock": {
"Content": "Razer Software Auto-Install - Disable", "Content": "Razer Software Auto-Install - Disable",
"Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.", "Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.",
+1 -1
View File
@@ -5,7 +5,7 @@ toc: false
--- ---
> [!NOTE] > [!NOTE]
> This section contains code-only references. For end-user documentation, see the [User Guide](../userguide/). > This section contains technical documentation for developers. For end-user documentation, see the [User Guide](../userguide/).
## Architecture ## Architecture
@@ -3,7 +3,7 @@ title: "Computer Management"
description: "" description: ""
--- ---
```json {filename="config/feature.json",linenos=inline,linenostart=182} ```json {filename="config/feature.json",linenos=inline,linenostart=193}
"WPFPanelComputer": { "WPFPanelComputer": {
"Content": "Computer Management", "Content": "Computer Management",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@@ -3,7 +3,7 @@ title: "Control Panel"
description: "" description: ""
--- ---
```json {filename="config/feature.json",linenos=inline,linenostart=193} ```json {filename="config/feature.json",linenos=inline,linenostart=182}
"WPFPanelControl": { "WPFPanelControl": {
"Content": "Control Panel", "Content": "Control Panel",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@@ -1,16 +0,0 @@
---
title: "Windows Defender Firewall"
description: ""
---
```json {filename="config/feature.json",linenos=inline,linenostart=314}
"WPFPanelFirewall": {
"Content": "Windows Defender Firewall",
"category": "Legacy Windows Panels",
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"InvokeScript": [
"firewall.cpl"
],
```
@@ -1,16 +0,0 @@
---
title: "Mouse Properties"
description: ""
---
```json {filename="config/feature.json",linenos=inline,linenostart=204}
"WPFPanelMouse": {
"Content": "Mouse Properties",
"category": "Legacy Windows Panels",
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"InvokeScript": [
"main.cpl"
],
```
@@ -3,7 +3,7 @@ title: "Network Connections"
description: "" description: ""
--- ---
```json {filename="config/feature.json",linenos=inline,linenostart=215} ```json {filename="config/feature.json",linenos=inline,linenostart=204}
"WPFPanelNetwork": { "WPFPanelNetwork": {
"Content": "Network Connections", "Content": "Network Connections",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@@ -3,7 +3,7 @@ title: "Power Panel"
description: "" description: ""
--- ---
```json {filename="config/feature.json",linenos=inline,linenostart=226} ```json {filename="config/feature.json",linenos=inline,linenostart=215}
"WPFPanelPower": { "WPFPanelPower": {
"Content": "Power Panel", "Content": "Power Panel",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@@ -3,7 +3,7 @@ title: "Printer Panel"
description: "" description: ""
--- ---
```json {filename="config/feature.json",linenos=inline,linenostart=237} ```json {filename="config/feature.json",linenos=inline,linenostart=226}
"WPFPanelPrinter": { "WPFPanelPrinter": {
"Content": "Printer Panel", "Content": "Printer Panel",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@@ -1,16 +0,0 @@
---
title: "Programs and Features"
description: ""
---
```json {filename="config/feature.json",linenos=inline,linenostart=248}
"WPFPanelPrograms": {
"Content": "Programs and Features",
"category": "Legacy Windows Panels",
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"InvokeScript": [
"appwiz.cpl"
],
```
@@ -3,7 +3,7 @@ title: "Region"
description: "" description: ""
--- ---
```json {filename="config/feature.json",linenos=inline,linenostart=259} ```json {filename="config/feature.json",linenos=inline,linenostart=237}
"WPFPanelRegion": { "WPFPanelRegion": {
"Content": "Region", "Content": "Region",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@@ -3,7 +3,7 @@ title: "Windows Restore"
description: "" description: ""
--- ---
```json {filename="config/feature.json",linenos=inline,linenostart=325} ```json {filename="config/feature.json",linenos=inline,linenostart=248}
"WPFPanelRestore": { "WPFPanelRestore": {
"Content": "Windows Restore", "Content": "Windows Restore",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@@ -1,16 +0,0 @@
---
title: "Security and Maintenance"
description: ""
---
```json {filename="config/feature.json",linenos=inline,linenostart=270}
"WPFPanelSecurity": {
"Content": "Security and Maintenance",
"category": "Legacy Windows Panels",
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"InvokeScript": [
"wscui.cpl"
],
```
@@ -3,7 +3,7 @@ title: "Sound Settings"
description: "" description: ""
--- ---
```json {filename="config/feature.json",linenos=inline,linenostart=281} ```json {filename="config/feature.json",linenos=inline,linenostart=259}
"WPFPanelSound": { "WPFPanelSound": {
"Content": "Sound Settings", "Content": "Sound Settings",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@@ -3,7 +3,7 @@ title: "System Properties"
description: "" description: ""
--- ---
```json {filename="config/feature.json",linenos=inline,linenostart=292} ```json {filename="config/feature.json",linenos=inline,linenostart=270}
"WPFPanelSystem": { "WPFPanelSystem": {
"Content": "System Properties", "Content": "System Properties",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@@ -3,7 +3,7 @@ title: "Time and Date"
description: "" description: ""
--- ---
```json {filename="config/feature.json",linenos=inline,linenostart=303} ```json {filename="config/feature.json",linenos=inline,linenostart=281}
"WPFPanelTimedate": { "WPFPanelTimedate": {
"Content": "Time and Date", "Content": "Time and Date",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@@ -3,7 +3,7 @@ title: "System Tray Battery Percentage"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1268} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1252}
"WPFToggleBatteryPercentage": { "WPFToggleBatteryPercentage": {
"Content": "System Tray Battery Percentage", "Content": "System Tray Battery Percentage",
"Description": "Shows numeric battery percentage next to the battery icon in the system tray.", "Description": "Shows numeric battery percentage next to the battery icon in the system tray.",
@@ -3,7 +3,7 @@ title: "Start Menu Bing Search"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1621} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1605}
"WPFToggleBingSearch": { "WPFToggleBingSearch": {
"Content": "Start Menu Bing Search", "Content": "Start Menu Bing Search",
"Description": "Toggles Bing web search results in Windows Search.", "Description": "Toggles Bing web search results in Windows Search.",
@@ -3,7 +3,7 @@ title: "Dark Theme for Windows"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1286} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1270}
"WPFToggleDarkMode": { "WPFToggleDarkMode": {
"Content": "Dark Theme for Windows", "Content": "Dark Theme for Windows",
"Description": "Dark Mode for the system and applications.", "Description": "Dark Mode for the system and applications.",
@@ -3,7 +3,7 @@ title: "BSoD Verbose Mode"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1242} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1226}
"WPFToggleDetailedBSoD": { "WPFToggleDetailedBSoD": {
"Content": "BSoD Verbose Mode", "Content": "BSoD Verbose Mode",
"Description": "Gives more information when you blue screen.", "Description": "Gives more information when you blue screen.",
@@ -3,7 +3,7 @@ title: "Lock Screen - Disable"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1657} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1641}
"WPFTweaksDisableLockscreen": { "WPFTweaksDisableLockscreen": {
"Content": "Lock Screen - Disable", "Content": "Lock Screen - Disable",
"Description": "Skips the lock screen entirely and goes directly to the sign-in screen on boot and wake.", "Description": "Skips the lock screen entirely and goes directly to the sign-in screen on boot and wake.",
@@ -3,7 +3,7 @@ title: "Game Mode"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1800} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1784}
"WPFToggleGameMode": { "WPFToggleGameMode": {
"Content": "Game Mode", "Content": "Game Mode",
"Description": "Toggles Windows prioritizes gaming performance by allocating system resources to games.", "Description": "Toggles Windows prioritizes gaming performance by allocating system resources to games.",
@@ -3,7 +3,7 @@ title: "File Explorer Hidden Files"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1356} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1340}
"WPFToggleHiddenFiles": { "WPFToggleHiddenFiles": {
"Content": "File Explorer Hidden Files", "Content": "File Explorer Hidden Files",
"Description": "Reveals hidden files in Explorer.", "Description": "Reveals hidden files in Explorer.",
@@ -3,7 +3,7 @@ title: "Settings Home Page"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1603} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1587}
"WPFToggleHideSettingsHome": { "WPFToggleHideSettingsHome": {
"Content": "Settings Home Page", "Content": "Settings Home Page",
"Description": "Toggles the Home Page in the Windows Settings app.", "Description": "Toggles the Home Page in the Windows Settings app.",
@@ -3,7 +3,7 @@ title: "Logon Screen Acrylic Blur"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1639} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1623}
"WPFToggleLoginBlur": { "WPFToggleLoginBlur": {
"Content": "Logon Screen Acrylic Blur", "Content": "Logon Screen Acrylic Blur",
"Description": "Toggles the acrylic blur effect on login screen background.", "Description": "Toggles the acrylic blur effect on login screen background.",
@@ -3,7 +3,7 @@ title: "Enable Long Paths"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1826} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1810}
"WPFToggleLongPaths": { "WPFToggleLongPaths": {
"Content": "Enable Long Paths", "Content": "Enable Long Paths",
"Description": "Toggles support for file paths longer than 260 characters in Explorer.", "Description": "Toggles support for file paths longer than 260 characters in Explorer.",
@@ -3,7 +3,7 @@ title: "Mouse Acceleration"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1489} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1473}
"WPFToggleMouseAcceleration": { "WPFToggleMouseAcceleration": {
"Content": "Mouse Acceleration", "Content": "Mouse Acceleration",
"Description": "Makes it so Cursor movement is affected by the speed of your physical mouse movements.", "Description": "Makes it so Cursor movement is affected by the speed of your physical mouse movements.",
@@ -3,7 +3,7 @@ title: "Multiplane Overlay"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1463} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1447}
"WPFToggleMultiplaneOverlay": { "WPFToggleMultiplaneOverlay": {
"Content": "Multiplane Overlay", "Content": "Multiplane Overlay",
"Description": "Multiplane Overlay compose multiple image layers, which can sometimes cause issues with graphics cards.", "Description": "Multiplane Overlay compose multiple image layers, which can sometimes cause issues with graphics cards.",
@@ -3,7 +3,7 @@ title: "Microsoft Outlook New Version"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1402} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1386}
"WPFToggleNewOutlook": { "WPFToggleNewOutlook": {
"Content": "Microsoft Outlook New Version", "Content": "Microsoft Outlook New Version",
"Description": "This will ensures the classic Outlook application is used.", "Description": "This will ensures the classic Outlook application is used.",
@@ -3,7 +3,7 @@ title: "Num Lock on Startup"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1523} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1507}
"WPFToggleNumLock": { "WPFToggleNumLock": {
"Content": "Num Lock on Startup", "Content": "Num Lock on Startup",
"Description": "Toggle the Num Lock key state when your computer starts.", "Description": "Toggle the Num Lock key state when your computer starts.",
@@ -3,7 +3,7 @@ title: "S3 Sleep"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1585} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1569}
"WPFToggleS3Sleep": { "WPFToggleS3Sleep": {
"Content": "S3 Sleep", "Content": "S3 Sleep",
"Description": "Toggles between Modern Standby and S3 Sleep, which cuts off power to the CPU while continuing to refresh the memory.", "Description": "Toggles between Modern Standby and S3 Sleep, which cuts off power to the CPU while continuing to refresh the memory.",
@@ -3,7 +3,7 @@ title: "Scrollbars Always Visible"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1444} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1428}
"WPFToggleScrollbars": { "WPFToggleScrollbars": {
"Content": "Scrollbars Always Visible", "Content": "Scrollbars Always Visible",
"Description": "If enabled, scrollbars will always be visible. If disabled, Windows will automatically hide scrollbars when not in use.", "Description": "If enabled, scrollbars will always be visible. If disabled, Windows will automatically hide scrollbars when not in use.",
@@ -3,7 +3,7 @@ title: "File Explorer File Extensions"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1328} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1312}
"WPFToggleShowExt": { "WPFToggleShowExt": {
"Content": "File Explorer File Extensions", "Content": "File Explorer File Extensions",
"Description": "Shows .file extensions in Explorer (.exe, .png, etc.)", "Description": "Shows .file extensions in Explorer (.exe, .png, etc.)",
@@ -3,7 +3,7 @@ title: "S0 Sleep Network Connectivity"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1567} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1551}
"WPFToggleStandbyFix": { "WPFToggleStandbyFix": {
"Content": "S0 Sleep Network Connectivity", "Content": "S0 Sleep Network Connectivity",
"Description": "Toggles network connectivity during S0 Sleep which is low power idle in modern laptops.", "Description": "Toggles network connectivity during S0 Sleep which is low power idle in modern laptops.",
@@ -3,7 +3,7 @@ title: "Start Menu Recommendations"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1674} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1658}
"WPFToggleStartMenuRecommendations": { "WPFToggleStartMenuRecommendations": {
"Content": "Start Menu Recommendations", "Content": "Start Menu Recommendations",
"Description": "Toggles the recommendations section in the Start Menu. WARNING: This will also disable Windows Spotlight on your Lock Screen as a side effect.", "Description": "Toggles the recommendations section in the Start Menu. WARNING: This will also disable Windows Spotlight on your Lock Screen as a side effect.",
@@ -3,7 +3,7 @@ title: "Sticky Keys"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1718} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1702}
"WPFToggleStickyKeys": { "WPFToggleStickyKeys": {
"Content": "Sticky Keys", "Content": "Sticky Keys",
"Description": "Toggles the Sticky Keys, which activate when clicking shift rapidly.", "Description": "Toggles the Sticky Keys, which activate when clicking shift rapidly.",
@@ -3,7 +3,7 @@ title: "Taskbar Task View Icon"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1782} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1766}
"WPFToggleTaskView": { "WPFToggleTaskView": {
"Content": "Taskbar Task View Icon", "Content": "Taskbar Task View Icon",
"Description": "Toggles the Task View Button in the Taskbar.", "Description": "Toggles the Task View Button in the Taskbar.",
@@ -3,7 +3,7 @@ title: "Taskbar Centered Icons"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1736} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1720}
"WPFToggleTaskbarAlignment": { "WPFToggleTaskbarAlignment": {
"Content": "Taskbar Centered Icons", "Content": "Taskbar Centered Icons",
"Description": "Toggles the Taskbar alignment either to the left or center.", "Description": "Toggles the Taskbar alignment either to the left or center.",
@@ -3,7 +3,7 @@ title: "Taskbar Search Icon"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1764} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1748}
"WPFToggleTaskbarSearch": { "WPFToggleTaskbarSearch": {
"Content": "Taskbar Search Icon", "Content": "Taskbar Search Icon",
"Description": "Toggles the Search Button on the Taskbar.", "Description": "Toggles the Search Button on the Taskbar.",
@@ -3,7 +3,7 @@ title: "Logon Verbose Mode"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1384} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1368}
"WPFToggleVerboseLogon": { "WPFToggleVerboseLogon": {
"Content": "Logon Verbose Mode", "Content": "Logon Verbose Mode",
"Description": "Show detailed messages during startup/shutdown.", "Description": "Show detailed messages during startup/shutdown.",
@@ -3,7 +3,7 @@ title: "Window Snapping"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1549} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1533}
"WPFToggleWindowSnapping": { "WPFToggleWindowSnapping": {
"Content": "Window Snapping", "Content": "Window Snapping",
"Description": "Toggles the window snapping feature when dragging windows.", "Description": "Toggles the window snapping feature when dragging windows.",
@@ -6,7 +6,7 @@ description: ""
```json {filename="config/tweaks.json",linenos=inline,linenostart=430} ```json {filename="config/tweaks.json",linenos=inline,linenostart=430}
"WPFTweaksConsumerFeatures": { "WPFTweaksConsumerFeatures": {
"Content": "ConsumerFeatures - Disable", "Content": "ConsumerFeatures - Disable",
"Description": "Stops promoted app installs and reduces app suggestions from Microsoft Store content.", "Description": "Windows will not automatically install any games, third-party apps, or application links from the Windows Store for the signed-in user. Some default Apps will be inaccessible (e.g. Phone Link).",
"category": "Essential Tweaks", "category": "Essential Tweaks",
"panel": "1", "panel": "1",
"registry": [ "registry": [
@@ -3,7 +3,7 @@ title: "Temporary Files - Remove"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1082} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1066}
"WPFTweaksDeleteTempFiles": { "WPFTweaksDeleteTempFiles": {
"Content": "Temporary Files - Remove", "Content": "Temporary Files - Remove",
"Description": "Erases TEMP Folders.", "Description": "Erases TEMP Folders.",
@@ -3,7 +3,7 @@ title: "File Explorer Automatic Folder Discovery - Disable"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1187} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1171}
"WPFTweaksDisableExplorerAutoDiscovery": { "WPFTweaksDisableExplorerAutoDiscovery": {
"Content": "File Explorer Automatic Folder Discovery - Disable", "Content": "File Explorer Automatic Folder Discovery - Disable",
"Description": "Windows Explorer automatically tries to guess the type of the folder based on its contents, slowing down the browsing experience. WARNING! Will disable File Explorer grouping.", "Description": "Windows Explorer automatically tries to guess the type of the folder based on its contents, slowing down the browsing experience. WARNING! Will disable File Explorer grouping.",
@@ -3,7 +3,7 @@ title: "Disk Cleanup - Run"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1069} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1053}
"WPFTweaksDiskCleanup": { "WPFTweaksDiskCleanup": {
"Content": "Disk Cleanup - Run", "Content": "Disk Cleanup - Run",
"Description": "Runs Disk Cleanup on Drive C: and removes old Windows Updates.", "Description": "Runs Disk Cleanup on Drive C: and removes old Windows Updates.",
@@ -1,27 +0,0 @@
---
title: "Prevent Device Companion Apps"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=947}
"WPFTweaksPreventDeviceMetadataFromNetwork": {
"Content": "Prevent Device Companion Apps",
"Description": "Prevents additional software from being installed when plugging in devices (e.g. Ads when plugging in a monitor). Poses potential security risk.",
"category": "Essential Tweaks",
"panel": "1",
"registry": [
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Device Metadata",
"Name": "PreventDeviceMetadataFromNetwork",
"Value": "1",
"Type": "DWord",
"OriginalValue": "<RemoveEntry>"
}
],
```
## Registry Changes
Applications and System Components store and retrieve configuration data to modify Windows settings, so we can use the registry to change many settings in one place.
You can find information about the registry on [Wikipedia](https://en.wikipedia.org/wiki/Windows_Registry) and [Microsoft's Website](https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry).
@@ -3,7 +3,7 @@ title: "Adobe URL Block List - Enable"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1027} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1011}
"WPFTweaksBlockAdobeNet": { "WPFTweaksBlockAdobeNet": {
"Content": "Adobe URL Block List - Enable", "Content": "Adobe URL Block List - Enable",
"Description": "Reduces user interruptions by selectively blocking connections to Adobe's activation and telemetry servers. Credit: Ruddernation-Designs", "Description": "Reduces user interruptions by selectively blocking connections to Adobe's activation and telemetry servers. Credit: Ruddernation-Designs",
@@ -3,7 +3,7 @@ title: "Background Apps - Disable"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1155} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1139}
"WPFTweaksDisableBGapps": { "WPFTweaksDisableBGapps": {
"Content": "Background Apps - Disable", "Content": "Background Apps - Disable",
"Description": "Disables all Microsoft Store apps from running in the background, which has to be done individually since Windows 11.", "Description": "Disables all Microsoft Store apps from running in the background, which has to be done individually since Windows 11.",
@@ -3,7 +3,7 @@ title: "Fullscreen Optimizations - Disable"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1171} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1155}
"WPFTweaksDisableFSO": { "WPFTweaksDisableFSO": {
"Content": "Fullscreen Optimizations - Disable", "Content": "Fullscreen Optimizations - Disable",
"Description": "Disables FSO in all applications. NOTE: This will disable Color Management in Exclusive Fullscreen.", "Description": "Disables FSO in all applications. NOTE: This will disable Color Management in Exclusive Fullscreen.",
@@ -3,7 +3,7 @@ title: "IPv6 - Disable"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1133} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1117}
"WPFTweaksDisableIPv6": { "WPFTweaksDisableIPv6": {
"Content": "IPv6 - Disable", "Content": "IPv6 - Disable",
"Description": "Disables IPv6.", "Description": "Disables IPv6.",
@@ -3,7 +3,7 @@ title: "System Tray Notifications & Calendar - Disable"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1004} ```json {filename="config/tweaks.json",linenos=inline,linenostart=988}
"WPFTweaksDisableNotifications": { "WPFTweaksDisableNotifications": {
"Content": "System Tray Notifications & Calendar - Disable", "Content": "System Tray Notifications & Calendar - Disable",
"Description": "Disables all Notifications INCLUDING Calendar.", "Description": "Disables all Notifications INCLUDING Calendar.",
@@ -3,7 +3,7 @@ title: "IPv6 - Set IPv4 as Preferred"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1095} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1079}
"WPFTweaksIPv46": { "WPFTweaksIPv46": {
"Content": "IPv6 - Set IPv4 as Preferred", "Content": "IPv6 - Set IPv4 as Preferred",
"Description": "Setting the IPv4 preference can have latency and security benefits on private networks where IPv6 is not configured.", "Description": "Setting the IPv4 preference can have latency and security benefits on private networks where IPv6 is not configured.",
@@ -5,53 +5,15 @@ description: ""
```powershell {filename="functions/public/Invoke-WPFOOSU.ps1",linenos=inline,linenostart=1} ```powershell {filename="functions/public/Invoke-WPFOOSU.ps1",linenos=inline,linenostart=1}
function Invoke-WPFOOSU { function Invoke-WPFOOSU {
if ($sync.ProcessRunning) { try {
Show-WinUtilMessage -Message "Another process is currently running." -Title "WinUtil" -Button "OK" -Icon "Warning" $ProgressPreference = 'SilentlyContinue'
return
}
$downloadPath = Join-Path $sync.winutildir "ooshutup10.exe" Invoke-WebRequest -Uri https://dl5.oo-software.com/files/ooshutup10/OOSU10.exe -OutFile "$winutildir\ooshutup10.exe"
$sync.ProcessRunning = $true Start-Process -FilePath "$winutildir\ooshutup10.exe"
Invoke-WPFRunspace -ParameterList @(,("downloadPath", $downloadPath)) -ScriptBlock { $ProgressPreference = 'Continue'
param($downloadPath) } catch {
Write-Error "Couldn't download O&O ShutUp10. Please make sure you have an active Internet connection."
$hasUI = $null -ne $sync.Form -and $null -ne $sync.Form.Dispatcher
try {
Write-WinUtilLog -Component "OOSU" -Message "Downloading O&O ShutUp10++."
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Downloading O&O ShutUp10++ (0%)" -Percent 0
}
Save-WinUtilFile -Uri "https://dl5.oo-software.com/files/ooshutup10/OOSU10.exe" -DestinationPath $downloadPath -ProgressCallback {
param($percent)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Downloading O&O ShutUp10++ ($percent%)" -Percent $percent
}
}
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Launching O&O ShutUp10++" -Percent 100
}
Start-Process -FilePath $downloadPath
Write-WinUtilLog -Component "OOSU" -Message "O&O ShutUp10++ launched."
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "O&O ShutUp10++ launched" -Percent 100
}
}
catch {
Write-WinUtilLog -Level "ERROR" -Component "OOSU" -Message "O&O ShutUp10++ download failed: $($_.Exception.Message)"
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "O&O ShutUp10++ download failed" -Percent 100
}
Write-Error "Couldn't download O&O ShutUp10. Please make sure you have an active Internet connection."
}
finally {
$sync.ProcessRunning = $false
}
} }
} }
``` ```
@@ -3,7 +3,7 @@ title: "Razer Software Auto-Install - Disable"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=963} ```json {filename="config/tweaks.json",linenos=inline,linenostart=947}
"WPFTweaksRazerBlock": { "WPFTweaksRazerBlock": {
"Content": "Razer Software Auto-Install - Disable", "Content": "Razer Software Auto-Install - Disable",
"Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.", "Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.",
@@ -3,7 +3,7 @@ title: "Right-Click Menu Previous Layout - Enable"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1053} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1037}
"WPFTweaksRightClickMenu": { "WPFTweaksRightClickMenu": {
"Content": "Right-Click Menu Previous Layout - Enable", "Content": "Right-Click Menu Previous Layout - Enable",
"Description": "Restores the classic context menu when right-clicking in File Explorer, replacing the simplified Windows 11 version.", "Description": "Restores the classic context menu when right-clicking in File Explorer, replacing the simplified Windows 11 version.",
@@ -3,7 +3,7 @@ title: "Teredo - Disable"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1111} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1095}
"WPFTweaksTeredo": { "WPFTweaksTeredo": {
"Content": "Teredo - Disable", "Content": "Teredo - Disable",
"Description": "Teredo network tunneling is an IPv6 feature that can cause additional latency, but may cause problems with some games.", "Description": "Teredo network tunneling is an IPv6 feature that can cause additional latency, but may cause problems with some games.",
@@ -3,7 +3,7 @@ title: "DNS - Set to:"
description: "" description: ""
--- ---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1851} ```json {filename="config/tweaks.json",linenos=inline,linenostart=1835}
"WPFchangedns": { "WPFchangedns": {
"Content": "DNS - Set to:", "Content": "DNS - Set to:",
"category": "z__Advanced Tweaks - CAUTION", "category": "z__Advanced Tweaks - CAUTION",
@@ -138,7 +138,7 @@ For a better Windows experience with minimal risk:
1. Check multiple application boxes 1. Check multiple application boxes
2. All checked apps will install in sequence 2. All checked apps will install in sequence
3. Install and uninstall progress is shown in the window-level bottom panel, including the current package or package-manager batch and overall completion 3. Progress is shown in the bottom panel
### Applying Tweaks ### Applying Tweaks
-8
View File
@@ -34,14 +34,6 @@ Use the quick-selection buttons at the top of the Tweaks tab to speed up setup:
* **Select Tweaks to Remove**: Choose the tweaks you want to disable or remove. * **Select Tweaks to Remove**: Choose the tweaks you want to disable or remove.
* **Undo Tweaks**: Click **Undo Selected Tweaks** at the bottom of the screen to apply the changes. * **Undo Tweaks**: Click **Undo Selected Tweaks** at the bottom of the screen to apply the changes.
### AppX Packages
Open **AppX Removal** from the Tweaks tab to manage the listed Windows apps. Select one or more packages, then choose **Install Selected** or **Remove Selected**.
When installing a selected package, WinUtil first registers an existing local `AppxManifest.xml`. If no usable local manifest remains, WinUtil installs the package from the Microsoft Store through WinGet when a Store product ID is available.
During AppX installation or removal, the window-level progress bar shows the current package, completed package count, and overall progress. The Windows taskbar also reflects progress and the final success or failure state.
### Essential Tweaks ### Essential Tweaks
Essential Tweaks are the safest starting point for most systems. They focus on lower-risk changes that improve usability, reduce noise, and avoid the more invasive changes found in advanced options. Essential Tweaks are the safest starting point for most systems. They focus on lower-risk changes that improve usability, reduce noise, and avoid the more invasive changes found in advanced options.
+12 -14
View File
@@ -9,30 +9,28 @@ WinUtil provides three update modes so you can choose how aggressively Windows U
Changing modes adjusts system-wide Windows Update behavior. After switching modes, give Windows a moment to apply the policy and plan for a restart if the new state does not appear immediately. Changing modes adjusts system-wide Windows Update behavior. After switching modes, give Windows a moment to apply the policy and plan for a restart if the new state does not appear immediately.
- **Recommended**: Prioritizes stability while still receiving security updates {{< image src="images/updates-tab-new" alt="Updates tab in WinUtil" >}}
- **Windows Default**: Restores standard Windows Update behavior
- **Disable Updates**: Blocks Windows Update and should only be used with extreme caution
### Windows Default - **Default (Out of the Box) Settings**: Restores standard Windows Update behavior
- **Security (Recommended) Settings**: Prioritizes stability while still receiving security updates
- **Disable ALL Updates**: Turns off Windows Update entirely and should only be used with extreme caution
- **What it does**: Removes Windows Update policies managed by WinUtil, restores update service startup settings, and re-enables update scheduled tasks. ### Default (Out of Box) Settings
- **What it does**: Restores the default Windows Update configuration.
- **Best for**: Systems where you want Windows to manage updates normally. - **Best for**: Systems where you want Windows to manage updates normally.
- **Notes**: Only values managed by WinUtil are removed; other Windows Update policies are left in place. If update errors continue, use the reset option in the **Config** tab to repair Microsoft Update components. - **Notes**: This removes custom update settings previously applied by WinUtil. If update errors continue, use the reset option in the **Config** tab to restore Microsoft Update services to their default state.
### Recommended ### Security (Recommended) Settings
- **What it does**: Applies a more conservative update strategy designed for most users. - **What it does**: Applies a more conservative update strategy designed for most users.
- **Feature updates**: Delayed by **365 days** to reduce the chance of disruption from major Windows changes. - **Feature updates**: Delayed by **365 days** to reduce the chance of disruption from major Windows changes.
- **Quality updates**: Delayed by **4 days** to allow time for early issues to surface while still keeping the system protected. - **Security updates**: Delayed by **4 days** to allow time for early issues to surface while still keeping the system protected.
- **Drivers**: Excluded from Windows quality updates.
- **Restarts**: Scheduled updates do not automatically restart Windows while a user is signed in. A restart explicitly scheduled by a user still takes precedence.
- **Availability**: Update deferral policies apply to Windows Pro, Enterprise, and Education editions.
- **Why use it**: This mode offers the best balance between security and stability, which is why it is the recommended option for most PCs. - **Why use it**: This mode offers the best balance between security and stability, which is why it is the recommended option for most PCs.
### Disable Updates (NOT RECOMMENDED!) ### Disable ALL Updates (NOT RECOMMENDED!)
- **What it does**: Disables automatic update policy, stops and disables update services, disables update scheduled tasks, and clears downloaded update files. - **What it does**: Disables all Windows updates.
- **Best for**: Highly controlled or special-purpose systems where updates must remain off temporarily. - **Best for**: Highly controlled or special-purpose systems where updates must remain off temporarily.
- **Warning**: This leaves the system without security patches and significantly increases security risk. - **Warning**: This leaves the system without security patches and significantly increases security risk.
- **Notes**: Windows servicing can restore update components in some circumstances. Use **Restore Defaults** when you are ready to receive updates again.
- **Recommendation**: Avoid this mode unless you fully understand the tradeoffs and have a specific reason to use it. - **Recommendation**: Avoid this mode unless you fully understand the tradeoffs and have a specific reason to use it.
@@ -10,9 +10,6 @@ function Find-AppsByNameOrDescription {
.PARAMETER SearchString .PARAMETER SearchString
The string to be searched for. Wildcards are treated as literal characters. The string to be searched for. Wildcards are treated as literal characters.
.PARAMETER Category
When provided, only applications in this exact category are shown.
.NOTES .NOTES
- Uses module-scope $sync (no parameter needed; inherits from caller's scope) - Uses module-scope $sync (no parameter needed; inherits from caller's scope)
- Performs literal matching (no wildcard expansion) - Performs literal matching (no wildcard expansion)
@@ -21,10 +18,7 @@ function Find-AppsByNameOrDescription {
#> #>
param( param(
[Parameter(Mandatory = $false)] [Parameter(Mandatory = $false)]
[string]$SearchString = "", [string]$SearchString = ""
[Parameter(Mandatory = $false)]
[string]$Category = ""
) )
# Validate that $sync exists and has required structure # Validate that $sync exists and has required structure
@@ -45,7 +39,7 @@ function Find-AppsByNameOrDescription {
try { try {
# Reset the visibility if the search string is empty or the search is cleared # Reset the visibility if the search string is empty or the search is cleared
if ([string]::IsNullOrWhiteSpace($SearchString) -and [string]::IsNullOrWhiteSpace($Category)) { if ([string]::IsNullOrWhiteSpace($SearchString)) {
$sync.ItemsControl.Items | ForEach-Object { $sync.ItemsControl.Items | ForEach-Object {
# Each item is a StackPanel container # Each item is a StackPanel container
$_.Visibility = [Windows.Visibility]::Visible $_.Visibility = [Windows.Visibility]::Visible
@@ -100,11 +94,10 @@ function Find-AppsByNameOrDescription {
# Check if app matches search criteria # Check if app matches search criteria
if ($null -ne $appEntry) { if ($null -ne $appEntry) {
$categoryMatch = -not [string]::IsNullOrWhiteSpace($Category) -and $appEntry.Category -eq $Category $contentMatch = $appEntry.Content -like "*$escapedSearchString*"
$contentMatch = [string]::IsNullOrWhiteSpace($Category) -and $appEntry.Content -like "*$escapedSearchString*" $descriptionMatch = $appEntry.Description -like "*$escapedSearchString*"
$descriptionMatch = [string]::IsNullOrWhiteSpace($Category) -and $appEntry.Description -like "*$escapedSearchString*"
if ($categoryMatch -or $contentMatch -or $descriptionMatch) { if ($contentMatch -or $descriptionMatch) {
# Show the App and mark that this category has a match # Show the App and mark that this category has a match
$appControl.Visibility = [Windows.Visibility]::Visible $appControl.Visibility = [Windows.Visibility]::Visible
$categoryHasMatch = $true $categoryHasMatch = $true
@@ -1,24 +0,0 @@
function Get-WinUtilInstalledAPPX {
<#
.SYNOPSIS
Gets the names of AppX packages installed for all users
#>
# AppX module auto-loading can leave PowerShell 7 dependent on a temporary Windows PowerShell
# compatibility proxy. Run the query in Windows PowerShell 5.1 so it remains available after
# those temporary proxy files are removed.
$ps5Command = {
Get-AppxPackage -AllUsers -ErrorAction Stop | Select-Object -ExpandProperty Name
}
$packageOutput = powershell.exe -NoProfile -NonInteractive -Command $ps5Command 2>&1
if ($LASTEXITCODE -ne 0) {
$failureDetails = ($packageOutput | Out-String).Trim()
Write-WinUtilLog -Level "ERROR" -Component "AppX" -Message "Failed to get installed AppX packages: $failureDetails"
return @()
}
return @($packageOutput)
}
@@ -0,0 +1,12 @@
function Hide-WPFInstallAppBusy {
<#
.SYNOPSIS
Hides the busy overlay in the install app area of the WPF form.
This is used to indicate that an install or uninstall has finished.
#>
Invoke-WPFUIThread -ScriptBlock {
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Collapsed
$sync.InstallAppAreaBorder.IsEnabled = $true
$sync.InstallAppAreaScrollViewer.Effect.Radius = 0
}
}
@@ -5,6 +5,8 @@
This is used as the parent object for all category and app entries on the install tab 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 Used to as part of the Install Tab UI generation
Also creates an overlay with a progress bar and text to indicate that an install or uninstall is in progress
.PARAMETER TargetElement .PARAMETER TargetElement
The element to which the AppArea should be added The element to which the AppArea should be added
@@ -17,14 +19,22 @@
$Border = New-Object Windows.Controls.Border $Border = New-Object Windows.Controls.Border
$Border.VerticalAlignment = "Stretch" $Border.VerticalAlignment = "Stretch"
$Border.SetResourceReference([Windows.Controls.Control]::StyleProperty, "BorderStyle") $Border.SetResourceReference([Windows.Controls.Control]::StyleProperty, "BorderStyle")
$sync.InstallAppAreaBorder = $Border
# Add a ScrollViewer, because the ItemsControl does not support scrolling by itself # Add a ScrollViewer, because the ItemsControl does not support scrolling by itself
$scrollViewer = New-Object Windows.Controls.ScrollViewer $scrollViewer = New-Object Windows.Controls.ScrollViewer
$scrollViewer.VerticalScrollBarVisibility = 'Auto' $scrollViewer.VerticalScrollBarVisibility = 'Auto'
$scrollViewer.HorizontalAlignment = 'Stretch' $scrollViewer.HorizontalAlignment = 'Stretch'
$scrollViewer.VerticalAlignment = 'Stretch' $scrollViewer.VerticalAlignment = 'Stretch'
$scrollViewer.CanContentScroll = $true $scrollViewer.CanContentScroll = $true
$sync.InstallAppAreaScrollViewer = $scrollViewer
$Border.Child = $scrollViewer $Border.Child = $scrollViewer
# Initialize the Blur Effect for the ScrollViewer, which will be used to indicate that an install/uninstall is in progress
$blurEffect = New-Object Windows.Media.Effects.BlurEffect
$blurEffect.Radius = 0
$scrollViewer.Effect = $blurEffect
## Create the ItemsControl, which will be the parent of all the app entries ## Create the ItemsControl, which will be the parent of all the app entries
$itemsControl = New-Object Windows.Controls.ItemsControl $itemsControl = New-Object Windows.Controls.ItemsControl
$itemsControl.HorizontalAlignment = 'Stretch' $itemsControl.HorizontalAlignment = 'Stretch'
@@ -42,5 +52,61 @@
# Add the Border containing the App Area to the target Grid # Add the Border containing the App Area to the target Grid
$targetGrid.Children.Add($Border) | Out-Null $targetGrid.Children.Add($Border) | Out-Null
$overlay = New-Object Windows.Controls.Border
$overlay.CornerRadius = New-Object Windows.CornerRadius(10)
$overlay.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallOverlayBackgroundColor")
$overlay.Visibility = [Windows.Visibility]::Collapsed
# Also add the overlay to the target Grid on top of the App Area
$targetGrid.Children.Add($overlay) | Out-Null
$sync.InstallAppAreaOverlay = $overlay
$overlayText = New-Object Windows.Controls.TextBlock
$overlayText.Text = "Installing apps..."
$overlayText.HorizontalAlignment = 'Center'
$overlayText.VerticalAlignment = 'Center'
$overlayText.SetResourceReference([Windows.Controls.TextBlock]::ForegroundProperty, "MainForegroundColor")
$overlayText.Background = "Transparent"
$overlayText.SetResourceReference([Windows.Controls.TextBlock]::FontSizeProperty, "HeaderFontSize")
$overlayText.SetResourceReference([Windows.Controls.TextBlock]::FontFamilyProperty, "MainFontFamily")
$overlayText.SetResourceReference([Windows.Controls.TextBlock]::FontWeightProperty, "MainFontWeight")
$overlayText.SetResourceReference([Windows.Controls.TextBlock]::MarginProperty, "MainMargin")
$sync.InstallAppAreaOverlayText = $overlayText
$progressbar = New-Object Windows.Controls.ProgressBar
$progressbar.Name = "ProgressBar"
$progressbar.Width = 250
$progressbar.Height = 50
$sync.ProgressBar = $progressbar
# Add a TextBlock overlay for the progress bar text
$progressBarTextBlock = New-Object Windows.Controls.TextBlock
$progressBarTextBlock.Name = "progressBarTextBlock"
$progressBarTextBlock.FontWeight = [Windows.FontWeights]::Bold
$progressBarTextBlock.FontSize = 16
$progressBarTextBlock.Width = $progressbar.Width
$progressBarTextBlock.Height = $progressbar.Height
$progressBarTextBlock.SetResourceReference([Windows.Controls.TextBlock]::ForegroundProperty, "ProgressBarTextColor")
$progressBarTextBlock.TextTrimming = "CharacterEllipsis"
$progressBarTextBlock.Background = "Transparent"
$sync.progressBarTextBlock = $progressBarTextBlock
# Create a Grid to overlay the text on the progress bar
$progressGrid = New-Object Windows.Controls.Grid
$progressGrid.Width = $progressbar.Width
$progressGrid.Height = $progressbar.Height
$progressGrid.Margin = "0,10,0,10"
$progressGrid.Children.Add($progressbar) | Out-Null
$progressGrid.Children.Add($progressBarTextBlock) | Out-Null
$overlayStackPanel = New-Object Windows.Controls.StackPanel
$overlayStackPanel.Orientation = "Vertical"
$overlayStackPanel.HorizontalAlignment = 'Center'
$overlayStackPanel.VerticalAlignment = 'Center'
$overlayStackPanel.Children.Add($overlayText) | Out-Null
$overlayStackPanel.Children.Add($progressGrid) | Out-Null
$overlay.Child = $overlayStackPanel
return $itemsControl return $itemsControl
} }
@@ -60,30 +60,6 @@ function Initialize-InstallAppEntry {
$borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor") $borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor")
}) })
$contentPanel = New-Object Windows.Controls.StackPanel
$contentPanel.Orientation = "Horizontal"
$contentPanel.VerticalAlignment = [Windows.VerticalAlignment]::Center
$icon = New-Object Windows.Controls.Grid
$icon.SetResourceReference([Windows.FrameworkElement]::WidthProperty, "AppEntryIconSize")
$icon.SetResourceReference([Windows.FrameworkElement]::HeightProperty, "AppEntryIconSize")
$icon.Margin = New-Object Windows.Thickness(0, 0, 8, 0)
$fallback = New-Object Windows.Controls.TextBlock
$fallback.Text = $app.content.TrimStart(".").Substring(0, 1).ToUpper()
$fallback.FontWeight = "Bold"; $fallback.HorizontalAlignment = "Center"; $fallback.VerticalAlignment = "Center"
if ($app.link) { $fallback.Visibility = "Collapsed" }
$fallback.SetResourceReference([Windows.Controls.TextBlock]::FontSizeProperty, "AppEntryFontSize")
$fallback.SetResourceReference([Windows.Controls.TextBlock]::ForegroundProperty, "ToggleButtonOnColor")
[void]$icon.Children.Add($fallback)
if ($app.link) {
$logo = New-Object Windows.Controls.Image
$logo.Stretch = [Windows.Media.Stretch]::Uniform
$logo.Source = "https://www.google.com/s2/favicons?sz=64&domain_url=$([uri]::EscapeDataString($app.link))"
$logo.Add_ImageFailed({ $this.Visibility = "Collapsed"; $this.Parent.Children[0].Visibility = "Visible" })
[void]$icon.Children.Add($logo)
}
[void]$contentPanel.Children.Add($icon)
# Create the TextBlock for the application name # Create the TextBlock for the application name
$appName = New-Object Windows.Controls.TextBlock $appName = New-Object Windows.Controls.TextBlock
$appName.Style = $sync.Form.Resources.AppEntryNameStyle $appName.Style = $sync.Form.Resources.AppEntryNameStyle
@@ -97,8 +73,7 @@ function Initialize-InstallAppEntry {
[void]$appName.Inlines.Add($fossRun) [void]$appName.Inlines.Add($fossRun)
} }
[void]$contentPanel.Children.Add($appName) $checkBox.Content = $appName
$checkBox.Content = $contentPanel
# Add accessibility properties to make the elements screen reader friendly # Add accessibility properties to make the elements screen reader friendly
$checkBox.SetValue([Windows.Automation.AutomationProperties]::NameProperty, $app.content) $checkBox.SetValue([Windows.Automation.AutomationProperties]::NameProperty, $app.content)
@@ -28,7 +28,7 @@ function Initialize-WinUtilTabContent {
"AppX" { "AppX" {
Invoke-WPFUIElements -configVariable $sync.configs.appx -targetGridName "appxpanel" -columncount 2 Invoke-WPFUIElements -configVariable $sync.configs.appx -targetGridName "appxpanel" -columncount 2
} }
"Win11ISO" { "Win11 Creator" {
if ($sync.Form -and $sync.Form.Dispatcher) { if ($sync.Form -and $sync.Form.Dispatcher) {
$sync.Form.Dispatcher.BeginInvoke([System.Windows.Threading.DispatcherPriority]::Background, [action]{ Invoke-WinUtilISOCheckExistingWork }) | Out-Null $sync.Form.Dispatcher.BeginInvoke([System.Windows.Threading.DispatcherPriority]::Background, [action]{ Invoke-WinUtilISOCheckExistingWork }) | Out-Null
} }
-79
View File
@@ -1,79 +0,0 @@
function Install-WinUtilAPPX {
<#
.SYNOPSIS
Registers a local AppX package or installs it from the Microsoft Store
.PARAMETER Name
The AppX package name to install
.PARAMETER StoreId
The optional Microsoft Store product ID used when no local manifest is available
#>
param (
[Parameter(Mandatory = $true)]
[string]$Name,
[string]$StoreId
)
Write-WinUtilLog -Component "AppX" -Message "Installing AppX package: $Name"
# AppX and DISM cmdlets are more reliable in Windows PowerShell 5.1. Query both installed and
# provisioned package metadata because either can expose a local manifest that can be registered.
$ps5Command = {
$packageName = $args[0]
$manifestPaths = [System.Collections.Generic.List[string]]::new()
Get-AppxPackage -AllUsers -Name $packageName -ErrorAction SilentlyContinue |
Sort-Object -Property Version -Descending |
ForEach-Object {
if (-not [string]::IsNullOrWhiteSpace($_.InstallLocation)) {
$manifestPaths.Add((Join-Path $_.InstallLocation "AppxManifest.xml"))
}
}
Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue |
Where-Object DisplayName -EQ $packageName |
ForEach-Object {
if (-not [string]::IsNullOrWhiteSpace($_.InstallLocation)) {
$manifestPaths.Add((Join-Path $_.InstallLocation "AppxManifest.xml"))
}
}
$manifestPath = $manifestPaths |
Select-Object -Unique |
Where-Object { Test-Path -LiteralPath $_ } |
Select-Object -First 1
if ($null -ne $manifestPath) {
Add-AppxPackage -Register $manifestPath -DisableDevelopmentMode -ErrorAction Stop
Write-Output $manifestPath
}
}
$manifestOutput = powershell.exe -NoProfile -NonInteractive -Command $ps5Command -args $Name 2>&1
if ($LASTEXITCODE -eq 0 -and $null -ne $manifestOutput) {
$manifestPath = ($manifestOutput | Select-Object -Last 1).ToString().Trim()
if (-not [string]::IsNullOrWhiteSpace($manifestPath)) {
Write-WinUtilLog -Component "AppX" -Message "Registered local AppX manifest for $Name`: $manifestPath"
return
}
}
if ($LASTEXITCODE -ne 0) {
$failureDetails = ($manifestOutput | Out-String).Trim()
Write-WinUtilLog -Level "WARN" -Component "AppX" -Message "Local AppX registration failed for $Name`: $failureDetails"
}
if ([string]::IsNullOrWhiteSpace($StoreId)) {
$errorMessage = "Unable to install $Name because no local manifest or Microsoft Store ID is available."
Write-WinUtilLog -Level "ERROR" -Component "AppX" -Message $errorMessage
throw $errorMessage
}
Write-WinUtilLog -Component "AppX" -Message "No usable local manifest found for $Name. Installing Microsoft Store product $StoreId."
Install-WinUtilWinget
Install-WinUtilProgramWinget -Action Install -Programs @("msstore:$StoreId")
}
@@ -15,36 +15,32 @@ Function Invoke-WinUtilCurrentSystem {
) )
if ($CheckBox -eq "choco") { if ($CheckBox -eq "choco") {
$apps = (choco list | Select-String -Pattern "^\S+").Matches.Value $apps = (choco list | Select-String -Pattern "^\S+").Matches.Value
$sync.configs.applicationsHashtable.GetEnumerator() | ForEach-Object { $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPFInstall*"}
$packageId = ($_.Value.choco -split ";")[-1].Trim() $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} | ForEach-Object {
if ($packageId -ne "na" -and $packageId -in $apps) { $dependencies = @($sync.configs.applications.$($psitem.Key).choco -split ";")
Write-Output $_.Key if ($dependencies -in $apps) {
Write-Output $psitem.name
} }
} }
} }
if ($checkbox -eq "winget") { if ($checkbox -eq "winget") {
$originalEncoding = [Console]::OutputEncoding $originalEncoding = [Console]::OutputEncoding
try { [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new() $Sync.InstalledPrograms = @("winget", "msstore") | ForEach-Object {
$installedProgramOutput = @(winget list --accept-source-agreements --disable-interactivity 2>&1) winget list -s $psitem | Select-Object -skip 3 | ConvertFrom-String -PropertyNames "Name", "Id", "Version", "Available" -Delimiter '\s{2,}'
if ($LASTEXITCODE -ne 0) {
throw "winget list failed with exit code $LASTEXITCODE."
}
} finally {
[Console]::OutputEncoding = $originalEncoding
} }
$installedProgramText = $installedProgramOutput -join "`n" [Console]::OutputEncoding = $originalEncoding
$sync.configs.applicationsHashtable.GetEnumerator() | ForEach-Object { $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPFInstall*"}
$packageId = (($_.Value.winget -split ";")[-1] -replace "^msstore:", "").Trim() $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} | ForEach-Object {
if ([string]::IsNullOrWhiteSpace($packageId) -or $packageId -eq "na") { $dependencies = @($sync.configs.applications.$($psitem.Key).winget -split ";") | ForEach-Object {
return $psitem -replace "^msstore:", ""
} }
$packagePattern = "(?im)[^\S\r\n]{2,}$([regex]::Escape($packageId))(?=[^\S\r\n]{2,}|$)" if ($dependencies[-1] -in $sync.InstalledPrograms.Id) {
if ($installedProgramText -match $packagePattern) { Write-Output $psitem.name
Write-Output $_.Key
} }
} }
} }
+28 -42
View File
@@ -47,7 +47,7 @@ function Invoke-WinUtilISOMountAndVerify {
} }
Write-Win11ISOLog "Mounting ISO: $isoPath" Write-Win11ISOLog "Mounting ISO: $isoPath"
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Mounting ISO..." -Percent 10 Set-WinUtilProgressBar -Label "Mounting ISO..." -Percent 10
try { try {
Mount-DiskImage -ImagePath $isoPath Mount-DiskImage -ImagePath $isoPath
@@ -59,7 +59,7 @@ function Invoke-WinUtilISOMountAndVerify {
$driveLetter = (Get-DiskImage -ImagePath $isoPath | Get-Volume).DriveLetter + ":" $driveLetter = (Get-DiskImage -ImagePath $isoPath | Get-Volume).DriveLetter + ":"
Write-Win11ISOLog "Mounted at drive $driveLetter" Write-Win11ISOLog "Mounted at drive $driveLetter"
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Verifying ISO contents..." -Percent 30 Set-WinUtilProgressBar -Label "Verifying ISO contents..." -Percent 30
$wimPath = Join-Path $driveLetter "sources\install.wim" $wimPath = Join-Path $driveLetter "sources\install.wim"
$esdPath = Join-Path $driveLetter "sources\install.esd" $esdPath = Join-Path $driveLetter "sources\install.esd"
@@ -70,13 +70,13 @@ function Invoke-WinUtilISOMountAndVerify {
[System.Windows.MessageBox]::Show( [System.Windows.MessageBox]::Show(
"This does not appear to be a valid Windows ISO.`n`ninstall.wim / install.esd was not found.", "This does not appear to be a valid Windows ISO.`n`ninstall.wim / install.esd was not found.",
"Invalid ISO", "OK", "Error") "Invalid ISO", "OK", "Error")
Set-WinUtilTweaksProgressIndicator -Visible $false Set-WinUtilProgressBar -Label "" -Percent 0
return return
} }
$activeWim = if (Test-Path $wimPath) { $wimPath } else { $esdPath } $activeWim = if (Test-Path $wimPath) { $wimPath } else { $esdPath }
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Reading image metadata..." -Percent 55 Set-WinUtilProgressBar -Label "Reading image metadata..." -Percent 55
$imageInfo = Get-WindowsImage -ImagePath $activeWim | Select-Object ImageIndex, ImageName $imageInfo = Get-WindowsImage -ImagePath $activeWim | Select-Object ImageIndex, ImageName
if (-not ($imageInfo | Where-Object { $_.ImageName -match "Windows 11" })) { if (-not ($imageInfo | Where-Object { $_.ImageName -match "Windows 11" })) {
@@ -85,7 +85,7 @@ function Invoke-WinUtilISOMountAndVerify {
[System.Windows.MessageBox]::Show( [System.Windows.MessageBox]::Show(
"No Windows 11 edition was found in this ISO.`n`nOnly official Windows 11 ISOs are supported.", "No Windows 11 edition was found in this ISO.`n`nOnly official Windows 11 ISOs are supported.",
"Not a Windows 11 ISO", "OK", "Error") "Not a Windows 11 ISO", "OK", "Error")
Set-WinUtilTweaksProgressIndicator -Visible $false Set-WinUtilProgressBar -Label "" -Percent 0
return return
} }
@@ -114,7 +114,7 @@ function Invoke-WinUtilISOMountAndVerify {
$sync["Win11ISOImagePath"] = $isoPath $sync["Win11ISOImagePath"] = $isoPath
$sync["WPFWin11ISOModifySection"].Visibility = "Visible" $sync["WPFWin11ISOModifySection"].Visibility = "Visible"
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "ISO verified" -Percent 100 Set-WinUtilProgressBar -Label "ISO verified" -Percent 100
Write-Win11ISOLog "ISO verified OK. Editions found: $($imageInfo.Count)" Write-Win11ISOLog "ISO verified OK. Editions found: $($imageInfo.Count)"
} catch { } catch {
Write-Win11ISOLog "ERROR during mount/verify: $_" Write-Win11ISOLog "ERROR during mount/verify: $_"
@@ -123,7 +123,7 @@ function Invoke-WinUtilISOMountAndVerify {
"Error", "OK", "Error") "Error", "OK", "Error")
} finally { } finally {
Start-Sleep -Milliseconds 800 Start-Sleep -Milliseconds 800
Set-WinUtilTweaksProgressIndicator -Visible $false Set-WinUtilProgressBar -Label "" -Percent 0
} }
} }
@@ -151,7 +151,6 @@ function Invoke-WinUtilISOModify {
$sync["WPFWin11ISOModifyButton"].IsEnabled = $false $sync["WPFWin11ISOModifyButton"].IsEnabled = $false
$sync["Win11ISOModifying"] = $true $sync["Win11ISOModifying"] = $true
$sync["Win11ISOProcessRunning"] = $true
$workDir = Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')" $workDir = Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
if (Test-Path $workDir) { if (Test-Path $workDir) {
@@ -204,10 +203,9 @@ function Invoke-WinUtilISOModify {
function SetProgress($label, $pct) { function SetProgress($label, $pct) {
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
$sync["WPFTweaksProgressBar"].Visibility = "Visible" $sync.progressBarTextBlock.Text = $label
$sync["WPFTweaksProgressLabel"].Text = $label $sync.progressBarTextBlock.ToolTip = $label
$sync["WPFTweaksProgressLabel"].ToolTip = $label $sync.ProgressBar.Value = [Math]::Max($pct, 5)
$sync["WPFTweaksProgressValue"].Value = [Math]::Max($pct, 5)
}) })
} }
@@ -454,12 +452,10 @@ function Invoke-WinUtilISOModify {
} finally { } finally {
Start-Sleep -Milliseconds 800 Start-Sleep -Milliseconds 800
$sync["Win11ISOModifying"] = $false $sync["Win11ISOModifying"] = $false
$sync["Win11ISOProcessRunning"] = $false
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
$sync["WPFTweaksProgressBar"].Visibility = "Collapsed" $sync.progressBarTextBlock.Text = ""
$sync["WPFTweaksProgressLabel"].Text = "" $sync.progressBarTextBlock.ToolTip = ""
$sync["WPFTweaksProgressLabel"].ToolTip = "" $sync.ProgressBar.Value = 0
$sync["WPFTweaksProgressValue"].Value = 0
$sync["WPFWin11ISOModifyButton"].IsEnabled = $true $sync["WPFWin11ISOModifyButton"].IsEnabled = $true
if ($sync["WPFWin11ISOOutputSection"].Visibility -ne "Visible") { if ($sync["WPFWin11ISOOutputSection"].Visibility -ne "Visible") {
$sync["WPFWin11ISOSelectSection"].Visibility = "Visible" $sync["WPFWin11ISOSelectSection"].Visibility = "Visible"
@@ -518,7 +514,6 @@ function Invoke-WinUtilISOCleanAndReset {
} }
$sync["WPFWin11ISOCleanResetButton"].IsEnabled = $false $sync["WPFWin11ISOCleanResetButton"].IsEnabled = $false
$sync["Win11ISOProcessRunning"] = $true
$runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace() $runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
$runspace.ApartmentState = "STA" $runspace.ApartmentState = "STA"
@@ -543,10 +538,9 @@ function Invoke-WinUtilISOCleanAndReset {
function SetProgress($label, $pct) { function SetProgress($label, $pct) {
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
$sync["WPFTweaksProgressBar"].Visibility = "Visible" $sync.progressBarTextBlock.Text = $label
$sync["WPFTweaksProgressLabel"].Text = $label $sync.progressBarTextBlock.ToolTip = $label
$sync["WPFTweaksProgressLabel"].ToolTip = $label $sync.ProgressBar.Value = [Math]::Max($pct, 5)
$sync["WPFTweaksProgressValue"].Value = [Math]::Max($pct, 5)
}) })
} }
@@ -634,24 +628,20 @@ function Invoke-WinUtilISOCleanAndReset {
$sync["WPFWin11ISOModifyButton"].IsEnabled = $true $sync["WPFWin11ISOModifyButton"].IsEnabled = $true
$sync["WPFWin11ISOCleanResetButton"].IsEnabled = $true $sync["WPFWin11ISOCleanResetButton"].IsEnabled = $true
$sync["WPFTweaksProgressBar"].Visibility = "Collapsed" $sync.progressBarTextBlock.Text = ""
$sync["WPFTweaksProgressLabel"].Text = "" $sync.progressBarTextBlock.ToolTip = ""
$sync["WPFTweaksProgressLabel"].ToolTip = "" $sync.ProgressBar.Value = 0
$sync["WPFTweaksProgressValue"].Value = 0
$sync["WPFWin11ISOStatusLog"].Text = "Ready. Please select a Windows 11 ISO to begin." $sync["WPFWin11ISOStatusLog"].Text = "Ready. Please select a Windows 11 ISO to begin."
}) })
} catch { } catch {
Log "ERROR during Clean & Reset: $_" Log "ERROR during Clean & Reset: $_"
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
$sync["WPFTweaksProgressBar"].Visibility = "Collapsed" $sync.progressBarTextBlock.Text = ""
$sync["WPFTweaksProgressLabel"].Text = "" $sync.progressBarTextBlock.ToolTip = ""
$sync["WPFTweaksProgressLabel"].ToolTip = "" $sync.ProgressBar.Value = 0
$sync["WPFTweaksProgressValue"].Value = 0
$sync["WPFWin11ISOCleanResetButton"].IsEnabled = $true $sync["WPFWin11ISOCleanResetButton"].IsEnabled = $true
}) })
} finally {
$sync["Win11ISOProcessRunning"] = $false
} }
}) })
@@ -716,7 +706,6 @@ function Invoke-WinUtilISOExport {
} }
$sync["WPFWin11ISOChooseISOButton"].IsEnabled = $false $sync["WPFWin11ISOChooseISOButton"].IsEnabled = $false
$sync["Win11ISOProcessRunning"] = $true
$runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace() $runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
$runspace.ApartmentState = "STA" $runspace.ApartmentState = "STA"
@@ -737,10 +726,9 @@ function Invoke-WinUtilISOExport {
function SetProgress($label, $pct) { function SetProgress($label, $pct) {
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
$sync["WPFTweaksProgressBar"].Visibility = "Visible" $sync.progressBarTextBlock.Text = $label
$sync["WPFTweaksProgressLabel"].Text = $label $sync.progressBarTextBlock.ToolTip = $label
$sync["WPFTweaksProgressLabel"].ToolTip = $label $sync.ProgressBar.Value = [Math]::Max($pct, 5)
$sync["WPFTweaksProgressValue"].Value = [Math]::Max($pct, 5)
}) })
} }
@@ -800,12 +788,10 @@ function Invoke-WinUtilISOExport {
}) })
} finally { } finally {
Start-Sleep -Milliseconds 800 Start-Sleep -Milliseconds 800
$sync["Win11ISOProcessRunning"] = $false
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
$sync["WPFTweaksProgressBar"].Visibility = "Collapsed" $sync.progressBarTextBlock.Text = ""
$sync["WPFTweaksProgressLabel"].Text = "" $sync.progressBarTextBlock.ToolTip = ""
$sync["WPFTweaksProgressLabel"].ToolTip = "" $sync.ProgressBar.Value = 0
$sync["WPFTweaksProgressValue"].Value = 0
$sync["WPFWin11ISOChooseISOButton"].IsEnabled = $true $sync["WPFWin11ISOChooseISOButton"].IsEnabled = $true
}) })
} }
+6 -10
View File
@@ -61,7 +61,6 @@ function Invoke-WinUtilISOWriteUSB {
} }
$sync["WPFWin11ISOWriteUSBButton"].IsEnabled = $false $sync["WPFWin11ISOWriteUSBButton"].IsEnabled = $false
$sync["Win11ISOProcessRunning"] = $true
Write-Win11ISOLog "Starting USB write to Disk $diskNum..." Write-Win11ISOLog "Starting USB write to Disk $diskNum..."
$runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace() $runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
@@ -87,10 +86,9 @@ function Invoke-WinUtilISOWriteUSB {
function SetProgress($label, $pct) { function SetProgress($label, $pct) {
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
$sync["WPFTweaksProgressBar"].Visibility = "Visible" $sync.progressBarTextBlock.Text = $label
$sync["WPFTweaksProgressLabel"].Text = $label $sync.progressBarTextBlock.ToolTip = $label
$sync["WPFTweaksProgressLabel"].ToolTip = $label $sync.ProgressBar.Value = [Math]::Max($pct, 5)
$sync["WPFTweaksProgressValue"].Value = [Math]::Max($pct, 5)
}) })
} }
@@ -257,12 +255,10 @@ function Invoke-WinUtilISOWriteUSB {
}) })
} finally { } finally {
Start-Sleep -Milliseconds 800 Start-Sleep -Milliseconds 800
$sync["Win11ISOProcessRunning"] = $false
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
$sync["WPFTweaksProgressBar"].Visibility = "Collapsed" $sync.progressBarTextBlock.Text = ""
$sync["WPFTweaksProgressLabel"].Text = "" $sync.progressBarTextBlock.ToolTip = ""
$sync["WPFTweaksProgressLabel"].ToolTip = "" $sync.ProgressBar.Value = 0
$sync["WPFTweaksProgressValue"].Value = 0
$sync["WPFWin11ISOWriteUSBButton"].IsEnabled = $true $sync["WPFWin11ISOWriteUSBButton"].IsEnabled = $true
}) })
} }
@@ -78,7 +78,6 @@ function Invoke-WinUtilTweaks {
$sync.configs.tweaks.$CheckBox.appx | ForEach-Object { $sync.configs.tweaks.$CheckBox.appx | ForEach-Object {
Remove-WinUtilAPPX -Name $psitem Remove-WinUtilAPPX -Name $psitem
} }
Remove-WinUtilProvisionedAPPX -PackageList $sync.configs.tweaks.$CheckBox.appx
} }
} }
Write-WinUtilLog -Component "Tweaks" -Message "$action tweak completed: $CheckBox" Write-WinUtilLog -Component "Tweaks" -Message "$action tweak completed: $CheckBox"
+2 -15
View File
@@ -17,20 +17,7 @@ function Remove-WinUtilAPPX {
Write-Host "Removing $Name" Write-Host "Removing $Name"
Write-WinUtilLog -Component "AppX" -Message "Removing AppX package pattern: $Name" Write-WinUtilLog -Component "AppX" -Message "Removing AppX package pattern: $Name"
Get-AppxPackage $Name -AllUsers | Remove-AppxPackage -AllUsers
# We explicitly loop through packages instead of using the pipeline because PowerShell 7 pipeline binding Get-AppxProvisionedPackage -Online | Where-Object DisplayName -like $Name | Remove-AppxProvisionedPackage -Online
# for Remove-AppxPackage fails silently, and Get-AppxPackage -AllUsers returns duplicate objects for each user profile.
$pkgs = Get-AppxPackage "*$Name*" -AllUsers | Sort-Object -Property PackageFullName -Unique
if ($null -ne $pkgs) {
foreach ($pkg in $pkgs) {
try {
Remove-AppxPackage -Package $pkg.PackageFullName -AllUsers -ErrorAction Stop
}
catch {
Write-WinUtilLog -Level "ERROR" -Component "AppX" -Message "Failed to remove AppX package $($pkg.PackageFullName): $($_.Exception.Message)"
}
}
}
Write-WinUtilLog -Component "AppX" -Message "AppX removal completed for package pattern: $Name" Write-WinUtilLog -Component "AppX" -Message "AppX removal completed for package pattern: $Name"
} }
@@ -1,62 +0,0 @@
function Remove-WinUtilProvisionedAPPX {
<#
.SYNOPSIS
Removes all AppX provisioned packages that match the given names
.PARAMETER PackageList
An array of names of the APPX packages to remove
.EXAMPLE
Remove-WinUtilProvisionedAPPX -PackageList @("Microsoft.Microsoft3DViewer", "Microsoft.WindowsCalculator")
#>
param (
[string[]]$PackageList
)
if ($null -eq $PackageList -or $PackageList.Count -eq 0) {
return
}
Write-Host "`nRemoving provisioned packages..."
Write-WinUtilLog -Component "AppX" -Message "Removing AppX provisioned packages: $($PackageList -join ', ')"
# DISM cmdlets like Get-AppxProvisionedPackage often fail with "Class not registered" or hang in PowerShell 7.
# We shell out to Windows PowerShell 5.1 (powershell.exe) to reliably remove the provisioned packages.
$ps5Command = {
$pkgs = $args
$provisionedPackages = Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue
$failures = [System.Collections.Generic.List[string]]::new()
foreach ($Package in $pkgs) {
$provs = $provisionedPackages |
Where-Object DisplayName -Like "*$Package*"
if ($null -ne $provs) {
foreach ($prov in $provs) {
try {
Remove-AppxProvisionedPackage -Online -PackageName $prov.PackageName -ErrorAction Stop | Out-Null
}
catch {
$failures.Add("Failed to remove provisioned AppX package $($prov.PackageName): $($_.Exception.Message)")
}
}
}
}
if ($failures.Count -gt 0) {
throw ($failures -join [Environment]::NewLine)
}
}
$removalOutput = powershell.exe -NoProfile -NonInteractive -Command $ps5Command -args $PackageList 2>&1
if ($LASTEXITCODE -ne 0 -or $null -ne $removalOutput) {
$failureDetails = ($removalOutput | Out-String).Trim()
$errorMessage = "AppX provisioned package removal failed: $failureDetails"
Write-WinUtilLog -Level "ERROR" -Component "AppX" -Message $errorMessage
throw $errorMessage
}
Write-WinUtilLog -Component "AppX" -Message "AppX provisioned package removal completed."
}
-59
View File
@@ -1,59 +0,0 @@
function Save-WinUtilFile {
<#
.SYNOPSIS
Downloads a file and reports transfer progress.
#>
param(
[Parameter(Mandatory)]
[uri]$Uri,
[Parameter(Mandatory)]
[string]$DestinationPath,
[Parameter(Mandatory)]
[scriptblock]$ProgressCallback
)
$response = $null
$responseStream = $null
$outputStream = $null
try {
$request = [System.Net.WebRequest]::Create($Uri)
$response = $request.GetResponse()
$totalBytes = $response.ContentLength
$responseStream = $response.GetResponseStream()
$outputStream = [System.IO.File]::Create($DestinationPath)
$buffer = New-Object byte[] 81920
$downloadedBytes = 0L
$lastPercent = -1
while (($bytesRead = $responseStream.Read($buffer, 0, $buffer.Length)) -gt 0) {
$outputStream.Write($buffer, 0, $bytesRead)
$downloadedBytes += $bytesRead
if ($totalBytes -gt 0) {
$percent = [Math]::Min(100, [int](($downloadedBytes / $totalBytes) * 100))
if ($percent -ne $lastPercent) {
& $ProgressCallback $percent
$lastPercent = $percent
}
}
}
if ($lastPercent -ne 100) {
& $ProgressCallback 100
}
}
finally {
if ($null -ne $outputStream) {
$outputStream.Dispose()
}
if ($null -ne $responseStream) {
$responseStream.Dispose()
}
if ($null -ne $response) {
$response.Dispose()
}
}
}
@@ -1,17 +0,0 @@
function Set-WinUtilAppCategoryFilter {
<#
.SYNOPSIS
Applies an exact application category filter from an Install tab search chip.
.PARAMETER Category
The application category to show. An empty value clears the filter.
#>
param(
[Parameter(Mandatory = $false)]
[string]$Category = ""
)
$sync.SearchBar.Tag = $Category
$sync.SearchBar.Text = $Category
Find-AppsByNameOrDescription -SearchString $Category -Category $Category
}
@@ -0,0 +1,26 @@
function Set-WinUtilProgressbar{
<#
.SYNOPSIS
This function is used to Update the Progress Bar displayed in the winutil GUI.
It will be automatically hidden if the user clicks something and no process is running
.PARAMETER Label
The Text to be overlaid onto the Progress Bar
.PARAMETER PERCENT
The percentage of the Progress Bar that should be filled (0-100)
#>
param(
[string]$Label,
[ValidateRange(0,100)]
[int]$Percent
)
$progressLabel = $Label
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.Text = $progressLabel}
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.ToolTip = $progressLabel}
if ($Percent -lt 5 ) {
$Percent = 5 # Ensure the progress bar is not empty, as it looks weird
}
Invoke-WPFUIThread -ScriptBlock { $sync.ProgressBar.Value = $Percent}
}
@@ -1,35 +0,0 @@
function Set-WinUtilTweaksProgressIndicator {
<#
.SYNOPSIS
Shows, updates, or hides the window-level progress indicator used by long-running
workflows such as app management, Tweaks, AppX management, and Win11 Creator.
It lives outside the TabControl, so it stays visible no matter which tab is active.
.PARAMETER Visible
Whether the indicator should be shown or hidden.
.PARAMETER Label
The text to display above the progress bar.
.PARAMETER Percent
The percentage of the progress bar that should be filled (0-100).
#>
param(
[bool]$Visible,
[string]$Label,
[ValidateRange(0,100)]
[int]$Percent
)
$indicatorVisible = if ($Visible) { [Windows.Visibility]::Visible } else { [Windows.Visibility]::Collapsed }
$indicatorLabel = $Label
$hasLabel = $PSBoundParameters.ContainsKey('Label')
$hasPercent = $PSBoundParameters.ContainsKey('Percent')
Invoke-WPFUIThread -ScriptBlock {
$sync.WPFTweaksProgressBar.Visibility = $indicatorVisible
if ($hasLabel) {
$sync.WPFTweaksProgressLabel.Text = $indicatorLabel
}
if ($hasPercent) {
$sync.WPFTweaksProgressValue.Value = $Percent
}
}
}
@@ -0,0 +1,23 @@
function Show-WPFInstallAppBusy {
<#
.SYNOPSIS
Displays a busy overlay in the install app area of the WPF form.
This is used to indicate that an install or uninstall is in progress.
Dynamically updates the size of the overlay based on the app area on each invocation.
.PARAMETER text
The text to display in the busy overlay. Defaults to "Installing apps...".
#>
param (
$text = "Installing apps..."
)
$overlayText = $text
Invoke-WPFUIThread -ScriptBlock {
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Visible
$sync.InstallAppAreaOverlay.Width = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
$sync.InstallAppAreaOverlay.Height = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
$sync.InstallAppAreaOverlayText.Text = $overlayText
$sync.InstallAppAreaBorder.IsEnabled = $false
$sync.InstallAppAreaScrollViewer.Effect.Radius = 5
}
}
@@ -9,7 +9,7 @@ function Invoke-WinUtilInstallAppRenderBatch {
} }
if ($sync.currentTab -eq "Install" -and $sync.SearchBar -and -not [string]::IsNullOrWhiteSpace($sync.SearchBar.Text)) { if ($sync.currentTab -eq "Install" -and $sync.SearchBar -and -not [string]::IsNullOrWhiteSpace($sync.SearchBar.Text)) {
Find-AppsByNameOrDescription -SearchString $sync.SearchBar.Text -Category $sync.SearchBar.Tag Find-AppsByNameOrDescription -SearchString $sync.SearchBar.Text
} }
} }
@@ -1,68 +0,0 @@
function Invoke-WPFAppxInstall {
if ($sync.ProcessRunning) {
Show-WinUtilMessage -Message "An AppX process is currently running." -Title "WinUtil" -Button "OK" -Icon "Warning"
return
}
if ($null -eq $sync.selectedAppx -or $sync.selectedAppx.Count -eq 0) {
Show-WinUtilMessage -Message "No AppX Package selected" -Title "Error" -Button "OK" -Icon "Error"
return
}
$selected = @($sync.selectedAppx)
$apps = $sync.configs.appxHashtable
$sync.ProcessRunning = $true
Invoke-WPFRunspace -ParameterList @(("selected", $selected), ("apps", $apps)) -ScriptBlock {
param($selected, $apps)
$totalPackages = @($selected).Count
$hasUI = $null -ne $sync.Form -and $null -ne $sync.Form.Dispatcher
try {
Write-WinUtilLog -Component "AppX" -Message "Starting AppX install for $totalPackages selected package(s)."
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Preparing AppX install (0/$totalPackages)" -Percent 0
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }
}
for ($index = 0; $index -lt $totalPackages; $index++) {
$key = $selected[$index]
$app = $apps[$key]
$position = $index + 1
$startPercent = [int](($index / $totalPackages) * 100)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Installing $($app.Content) ($position/$totalPackages)" -Percent $startPercent
}
Write-Host "Installing $($app.Content)"
Install-WinUtilAPPX -Name $app.PackageId -StoreId $app.StoreId
$completedPercent = [int](($position / $totalPackages) * 100)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Installed $($app.Content) ($position/$totalPackages)" -Percent $completedPercent
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($completedPercent / 100) }
}
}
Write-Host "================================="
Write-Host "-- AppX Install Finished ---"
Write-Host "================================="
Write-WinUtilLog -Component "AppX" -Message "AppX install finished."
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "AppX install finished" -Percent 100
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
}
}
catch {
Write-WinUtilLog -Level "ERROR" -Component "AppX" -Message "AppX install failed: $($_.Exception.Message)"
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "AppX install failed" -Percent 100
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" -overlay "warning" }
}
}
finally {
$sync.ProcessRunning = $false
}
}
}
+29 -78
View File
@@ -1,100 +1,51 @@
function Invoke-WPFAppxRemoval { function Invoke-WPFAppxRemoval {
if ($sync.ProcessRunning) {
Show-WinUtilMessage -Message "An AppX process is currently running." -Title "WinUtil" -Button "OK" -Icon "Warning"
return
}
if ($null -eq $sync.selectedAppx -or $sync.selectedAppx.Count -eq 0) { if ($null -eq $sync.selectedAppx -or $sync.selectedAppx.Count -eq 0) {
Show-WinUtilMessage -Message "No AppX Package selected" -Title "Error" -Button "OK" -Icon "Error" Show-WinUtilMessage -Message "No AppX Package selected" -Title "Error" -Button "OK" -Icon "Error"
return return
} }
$selected = @($sync.selectedAppx) $selected = $sync.selectedAppx
$apps = $sync.configs.appxHashtable $apps = $sync.configs.appxHashtable
$sync.ProcessRunning = $true
Invoke-WPFRunspace -ParameterList @(("selected", $selected), ("apps", $apps)) -ScriptBlock { Invoke-WPFRunspace -ParameterList @(("selected", $selected), ("apps", $apps)) -ScriptBlock {
param($selected, $apps) param($selected, $apps)
$totalPackages = @($selected).Count $sync.ProcessRunning = $true
$hasUI = $null -ne $sync.Form -and $null -ne $sync.Form.Dispatcher Write-WinUtilLog -Component "AppX" -Message "Starting AppX removal for $(@($selected).Count) selected package(s)."
$packageList = [System.Collections.Generic.List[string]]::new()
try { foreach ($key in $selected) {
Write-WinUtilLog -Component "AppX" -Message "Starting AppX removal for $totalPackages selected package(s)." if ($key -eq "WPFAppxMicrosoft_XboxGamingOverlay") {
if ($hasUI) { # Making sure Game Bar isn't running
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Preparing AppX removal (0/$totalPackages)" -Percent 0 Write-WinUtilLog -Component "AppX" -Message "Stopping GameBarFTServer before removing Xbox Gaming Overlay."
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" } Stop-Process -Name GameBarFTServer
# This stops annoying ms-gamebar popup when launching games.
Write-WinUtilLog -Component "AppX" -Message "Disabling Game DVR capture before removing Xbox Gaming Overlay."
Set-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\GameDVR -Name AppCaptureEnabled -Value 0
} }
for ($index = 0; $index -lt $totalPackages; $index++) { if ($key -eq "WPFAppxMicrosoft_WindowsNotepad") {
$key = $selected[$index] # i hope your having fun reading this
$app = $apps[$key] Write-WinUtilLog -Component "AppX" -Message "Stopping dllhost before removing Notepad."
$position = $index + 1 Stop-Process -Name dllhost
$startPercent = [int](($index / $totalPackages) * 90)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Removing $($app.Content) ($position/$totalPackages)" -Percent $startPercent
}
if ($key -eq "WPFAppxMicrosoft_XboxGamingOverlay") {
# Making sure Game Bar isn't running
Write-WinUtilLog -Component "AppX" -Message "Stopping GameBarFTServer before removing Xbox Gaming Overlay."
Stop-Process -Name GameBarFTServer -Force -Confirm:$false -ErrorAction SilentlyContinue
# This stops annoying ms-gamebar popup when launching games.
Write-WinUtilLog -Component "AppX" -Message "Disabling Game DVR capture before removing Xbox Gaming Overlay."
Set-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\GameDVR -Name AppCaptureEnabled -Value 0
}
if ($key -eq "WPFAppxMicrosoft_WindowsNotepad") {
Write-WinUtilLog -Component "AppX" -Message "Stopping dllhost before removing Notepad."
Stop-Process -Name dllhost -Force -Confirm:$false -ErrorAction SilentlyContinue
}
Write-Host "Removing $($app.Content)"
Write-WinUtilLog -Component "AppX" -Message "Removing $($app.Content) ($($app.PackageId))."
Remove-WinUtilAPPX -Name $app.PackageId
$packageList.Add($app.PackageId)
if ($key -eq "WPFAppxMSTeams") {
# Uninstalls Microsoft Teams Meeting Add-in for Microsoft Office
Write-WinUtilLog -Component "AppX" -Message "Uninstalling Microsoft Teams meeting add-in package."
Get-Package -Name "Microsoft Teams*" -ErrorAction SilentlyContinue | Uninstall-Package -Force
}
$completedPercent = [int](($position / $totalPackages) * 90)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Removed $($app.Content) ($position/$totalPackages)" -Percent $completedPercent
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($completedPercent / 100) }
}
} }
if ($packageList.Count -gt 0) { Write-Host "Removing $($apps[$key].Content)"
if ($hasUI) { Write-WinUtilLog -Component "AppX" -Message "Removing $($apps[$key].Content) ($($apps[$key].PackageId))."
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Removing provisioned AppX packages" -Percent 90 Get-AppxPackage -Name $apps[$key].PackageId -AllUsers | Remove-AppxPackage -AllUsers
}
Remove-WinUtilProvisionedAPPX -PackageList $packageList.ToArray()
}
Write-Host "=================================" if ($key -eq "WPFAppxMSTeams") {
Write-Host "-- AppX Removal Finished ---" # Uninstalls Microsoft Teams Meeting Add-in for Microsoft Office
Write-Host "=================================" Write-WinUtilLog -Component "AppX" -Message "Uninstalling Microsoft Teams meeting add-in package."
Write-WinUtilLog -Component "AppX" -Message "AppX removal finished." Get-Package -Name "Microsoft Teams*" -ErrorAction SilentlyContinue | Uninstall-Package -Force
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "AppX removal finished" -Percent 100
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
} }
} }
catch {
Write-WinUtilLog -Level "ERROR" -Component "AppX" -Message "AppX removal failed: $($_.Exception.Message)"
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "AppX removal failed" -Percent 100
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" -overlay "warning" }
}
}
finally {
$sync.ProcessRunning = $false
}
Write-Host "================================="
Write-Host "-- AppX Removal Finished ---"
Write-Host "================================="
Write-WinUtilLog -Component "AppX" -Message "AppX removal finished."
$sync.ProcessRunning = $false
} }
} }
+3 -13
View File
@@ -14,8 +14,8 @@ function Invoke-WPFButton {
# Use this to get the name of the button # Use this to get the name of the button
#[System.Windows.MessageBox]::Show("$Button","Chris Titus Tech's Windows Utility","OK","Info") #[System.Windows.MessageBox]::Show("$Button","Chris Titus Tech's Windows Utility","OK","Info")
if (-not $sync.ProcessRunning -and -not $sync.Win11ISOProcessRunning) { if (-not $sync.ProcessRunning) {
Set-WinUtilTweaksProgressIndicator -Visible $false Set-WinUtilProgressBar -label "" -percent 0
} }
# Check if button is defined in feature config with function or InvokeScript # Check if button is defined in feature config with function or InvokeScript
@@ -65,9 +65,6 @@ function Invoke-WPFButton {
"WPFUpdatessecurity" {Invoke-WPFUpdatessecurity} "WPFUpdatessecurity" {Invoke-WPFUpdatessecurity}
"WPFGetInstalled" {Invoke-WPFGetInstalled -CheckBox "winget"} "WPFGetInstalled" {Invoke-WPFGetInstalled -CheckBox "winget"}
"WPFGetInstalledTweaks" {Invoke-WPFGetInstalled -CheckBox "tweaks"} "WPFGetInstalledTweaks" {Invoke-WPFGetInstalled -CheckBox "tweaks"}
"WPFAppxRemoval" {Invoke-WPFTab "WPFTab6BT"}
"WPFBackToTweaks" {Invoke-WPFTab "WPFTab2BT"}
"WPFInstallSelectedAppx" {Invoke-WPFAppxInstall}
"WPFRemoveSelectedAppx" {Invoke-WPFAppxRemoval} "WPFRemoveSelectedAppx" {Invoke-WPFAppxRemoval}
"WPFDefaultAppxSelection" {Invoke-WPFPresets "AppxDefault" -checkboxfilterpattern "WPFAppx*"} "WPFDefaultAppxSelection" {Invoke-WPFPresets "AppxDefault" -checkboxfilterpattern "WPFAppx*"}
"WPFSelectAllAppx" { "WPFSelectAllAppx" {
@@ -77,7 +74,7 @@ function Invoke-WPFButton {
$sync.configs.appxHashtable.Keys | ForEach-Object {$sync.$_.IsChecked = $false} $sync.configs.appxHashtable.Keys | ForEach-Object {$sync.$_.IsChecked = $false}
} }
"WPFGetInstalledAppx" { "WPFGetInstalledAppx" {
$installedAppxPackages = Get-WinUtilInstalledAPPX $installedAppxPackages = Get-AppxPackage -AllUsers | Select-Object -ExpandProperty Name
foreach ($appx in $sync.configs.appxHashtable.GetEnumerator()) { foreach ($appx in $sync.configs.appxHashtable.GetEnumerator()) {
if ($appx.Value.PackageId -in $installedAppxPackages) { if ($appx.Value.PackageId -in $installedAppxPackages) {
$sync.$($appx.Key).IsChecked = $true $sync.$($appx.Key).IsChecked = $true
@@ -86,13 +83,6 @@ function Invoke-WPFButton {
} }
"WPFCloseButton" {$sync.Form.Close(); Write-Host "Bye bye!"} "WPFCloseButton" {$sync.Form.Close(); Write-Host "Bye bye!"}
"WPFMinimizeButton" {$sync.Form.WindowState = [Windows.WindowState]::Minimized} "WPFMinimizeButton" {$sync.Form.WindowState = [Windows.WindowState]::Minimized}
"WPFMaximizeButton" {
if ($sync.Form.WindowState -eq [Windows.WindowState]::Normal) {
$sync.Form.WindowState = [Windows.WindowState]::Maximized
} else {
$sync.Form.WindowState = [Windows.WindowState]::Normal
}
}
"WPFselectedAppsButton" {$sync.selectedAppsPopup.IsOpen = -not $sync.selectedAppsPopup.IsOpen} "WPFselectedAppsButton" {$sync.selectedAppsPopup.IsOpen = -not $sync.selectedAppsPopup.IsOpen}
} }
} }
+27 -63
View File
@@ -1,5 +1,6 @@
function Invoke-WPFGetInstalled { function Invoke-WPFGetInstalled {
<# <#
TODO: Add the Option to use Chocolatey as Engine
.SYNOPSIS .SYNOPSIS
Invokes the function that gets the checkboxes to check in a new runspace Invokes the function that gets the checkboxes to check in a new runspace
@@ -18,72 +19,35 @@ function Invoke-WPFGetInstalled {
return return
} }
$managerPreference = $sync.preferences.packagemanager $managerPreference = $sync.preferences.packagemanager
$operation = [Hashtable]::Synchronized(@{
Checkboxes = @() Invoke-WPFRunspace -ParameterList @(("managerPreference", $managerPreference),("checkbox", $checkbox)) -ScriptBlock {
Error = $null param (
}) [string]$checkbox,
$completeAction = [Action[hashtable, string]]{ [string]$managerPreference
param(
[hashtable]$completedOperation,
[string]$completedCheckbox
) )
try { $sync.ProcessRunning = $true
if ($completedOperation.Error) { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" }
Write-WinUtilLog -Level "ERROR" -Component "Install" -Message "Get installed state failed: $($completedOperation.Error)"
Write-Warning "Unable to get installed state: $($completedOperation.Error)"
return
}
if ($completedCheckbox -eq "winget") { if ($checkbox -eq "winget") {
foreach ($checkboxName in $completedOperation.Checkboxes) { Write-Host "Getting Installed Programs..."
if (-not $sync.selectedApps.Contains($checkboxName)) { switch ($managerPreference) {
$sync.selectedApps.Add($checkboxName) "Choco"{$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox "choco"; break}
} "Winget"{$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox; break}
}
Reset-WPFCheckBoxes -checkboxfilterpattern "WPFInstall*"
} else {
foreach ($checkboxName in $completedOperation.Checkboxes) {
$sync.$checkboxName.ischecked = $True
}
}
} finally {
$sync.ProcessRunning = $false
Set-WinUtilTaskbaritem -state "None"
}
}
$sync.ProcessRunning = $true
Set-WinUtilTaskbaritem -state "Indeterminate"
try {
Invoke-WPFRunspace -ParameterList @(
("managerPreference", $managerPreference),
("checkbox", $checkbox),
("operation", $operation),
("completeAction", $completeAction)
) -ScriptBlock {
param (
[string]$checkbox,
[string]$managerPreference,
[hashtable]$operation,
[Action[hashtable, string]]$completeAction
)
try {
if ($checkbox -eq "winget") {
switch ($managerPreference) {
"Choco" { $operation.Checkboxes = @(Invoke-WinUtilCurrentSystem -CheckBox "choco"); break }
"Winget" { $operation.Checkboxes = @(Invoke-WinUtilCurrentSystem -CheckBox $checkbox); break }
}
} elseif ($checkbox -eq "tweaks") {
$operation.Checkboxes = @(Invoke-WinUtilCurrentSystem -CheckBox $checkbox)
}
} catch {
$operation.Error = $_.Exception.Message
} finally {
$sync.Form.Dispatcher.BeginInvoke($completeAction, [object[]]@($operation, $checkbox)) | Out-Null
} }
} }
} catch { elseif ($checkbox -eq "tweaks") {
$operation.Error = $_.Exception.Message Write-Host "Getting Installed Tweaks..."
$completeAction.Invoke($operation, $checkbox) $Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox
}
$sync.form.Dispatcher.invoke({
foreach ($checkbox in $Checkboxes) {
$sync.$checkbox.ischecked = $True
}
})
Write-Host "Done..."
$sync.ProcessRunning = $false
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" }
} }
} }
+6 -54
View File
@@ -31,81 +31,33 @@ function Invoke-WPFInstall {
$packagesWinget = $packagesSorted['Winget'] $packagesWinget = $packagesSorted['Winget']
$packagesChoco = $packagesSorted['Choco'] $packagesChoco = $packagesSorted['Choco']
$totalPackages = @($packagesWinget).Count + @($packagesChoco).Count
$completedPackages = 0
$hasUI = $null -ne $sync.Form -and $null -ne $sync.Form.Dispatcher
Write-WinUtilLog -Component "Install" -Message "Install package manager split: winget=$(@($packagesWinget).Count), choco=$(@($packagesChoco).Count)" Write-WinUtilLog -Component "Install" -Message "Install package manager split: winget=$(@($packagesWinget).Count), choco=$(@($packagesChoco).Count)"
try { try {
$sync.ProcessRunning = $true $sync.ProcessRunning = $true
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Preparing app install (0/$totalPackages)" -Percent 0
Invoke-WPFUIThread -ScriptBlock {
if ($null -ne $sync.ItemsControl) {
$sync.ItemsControl.IsEnabled = $false
}
}
}
if($packagesWinget.Count -gt 0 -and $packagesWinget -ne "0") { if($packagesWinget.Count -gt 0 -and $packagesWinget -ne "0") {
Show-WPFInstallAppBusy -text "Installing apps..."
Install-WinUtilWinget Install-WinUtilWinget
foreach ($program in $packagesWinget) { Install-WinUtilProgramWinget -Action Install -Programs $packagesWinget
$position = $completedPackages + 1
$startPercent = [int](($completedPackages / $totalPackages) * 100)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Installing $program ($position/$totalPackages)" -Percent $startPercent
}
Install-WinUtilProgramWinget -Action Install -Programs @($program)
$completedPackages++
$completedPercent = [int](($completedPackages / $totalPackages) * 100)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Installed $program ($completedPackages/$totalPackages)" -Percent $completedPercent
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($completedPercent / 100) }
}
}
} }
if($packagesChoco.Count -gt 0) { if($packagesChoco.Count -gt 0) {
$position = $completedPackages + 1
$startPercent = [int](($completedPackages / $totalPackages) * 100)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Installing Chocolatey packages ($position/$totalPackages)" -Percent $startPercent
}
Install-WinUtilChoco Install-WinUtilChoco
Install-WinUtilProgramChoco -Action Install -Programs $packagesChoco Install-WinUtilProgramChoco -Action Install -Programs $packagesChoco
$completedPackages += @($packagesChoco).Count
$completedPercent = [int](($completedPackages / $totalPackages) * 100)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Installed Chocolatey packages ($completedPackages/$totalPackages)" -Percent $completedPercent
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($completedPercent / 100) }
}
} }
Hide-WPFInstallAppBusy
Write-Host "===========================================" Write-Host "==========================================="
Write-Host "-- Installs have finished ---" Write-Host "-- Installs have finished ---"
Write-Host "===========================================" Write-Host "==========================================="
Write-WinUtilLog -Component "Install" -Message "Install workflow completed." Write-WinUtilLog -Component "Install" -Message "Install workflow completed."
if ($hasUI) { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "App install finished" -Percent 100
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
}
} catch { } catch {
Hide-WPFInstallAppBusy
Write-Host "===========================================" Write-Host "==========================================="
Write-Host "Error: $_" Write-Host "Error: $_"
Write-Host "===========================================" Write-Host "==========================================="
Write-WinUtilLog -Level "ERROR" -Component "Install" -Message "Install workflow failed: $($_.Exception.Message)" Write-WinUtilLog -Level "ERROR" -Component "Install" -Message "Install workflow failed: $($_.Exception.Message)"
if ($hasUI) { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" -overlay "warning" }
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "App install failed" -Percent 100
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" -overlay "warning" }
}
} finally { } finally {
if ($hasUI) {
Invoke-WPFUIThread -ScriptBlock {
if ($null -ne $sync.ItemsControl) {
$sync.ItemsControl.IsEnabled = $true
}
}
}
$sync.ProcessRunning = $False $sync.ProcessRunning = $False
} }
} }
+7 -45
View File
@@ -1,50 +1,12 @@
function Invoke-WPFOOSU { function Invoke-WPFOOSU {
if ($sync.ProcessRunning) { try {
Show-WinUtilMessage -Message "Another process is currently running." -Title "WinUtil" -Button "OK" -Icon "Warning" $ProgressPreference = 'SilentlyContinue'
return
}
$downloadPath = Join-Path $sync.winutildir "ooshutup10.exe" Invoke-WebRequest -Uri https://dl5.oo-software.com/files/ooshutup10/OOSU10.exe -OutFile "$winutildir\ooshutup10.exe"
$sync.ProcessRunning = $true Start-Process -FilePath "$winutildir\ooshutup10.exe"
Invoke-WPFRunspace -ParameterList @(,("downloadPath", $downloadPath)) -ScriptBlock { $ProgressPreference = 'Continue'
param($downloadPath) } catch {
Write-Error "Couldn't download O&O ShutUp10. Please make sure you have an active Internet connection."
$hasUI = $null -ne $sync.Form -and $null -ne $sync.Form.Dispatcher
try {
Write-WinUtilLog -Component "OOSU" -Message "Downloading O&O ShutUp10++."
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Downloading O&O ShutUp10++ (0%)" -Percent 0
}
Save-WinUtilFile -Uri "https://dl5.oo-software.com/files/ooshutup10/OOSU10.exe" -DestinationPath $downloadPath -ProgressCallback {
param($percent)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Downloading O&O ShutUp10++ ($percent%)" -Percent $percent
}
}
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Launching O&O ShutUp10++" -Percent 100
}
Start-Process -FilePath $downloadPath
Write-WinUtilLog -Component "OOSU" -Message "O&O ShutUp10++ launched."
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "O&O ShutUp10++ launched" -Percent 100
}
}
catch {
Write-WinUtilLog -Level "ERROR" -Component "OOSU" -Message "O&O ShutUp10++ download failed: $($_.Exception.Message)"
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "O&O ShutUp10++ download failed" -Percent 100
}
Write-Error "Couldn't download O&O ShutUp10. Please make sure you have an active Internet connection."
}
finally {
$sync.ProcessRunning = $false
}
} }
} }
+2 -3
View File
@@ -44,8 +44,6 @@ public sealed class WinUtilRunspaceCleanupState
public static class WinUtilRunspaceCleanup public static class WinUtilRunspaceCleanup
{ {
public static readonly System.Threading.WaitOrTimerCallback Callback = Cleanup;
public static void Cleanup(object state, bool timedOut) public static void Cleanup(object state, bool timedOut)
{ {
var cleanupState = state as WinUtilRunspaceCleanupState; var cleanupState = state as WinUtilRunspaceCleanupState;
@@ -91,7 +89,8 @@ public static class WinUtilRunspaceCleanup
$cleanupState = [WinUtilRunspaceCleanupState]::new() $cleanupState = [WinUtilRunspaceCleanupState]::new()
$cleanupState.PowerShell = $powershell $cleanupState.PowerShell = $powershell
$cleanupState.Handle = $handle $cleanupState.Handle = $handle
[System.Threading.ThreadPool]::RegisterWaitForSingleObject($handle.AsyncWaitHandle, [WinUtilRunspaceCleanup]::Callback, $cleanupState, -1, $true) | Out-Null $cleanupCallback = [System.Threading.WaitOrTimerCallback][WinUtilRunspaceCleanup]::Cleanup
[System.Threading.ThreadPool]::RegisterWaitForSingleObject($handle.AsyncWaitHandle, $cleanupCallback, $cleanupState, -1, $true) | Out-Null
# Return the handle # Return the handle
return $handle return $handle
@@ -7,21 +7,11 @@ function Invoke-WPFSelectedCheckboxesUpdate ($type, $checkboxName) {
'^WPFAppx' { 'selectedAppx' } '^WPFAppx' { 'selectedAppx' }
} }
$selectionChanged = $false
if ($type -eq "Add") { if ($type -eq "Add") {
if (-not $sync.$listName.Contains($checkboxName)) { if (-not $sync.$listName.Contains($checkboxName)) {
$sync.$listName.Add($checkboxName) $sync.$listName.Add($checkboxName)
$selectionChanged = $true
} }
} else { } else {
$selectionChanged = $sync.$listName.Remove($checkboxName) $sync.$listName.Remove($checkboxName)
}
if ($listName -eq "selectedApps" -and $selectionChanged) {
$sync.WPFselectedAppsButton.Content = "Selected Apps: $($sync.selectedApps.Count)"
$sync.selectedAppsstackPanel.Children.Clear()
$sync.selectedApps | Sort-Object | ForEach-Object {
Add-SelectedAppsMenuItem -name $sync.configs.applicationsHashtable.$_.Content -key $_
}
} }
} }
+2 -1
View File
@@ -19,12 +19,13 @@ function Invoke-WPFTab {
$tabNumber = [int]($ClickedTab -replace "WPFTab","" -replace "BT","") - 1 $tabNumber = [int]($ClickedTab -replace "WPFTab","" -replace "BT","") - 1
$filter = Get-WinUtilVariables -Type ToggleButton | Where-Object {$psitem -like "WPFTab?BT"} $filter = Get-WinUtilVariables -Type ToggleButton | Where-Object {$psitem -like "WPFTab?BT"}
$sync.$tabNav.Items[$tabNumber].IsSelected = $true
($sync.GetEnumerator()).where{$psitem.Key -in $filter} | ForEach-Object { ($sync.GetEnumerator()).where{$psitem.Key -in $filter} | ForEach-Object {
if ($ClickedTab -ne $PSItem.name) { if ($ClickedTab -ne $PSItem.name) {
$sync[$PSItem.Name].IsChecked = $false $sync[$PSItem.Name].IsChecked = $false
} else { } else {
$sync["$ClickedTab"].IsChecked = $true $sync["$ClickedTab"].IsChecked = $true
$tabNumber = [int]($ClickedTab-replace "WPFTab","" -replace "BT","") - 1
$sync.$tabNav.Items[$tabNumber].IsSelected = $true
} }
} }
$sync.currentTab = $sync.$tabNav.Items[$tabNumber].Header $sync.currentTab = $sync.$tabNav.Items[$tabNumber].Header
+2 -7
View File
@@ -404,16 +404,11 @@ function Invoke-WPFUIElements {
$textBlock.ToolTip = $entryInfo.Link $textBlock.ToolTip = $entryInfo.Link
$textBlock.Style = $HoverTextBlockStyle $textBlock.Style = $HoverTextBlockStyle
$textBlock.UseLayoutRounding = $true $textBlock.UseLayoutRounding = $true
$textBlock.VerticalAlignment = "Center" $textBlock.VerticalAlignment = "Center"
$textBlock.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize") $textBlock.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize")
$textBlock.Tag = $checkBox $textBlock.Tag = $checkBox
$textBlock.Add_MouseUp({
[System.Object]$Sender = $args[0]
Start-Process $Sender.ToolTip -ErrorAction Stop
})
$updateLinkMargin = { $updateLinkMargin = {
[System.Object]$Sender = $args[0] [System.Object]$Sender = $args[0]
$linkedCheckBox = $Sender.Tag $linkedCheckBox = $Sender.Tag
@@ -446,7 +441,7 @@ function Invoke-WPFUIElements {
$sync[$entryInfo.Name].Add_Unchecked({ $sync[$entryInfo.Name].Add_Unchecked({
[System.Object]$Sender = $args[0] [System.Object]$Sender = $args[0]
Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $Sender.name Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkbox $Sender.name
}) })
} }
} }
+6 -53
View File
@@ -42,21 +42,11 @@ function Invoke-WPFUnInstall {
$packagesWinget = $packagesSorted['Winget'] $packagesWinget = $packagesSorted['Winget']
$packagesChoco = $packagesSorted['Choco'] $packagesChoco = $packagesSorted['Choco']
$totalPackages = @($packagesWinget).Count + @($packagesChoco).Count
$completedPackages = 0
$hasUI = $null -ne $sync.Form -and $null -ne $sync.Form.Dispatcher
Write-WinUtilLog -Component "Uninstall" -Message "Uninstall package manager split: winget=$(@($packagesWinget).Count), choco=$(@($packagesChoco).Count)" Write-WinUtilLog -Component "Uninstall" -Message "Uninstall package manager split: winget=$(@($packagesWinget).Count), choco=$(@($packagesChoco).Count)"
try { try {
$sync.ProcessRunning = $true $sync.ProcessRunning = $true
if ($hasUI) { Show-WPFInstallAppBusy -text "Uninstalling apps..."
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Preparing app uninstall (0/$totalPackages)" -Percent 0
Invoke-WPFUIThread -ScriptBlock {
if ($null -ne $sync.ItemsControl) {
$sync.ItemsControl.IsEnabled = $false
}
}
}
if ($packagesWinget -contains "Microsoft.Edge") { if ($packagesWinget -contains "Microsoft.Edge") {
New-Item -Path "$Env:SystemRoot\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdge.exe" -Force New-Item -Path "$Env:SystemRoot\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdge.exe" -Force
@@ -64,62 +54,25 @@ function Invoke-WPFUnInstall {
# Uninstall all selected programs in new window # Uninstall all selected programs in new window
if($packagesWinget.Count -gt 0) { if($packagesWinget.Count -gt 0) {
foreach ($program in $packagesWinget) { Install-WinUtilProgramWinget -Action Uninstall -Programs $packagesWinget
$position = $completedPackages + 1
$startPercent = [int](($completedPackages / $totalPackages) * 100)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Uninstalling $program ($position/$totalPackages)" -Percent $startPercent
}
Install-WinUtilProgramWinget -Action Uninstall -Programs @($program)
$completedPackages++
$completedPercent = [int](($completedPackages / $totalPackages) * 100)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Uninstalled $program ($completedPackages/$totalPackages)" -Percent $completedPercent
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($completedPercent / 100) }
}
}
} }
if($packagesChoco.Count -gt 0) { if($packagesChoco.Count -gt 0) {
$position = $completedPackages + 1
$startPercent = [int](($completedPackages / $totalPackages) * 100)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Uninstalling Chocolatey packages ($position/$totalPackages)" -Percent $startPercent
}
Install-WinUtilProgramChoco -Action Uninstall -Programs $packagesChoco Install-WinUtilProgramChoco -Action Uninstall -Programs $packagesChoco
$completedPackages += @($packagesChoco).Count
$completedPercent = [int](($completedPackages / $totalPackages) * 100)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Uninstalled Chocolatey packages ($completedPackages/$totalPackages)" -Percent $completedPercent
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($completedPercent / 100) }
}
} }
Hide-WPFInstallAppBusy
Write-Host "===========================================" Write-Host "==========================================="
Write-Host "-- Uninstalls have finished ---" Write-Host "-- Uninstalls have finished ---"
Write-Host "===========================================" Write-Host "==========================================="
Write-WinUtilLog -Component "Uninstall" -Message "Uninstall workflow completed." Write-WinUtilLog -Component "Uninstall" -Message "Uninstall workflow completed."
if ($hasUI) { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "App uninstall finished" -Percent 100
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
}
} catch { } catch {
Hide-WPFInstallAppBusy
Write-Host "===========================================" Write-Host "==========================================="
Write-Host "Error: $_" Write-Host "Error: $_"
Write-Host "===========================================" Write-Host "==========================================="
Write-WinUtilLog -Level "ERROR" -Component "Uninstall" -Message "Uninstall workflow failed: $($_.Exception.Message)" Write-WinUtilLog -Level "ERROR" -Component "Uninstall" -Message "Uninstall workflow failed: $($_.Exception.Message)"
if ($hasUI) { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" -overlay "warning" }
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "App uninstall failed" -Percent 100
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" -overlay "warning" }
}
} finally { } finally {
if ($hasUI) {
Invoke-WPFUIThread -ScriptBlock {
if ($null -ne $sync.ItemsControl) {
$sync.ItemsControl.IsEnabled = $true
}
}
}
$sync.ProcessRunning = $False $sync.ProcessRunning = $False
} }
+22 -43
View File
@@ -5,51 +5,22 @@ function Invoke-WPFUpdatesdefault {
Resets Windows Update settings to default Resets Windows Update settings to default
#> #>
$ErrorActionPreference = 'SilentlyContinue'
Write-WinUtilLog -Component "Updates" -Message "Resetting Windows Update settings to default." Write-WinUtilLog -Component "Updates" -Message "Resetting Windows Update settings to default."
Write-Host "Removing Windows Update settings managed by WinUtil..." -ForegroundColor Green Write-Host "Removing Windows Update policy settings..." -ForegroundColor Green
Write-WinUtilLog -Component "Updates" -Message "Removing Windows Update registry values managed by WinUtil." Write-WinUtilLog -Component "Updates" -Message "Removing Windows Update policy registry paths."
$registryValues = @( Remove-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Recurse -Force
@{ Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization" -Recurse -Force
Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Recurse -Force
Names = @("NoAutoUpdate", "AUOptions", "NoAutoRebootWithLoggedOnUsers", "AUPowerManagement") Remove-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" -Recurse -Force
}, Remove-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Recurse -Force
@{ Remove-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Recurse -Force
Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
Names = @("ExcludeWUDriversInQualityUpdate", "DeferFeatureUpdates", "DeferFeatureUpdatesPeriodInDays", "DeferQualityUpdates", "DeferQualityUpdatesPeriodInDays")
},
@{
Path = "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings"
Names = @("BranchReadinessLevel", "DeferFeatureUpdatesPeriodInDays", "DeferQualityUpdatesPeriodInDays")
},
@{
Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata"
Names = @("PreventDeviceMetadataFromNetwork")
},
@{
Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching"
Names = @("DontPromptForWindowsUpdate", "DontSearchWindowsUpdate", "DriverUpdateWizardWuSearchEnabled")
},
@{
Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config"
Names = @("DODownloadMode")
}
)
foreach ($registryEntry in $registryValues) { Write-Host "Showing Windows Updates in settings..."
foreach ($valueName in $registryEntry.Names) { Write-WinUtilLog -Component "Updates" -Message "Showing Windows Update settings page."
Remove-ItemProperty -Path $registryEntry.Path -Name $valueName -ErrorAction SilentlyContinue Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name SettingsPageVisibility
}
}
$explorerPolicyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"
$settingsPageVisibility = (Get-ItemProperty -Path $explorerPolicyPath -Name "SettingsPageVisibility" -ErrorAction SilentlyContinue).SettingsPageVisibility
if ($settingsPageVisibility -eq "hide:windowsupdate") {
Write-Host "Removing WinUtil's legacy Windows Update page restriction..."
Write-WinUtilLog -Component "Updates" -Message "Removing the legacy Windows Update settings page restriction."
Remove-ItemProperty -Path $explorerPolicyPath -Name "SettingsPageVisibility" -ErrorAction SilentlyContinue
}
Write-Host "Reenabling Windows Update Services..." -ForegroundColor Green Write-Host "Reenabling Windows Update Services..." -ForegroundColor Green
Write-WinUtilLog -Component "Updates" -Message "Restoring Windows Update service startup types." Write-WinUtilLog -Component "Updates" -Message "Restoring Windows Update service startup types."
@@ -64,8 +35,12 @@ function Invoke-WPFUpdatesdefault {
Write-Host "Restored UsoSvc to Automatic." Write-Host "Restored UsoSvc to Automatic."
Write-WinUtilLog -Component "Updates" -Message "Starting UsoSvc service and restoring startup type to Automatic." Write-WinUtilLog -Component "Updates" -Message "Starting UsoSvc service and restoring startup type to Automatic."
Set-Service -Name UsoSvc -StartupType Automatic
Start-Service -Name UsoSvc Start-Service -Name UsoSvc
Set-Service -Name UsoSvc -StartupType Automatic
Write-Host "Restored WaaSMedicSvc to Manual."
Write-WinUtilLog -Component "Updates" -Message "Restoring WaaSMedicSvc service to Manual."
Set-Service -Name WaaSMedicSvc -StartupType Manual
Write-Host "Enabling update related scheduled tasks..." -ForegroundColor Green Write-Host "Enabling update related scheduled tasks..." -ForegroundColor Green
Write-WinUtilLog -Component "Updates" -Message "Enabling update related scheduled tasks." Write-WinUtilLog -Component "Updates" -Message "Enabling update related scheduled tasks."
@@ -79,9 +54,13 @@ function Invoke-WPFUpdatesdefault {
'\Microsoft\WindowsUpdate\*' '\Microsoft\WindowsUpdate\*'
foreach ($Task in $Tasks) { foreach ($Task in $Tasks) {
Get-ScheduledTask -TaskPath $Task -ErrorAction SilentlyContinue | Enable-ScheduledTask -ErrorAction SilentlyContinue Get-ScheduledTask -TaskPath $Task | Enable-ScheduledTask -ErrorAction SilentlyContinue
} }
Write-Host "Windows Local Policies Reset to Default."
Write-WinUtilLog -Component "Updates" -Message "Resetting local security policy to defaults with secedit."
secedit /configure /cfg "$Env:SystemRoot\inf\defltbase.inf" /db defltbase.sdb
Write-Host "===================================================" -ForegroundColor Green Write-Host "===================================================" -ForegroundColor Green
Write-Host "--- Windows Update Settings Reset to Default ---" -ForegroundColor Green Write-Host "--- Windows Update Settings Reset to Default ---" -ForegroundColor Green
Write-Host "===================================================" -ForegroundColor Green Write-Host "===================================================" -ForegroundColor Green
+20 -20
View File
@@ -8,17 +8,7 @@ function Invoke-WPFUpdatesdisable {
Disabling Windows Update is not recommended. This is only for advanced users who know what they are doing. Disabling Windows Update is not recommended. This is only for advanced users who know what they are doing.
#> #>
$confirmation = Show-WinUtilMessage ` $ErrorActionPreference = 'SilentlyContinue'
-Message "Disabling Windows Update stops update services, disables scheduled tasks, and clears downloaded update files. Security updates will not be installed until defaults are restored. Continue?" `
-Title "Disable Windows Update?" `
-Button "YesNo" `
-Icon "Warning"
if ($confirmation -ne "Yes") {
Write-WinUtilLog -Component "Updates" -Message "Windows Update disable workflow cancelled."
return
}
Write-WinUtilLog -Component "Updates" -Message "Disabling Windows Update settings." Write-WinUtilLog -Component "Updates" -Message "Disabling Windows Update settings."
Write-Host "Configuring registry settings..." -ForegroundColor Yellow Write-Host "Configuring registry settings..." -ForegroundColor Yellow
@@ -31,14 +21,24 @@ function Invoke-WPFUpdatesdisable {
New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config" -Force New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config" -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config" -Name "DODownloadMode" -Type DWord -Value 0 Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config" -Name "DODownloadMode" -Type DWord -Value 0
foreach ($serviceName in @("BITS", "wuauserv", "UsoSvc")) { Write-Host "Hiding Windows Updates from settings..."
Write-Host "Stopping and disabling $serviceName service." Write-WinUtilLog -Component "Updates" -Message "Hiding Windows Update settings page."
Write-WinUtilLog -Component "Updates" -Message "Stopping and disabling $serviceName service." Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name SettingsPageVisibility -Value hide:windowsupdate
Stop-Service -Name $serviceName -Force -ErrorAction SilentlyContinue
Set-Service -Name $serviceName -StartupType Disabled
}
Remove-Item -Path "C:\Windows\SoftwareDistribution\*" -Recurse -Force -ErrorAction SilentlyContinue Write-Host "Disabled BITS Service."
Write-WinUtilLog -Component "Updates" -Message "Disabling BITS service."
Set-Service -Name BITS -StartupType Disabled
Write-Host "Disabled wuauserv Service."
Write-WinUtilLog -Component "Updates" -Message "Disabling wuauserv service."
Set-Service -Name wuauserv -StartupType Disabled
Write-Host "Disabled UsoSvc Service."
Write-WinUtilLog -Component "Updates" -Message "Stopping and disabling UsoSvc service."
Stop-Service -Name UsoSvc -Force
Set-Service -Name UsoSvc -StartupType Disabled
Remove-Item "C:\Windows\SoftwareDistribution\*" -Recurse -Force
Write-Host "Cleared SoftwareDistribution folder." Write-Host "Cleared SoftwareDistribution folder."
Write-WinUtilLog -Component "Updates" -Message "Cleared SoftwareDistribution folder." Write-WinUtilLog -Component "Updates" -Message "Cleared SoftwareDistribution folder."
@@ -54,11 +54,11 @@ function Invoke-WPFUpdatesdisable {
'\Microsoft\WindowsUpdate\*' '\Microsoft\WindowsUpdate\*'
foreach ($Task in $Tasks) { foreach ($Task in $Tasks) {
Get-ScheduledTask -TaskPath $Task -ErrorAction SilentlyContinue | Disable-ScheduledTask -ErrorAction SilentlyContinue Get-ScheduledTask -TaskPath $Task | Disable-ScheduledTask -ErrorAction SilentlyContinue
} }
Write-Host "=================================" -ForegroundColor Green Write-Host "=================================" -ForegroundColor Green
Write-Host "--- Windows Update Is Disabled ---" -ForegroundColor Green Write-Host "--- Updates Are Disabled ---" -ForegroundColor Green
Write-Host "=================================" -ForegroundColor Green Write-Host "=================================" -ForegroundColor Green
Write-Host "Note: You must restart your system in order for all changes to take effect." -ForegroundColor Yellow Write-Host "Note: You must restart your system in order for all changes to take effect." -ForegroundColor Yellow

Some files were not shown because too many files have changed in this diff Show More