Compare commits

...

52 Commits

Author SHA1 Message Date
a55a44a54c Color the Description in the Update tab where the text was talking the blue and didn't had it own color. Fixed some color contrast issue (#2722) 2024-09-12 09:53:43 -05:00
9c0b0b8913 format update 2024-09-12 09:49:06 -05:00
7fe0f9a163 Fix the way arguments are passed to the runspace (#2720)
* Fix the way arguments are passed to the runspace

* Add $handle return

* Fix Choco Install logic
2024-09-12 09:45:54 -05:00
8e5fcceddb fix "ToLower" method invocation failure (#2714) 2024-09-11 09:20:25 -05:00
19a3c7070a Update release-drafter.yml 2024-09-10 18:12:21 -05:00
343a72f528 Update pre-release.yaml 2024-09-10 18:02:42 -05:00
0b13ca4b11 update release 2024-09-10 18:01:18 -05:00
215de06a58 Update release-drafter.yml 2024-09-10 17:11:38 -05:00
80555d945e Update release-drafter.yml 2024-09-10 17:05:13 -05:00
Rux
314588283a Add -Force flag for proper Hidden File detection in Invoke-Preprocessing.ps1 (#2700)
* Update Invoke-Preprocessing.ps1

- Added `-Force` argument to Get-ChildItem functions at lines 80 and 90.

* Update Invoke-Preprocessing.ps1

- Make changes to new Compile.ps1 file.
2024-09-10 14:28:59 -05:00
Rux
00668755c9 Modify Compile.ps1 Handling of Xaml to Improve Maintainability (#2701) 2024-09-10 14:24:53 -05:00
d3ef94f175 Update windev.ps1 2024-09-10 14:18:51 -05:00
1ac24c236e CTT Powershell Profile (#2707)
* add main logic

* finish logic
2024-09-10 14:05:55 -05:00
ff363d686f Fix/Refactor windev Admin Elevation (#2683)
* Revert Admin Elevation

* Unify logic to reuse the same urls whether the script is started as admin or not
2024-09-10 14:03:49 -05:00
9abe11c975 Fix Theming 2024-09-10 14:01:07 -05:00
14d20cd161 Choco Logic Refactor and Add Checkbox to prefer Chocolatey over Winget (#2596)
* First Selector and Logic

* Extend Functionality

* Switch to PreferChocolatey Checkbox

* Persist Choco Preference across program restarts

* Change Logging, Fix interactivity and optimize uninstall

* Implement "Get-Installed" (quick-and-dirty)

* Code Formatting

* Rename File/Function, Refactor Choco Install, Add Status Indicator

* Add documentation

---------

Co-authored-by: Chris Titus <contact@christitus.com>
2024-09-10 13:02:22 -05:00
2b9b1b026c Deploying to main from @ ChrisTitusTech/winutil@e9a45a002f 🚀 2024-09-10 15:31:59 +00:00
e9a45a002f Update applications.json (#2703)
Correct for winget Google.GoogleDrive
2024-09-09 20:27:57 -05:00
Nyx
6d996495a3 Reduce redundancy (#2686) 2024-09-09 20:25:19 -05:00
473f04ddc5 [fix compile] winutil used by another process (#2680)
* fix winutil used by another process

- remove winutil.ps1 if it is readonly (also works if another process is using it) to minimize failed compiles.

* fix action error

* Oops, typo

* make it more compact
2024-09-09 20:21:50 -05:00
95db85f791 [MicroWin] Don't disable already disabled features (#2675) 2024-09-09 20:20:55 -05:00
5059b93cd7 Better Image handling (#2665)
* enhance asset mgmt

- invoke ico directly
- invoke ico only at shortcut creation
- remove "ConvertTo-Icon" Function file

- removed image from xaml
- added stackpanel to xaml
- added functions to create viewbox with image
- added logic to add image via code to xaml & customdialog
- changed title color for customdialog

- remove webinvokes for assets from main.ps1

TODO: convert images into bitmap base64 string & add them directly into invoke-WinUtiltaskbaritem.ps1

* improve viewboxfunction

- add logo + checkmark + warning
- add params
- render on param "render"
- custom dialog logo function call fix
- main logo function call fix
- update winutiltaskbaritem to use new images

* fix sizing

- warning & checkmark sizing fix
- remove unneded comments

* fixes

- remove unneeded redundancy of "$canvas = New-Object Windows.Controls.Canvas"
- adjust empty lines
- use LimeGreen instead of Green

* fix layouting

* fixes

- use correct ctt blue color #0567ff
- remove unneeded comments
- rename Logoview to assets

* performance improvement

instead of rendering the image another time on each item switch, it caches it at the start and uses the render afterwards

* redo gray part of winutil logo

* correct gray shade

* fix coloring

* ise ico if available

---------

Co-authored-by: Chris Titus <contact@christitus.com>
2024-09-09 20:19:34 -05:00
380e1e73a6 Fix (?) button opening the link twice (#2664) 2024-09-09 20:15:13 -05:00
ad37371492 Add Legacy Print Panel (#2659)
* add legacy print panel

* fix documentation

- run generator
- add link to button
- add documentation for printer
- update table of contents

* fix spelling
2024-09-09 20:14:22 -05:00
1bfd8bddcc Simplify WinUtil Directory Creation in 'main.ps1' script by using C# 'CreateDirectory' Method which checks and creates the provided Directory Path (#2654) 2024-09-09 20:13:32 -05:00
6ad31edef1 Fix syntax error 2024-09-09 20:10:41 -05:00
c1009c3d7c Improve preprocessor (#2579)
* Update documentation for 'Invoke-Preprocessing' Script Tool

* Improve Compile Script a bit Deduplicating a lot of un-needed pre-fixes - Improve implementation for 'Invoke-Preprocessing' Script Tool

* Fix RegEx in 'Invoke-Preprocessing' Script Tool

* Result of Preprocessing

* Update Replace Regex for Code Formatting in 'Invoke-Preprocessing' Script Tool

* Result of Preprocessing

* Update Exclude Files List for Preprocessing in 'Compile.ps1' Script

* Remove Extra Whitespace in some place for 'Invoke-Preprocessing.ps1' Script Tool

* Simplified and Improved the Exclude List Validation Step in 'Invoke-Preprocessing.ps1' Script Tool

* Restore 'workingdir' variable when using '-Run' Parameter with 'Compile.ps1' Script

* Revert "Update Exclude Files List for Preprocessing in 'Compile.ps1' Script"

This reverts commit 674ab0308b.

* Result of Preprocessing
2024-09-09 20:05:10 -05:00
885108df7e Ultimate Performance via GUID rather than name (#2556)
* Ultimate Performance via GUID, not name

* Another way to extract the GUID to remove the French part code
2024-09-09 20:02:55 -05:00
b21bc35443 Bump release-drafter/release-drafter from 5 to 6 (#2666)
Bumps [release-drafter/release-drafter](https://github.com/release-drafter/release-drafter) from 5 to 6.
- [Release notes](https://github.com/release-drafter/release-drafter/releases)
- [Commits](https://github.com/release-drafter/release-drafter/compare/v5...v6)

---
updated-dependencies:
- dependency-name: release-drafter/release-drafter
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-09 20:01:48 -05:00
e2d539048d Deploying to main from @ ChrisTitusTech/winutil@588008612d 🚀 2024-09-07 15:31:02 +00:00
588008612d Deploying to main from @ ChrisTitusTech/winutil@859a733740 🚀 2024-09-06 15:33:05 +00:00
859a733740 add labels to issue templates (#2660)
- added "bug" to bug template
- added "enhancement" to feature request template
2024-09-04 16:38:46 -05:00
3bb1881254 update microwin wiki link (#2670)
- update wiki link to docs link
- change write error to write host for this message, bc write-host has "more support" for links, the color stays red
2024-09-04 16:33:40 -05:00
8b37420eec Add implicit string conversion to $flattenedJson in Invoke-WPFImpex.ps1 (#2658) 2024-09-02 18:32:22 -05:00
af7528a60b Deploying to main from @ ChrisTitusTech/winutil@0c6b2adb91 🚀 2024-09-02 15:31:29 +00:00
0c6b2adb91 Deploying to main from @ ChrisTitusTech/winutil@0635145896 🚀 2024-09-01 15:30:54 +00:00
0635145896 Deploying to main from @ ChrisTitusTech/winutil@2d751f4e8c 🚀 2024-08-31 15:32:17 +00:00
2d751f4e8c Fixes, improvements + Auto Window handling (#2648)
* fixes

- change fontsize back to 12
- add correct handling of windows
- removed double click handling of winutil

* readd double click

* fixes

- argument passing on elevation & to windev script
- remove shell output of log

* improve compile -run

- added $args param for args that get passed to winutil
- improved starting new Shell logic

* fix: compile's run logic

- removed old logic
- fixed command to run in new shell
- replaced $args with $arg

* fix: logs & border

- move log start to after admin elevation
- fix color of border on fixed tweaks button.

* fix: MicrowinInjectDrivers's Margin

- use theme value instead of custom value

* change microwin checkbox margin

- set cutom microwin checkbox margin due to cut off content

* fix layouting of nav bar

- replace strange collumndefinition to fix bugs, make sense and look better

* rename $arg to $Arguments

* change maxresolution from 1380 to 1280
2024-08-30 12:46:00 -05:00
9b9d0c58f5 Deploying to main from @ ChrisTitusTech/winutil@531cb4c63c 🚀 2024-08-30 15:31:11 +00:00
531cb4c63c Update LICENSE 2024-08-30 09:48:21 -05:00
42bda0dc47 clean home 2024-08-30 09:44:57 -05:00
3414a3eee1 LICENSE fix 2024-08-30 09:41:00 -05:00
a4302742b3 Create CODE_OF_CONDUCT.md 2024-08-30 09:40:15 -05:00
2a0d121cf0 [MicroWin] Add error details and messages (#2647) 2024-08-30 09:30:21 -05:00
a397f20ac6 improve impex (#2649)
- copy execution command to clipboard
- add tooltips to import & export menu items
2024-08-30 09:29:23 -05:00
bddf57bcee Hot Fix for clear button in Tweaks Section (#2645)
Patches changes related to PR #2608
2024-08-30 09:28:23 -05:00
2b3f1a811d Update pre-release.yaml 2024-08-29 22:47:18 -05:00
2af864f7ab update release notes 2024-08-29 22:42:41 -05:00
2b8592a50a Update pre-release.yaml 2024-08-29 22:05:18 -05:00
aad0356c28 Update pre-release.yaml 2024-08-29 21:59:12 -05:00
01515db90f Update pre-release.yaml 2024-08-29 21:48:09 -05:00
2ba5572b6c Update pre-release.yaml 2024-08-29 21:40:45 -05:00
48 changed files with 1414 additions and 752 deletions

128
.github/CODE_OF_CONDUCT.md vendored Normal file
View File

@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
contact@christitus.com.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@ -2,7 +2,7 @@
name: Bug report name: Bug report
about: Create a report to help us improve about: Create a report to help us improve
title: '' title: ''
labels: '' labels: 'bug'
assignees: '' assignees: ''
--- ---

View File

@ -2,7 +2,7 @@
name: Feature request name: Feature request
about: Suggest an idea for this project about: Suggest an idea for this project
title: '' title: ''
labels: '' labels: 'enhancement'
assignees: '' assignees: ''
--- ---

View File

@ -1,10 +1,5 @@
# Pull Request
<!--Before you make this PR have you followed the docs here? - https://christitustech.github.io/winutil/contribute/ --> <!--Before you make this PR have you followed the docs here? - https://christitustech.github.io/winutil/contribute/ -->
## Title
<!--[Provide a succinct and descriptive title for the pull request.]-->
## Type of Change ## Type of Change
- [ ] New feature - [ ] New feature
- [ ] Bug fix - [ ] Bug fix

View File

@ -1,6 +1,4 @@
name-template: '$RESOLVED_VERSION' tag-prefix: ''
tag-template: '$RESOLVED_VERSION'
tag-prefix: ""
categories: categories:
- title: '🚀 Features' - title: '🚀 Features'
labels: labels:
@ -11,8 +9,10 @@ categories:
- 'fix' - 'fix'
- 'bugfix' - 'bugfix'
- 'bug' - 'bug'
- title: '🧰 Maintenance' - title: '📚 Documentation'
label: 'chore' label: 'documentation'
- title: '🔒 Security'
label: 'security'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)' change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
template: | template: |
## Changes ## Changes
@ -22,3 +22,37 @@ template: |
## Contributors ## Contributors
$CONTRIBUTORS $CONTRIBUTORS
change-title-escapes: '\<*_&"'''
autolabeler:
- label: 'documentation'
files:
- '*.md'
branch:
- '/docs{0,1}\/.+/'
- label: 'bug'
branch:
- '/fix\/.+/'
title:
- '/fix/i'
- label: 'enhancement'
branch:
- '/feature\/.+/'
body:
- '/[A-Z]+-[0-9]+/'
- label: 'documentation'
files:
- '**/*.md'
- 'docs/**/*'
- label: 'security'
branch:
- '/security\/.+/'
replacers:
- search: /"/g
replace: ''
- search: /'/g
replace: ''
exclude-labels:
- 'skip-changelog'
filter-by-commitish: true

View File

@ -74,48 +74,23 @@ jobs:
name: winutil name: winutil
path: ./winutil.ps1 path: ./winutil.ps1
- name: Get latest release tag
id: get_latest_release
run: |
git fetch --tags --force
$latestTag = git for-each-ref --sort=-creatordate --format '%(refname:short)' refs/tags --count 1
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrEmpty($latestTag)) {
Write-Error "Failed to get latest tag. Error code: $LASTEXITCODE"
exit 1
}
Write-Host "Latest tag: $latestTag"
echo "LATEST_TAG=$latestTag" >> $env:GITHUB_ENV
shell: pwsh
- name: Generate Release Notes - name: Generate Release Notes
id: generate_notes id: generate_notes
uses: release-drafter/release-drafter@v5 uses: release-drafter/release-drafter@v6
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
config-name: release-drafter.yml config-name: release-drafter.yml
version: ${{ env.version }} version: ${{ env.VERSION }} # Pass the version variable
tag: ${{ env.LATEST_TAG }}
- name: Prepare Release Body
id: prepare_body
run: |
$newChanges = @'
${{ steps.generate_notes.outputs.body }}
'@
$formattedChanges = "Changes since ${{ env.LATEST_TAG }}:`n`n$newChanges"
$encodedChanges = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($formattedChanges))
echo "body=$encodedChanges" >> $env:GITHUB_OUTPUT
shell: pwsh
- name: Create and Upload Release - name: Create and Upload Release
id: create_release id: create_release
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
with: with:
tag_name: ${{ env.version }} tag_name: ${{ env.VERSION }}
name: Pre-Release ${{ env.version }} name: Pre-Release ${{ env.VERSION }}
body: | body: |
${{ '{{' }} fromJson(format('"{0}"', steps.prepare_body.outputs.body)) | base64decode {{ '}}' }} ${{ 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

View File

@ -1,12 +1,21 @@
param ( param (
[switch]$Debug, [switch]$Debug,
[switch]$Run, [switch]$Run,
[switch]$SkipPreprocessing [switch]$SkipPreprocessing,
[string]$Arguments
) )
if ((Get-Item ".\winutil.ps1" -ErrorAction SilentlyContinue).IsReadOnly) {
Remove-Item ".\winutil.ps1" -Force
}
$OFS = "`r`n" $OFS = "`r`n"
$scriptname = "winutil.ps1" $scriptname = "winutil.ps1"
$workingdir = $PSScriptRoot $workingdir = $PSScriptRoot
Push-Location
Set-Location $workingdir
# Variable to sync between runspaces # Variable to sync between runspaces
$sync = [Hashtable]::Synchronized(@{}) $sync = [Hashtable]::Synchronized(@{})
$sync.PSScriptRoot = $workingdir $sync.PSScriptRoot = $workingdir
@ -41,11 +50,11 @@ if (-NOT $SkipPreprocessing) {
# Dot source the 'Invoke-Preprocessing' Function from 'tools/Invoke-Preprocessing.ps1' Script # Dot source the 'Invoke-Preprocessing' Function from 'tools/Invoke-Preprocessing.ps1' Script
$preprocessingFilePath = ".\tools\Invoke-Preprocessing.ps1" $preprocessingFilePath = ".\tools\Invoke-Preprocessing.ps1"
. "$(($workingdir -replace ('\\$', '')) + '\' + ($preprocessingFilePath -replace ('\.\\', '')))" . $preprocessingFilePath
$excludedFiles = @('.\.git\', '.\.gitignore', '.\.gitattributes', '.\.github\CODEOWNERS', '.\LICENSE', "$preprocessingFilePath", '*.png', '*.exe') $excludedFiles = @('.\.git\', '.\.gitignore', '.\.gitattributes', '.\.github\CODEOWNERS', '.\LICENSE', "$preprocessingFilePath", '*.png', '*.exe')
$msg = "Pre-req: Code Formatting" $msg = "Pre-req: Code Formatting"
Invoke-Preprocessing -WorkingDir "$workingdir" -ExcludedFiles $excludedFiles -ProgressStatusMessage $msg Invoke-Preprocessing -WorkingDir "$workingdir" -ExcludedFiles $excludedFiles -ProgressStatusMessage $msg -ThrowExceptionOnEmptyFilesList
} }
# Create the script in memory. # Create the script in memory.
@ -56,14 +65,14 @@ Update-Progress "Adding: Header" 5
$script_content.Add($header) $script_content.Add($header)
Update-Progress "Adding: Version" 10 Update-Progress "Adding: Version" 10
$script_content.Add($(Get-Content "$workingdir\scripts\start.ps1").replace('#{replaceme}',"$(Get-Date -Format yy.MM.dd)")) $script_content.Add($(Get-Content "scripts\start.ps1").replace('#{replaceme}',"$(Get-Date -Format yy.MM.dd)"))
Update-Progress "Adding: Functions" 20 Update-Progress "Adding: Functions" 20
Get-ChildItem "$workingdir\functions" -Recurse -File | ForEach-Object { Get-ChildItem "functions" -Recurse -File | ForEach-Object {
$script_content.Add($(Get-Content $psitem.FullName)) $script_content.Add($(Get-Content $psitem.FullName))
} }
Update-Progress "Adding: Config *.json" 40 Update-Progress "Adding: Config *.json" 40
Get-ChildItem "$workingdir\config" | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object { Get-ChildItem "config" | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object {
$json = (Get-Content $psitem.FullName).replace("'","''") $json = (Get-Content $psitem.FullName).replace("'","''")
$jsonAsObject = $json | convertfrom-json $jsonAsObject = $json | convertfrom-json
@ -84,44 +93,52 @@ Get-ChildItem "$workingdir\config" | Where-Object {$psitem.extension -eq ".json"
$script_content.Add($(Write-output "`$sync.configs.$($psitem.BaseName) = '$json' `| convertfrom-json" )) $script_content.Add($(Write-output "`$sync.configs.$($psitem.BaseName) = '$json' `| convertfrom-json" ))
} }
$xaml = (Get-Content "$workingdir\xaml\inputXML.xaml").replace("'","''") # Read the entire XAML file as a single string, preserving line breaks
$xaml = Get-Content "$workingdir\xaml\inputXML.xaml" -Raw
Update-Progress "Adding: Xaml " 90 Update-Progress "Adding: Xaml " 90
$script_content.Add($(Write-output "`$inputXML = '$xaml'")) # Add the XAML content to $script_content using a here-string
$script_content.Add(@"
`$inputXML = @'
$xaml
'@
"@)
$script_content.Add($(Get-Content "$workingdir\scripts\main.ps1")) $script_content.Add($(Get-Content "scripts\main.ps1"))
if ($Debug) { if ($Debug) {
Update-Progress "Writing debug files" 95 Update-Progress "Writing debug files" 95
$appXamlContent | Out-File -FilePath "$workingdir\xaml\inputApp.xaml" -Encoding ascii $appXamlContent | Out-File -FilePath "xaml\inputApp.xaml" -Encoding ascii
$tweaksXamlContent | Out-File -FilePath "$workingdir\xaml\inputTweaks.xaml" -Encoding ascii $tweaksXamlContent | Out-File -FilePath "xaml\inputTweaks.xaml" -Encoding ascii
$featuresXamlContent | Out-File -FilePath "$workingdir\xaml\inputFeatures.xaml" -Encoding ascii $featuresXamlContent | Out-File -FilePath "xaml\inputFeatures.xaml" -Encoding ascii
} else { } else {
Update-Progress "Removing temporary files" 99 Update-Progress "Removing temporary files" 99
Remove-Item "$workingdir\xaml\inputApp.xaml" -ErrorAction SilentlyContinue Remove-Item "xaml\inputApp.xaml" -ErrorAction SilentlyContinue
Remove-Item "$workingdir\xaml\inputTweaks.xaml" -ErrorAction SilentlyContinue Remove-Item "xaml\inputTweaks.xaml" -ErrorAction SilentlyContinue
Remove-Item "$workingdir\xaml\inputFeatures.xaml" -ErrorAction SilentlyContinue Remove-Item "xaml\inputFeatures.xaml" -ErrorAction SilentlyContinue
} }
Set-Content -Path "$workingdir\$scriptname" -Value ($script_content -join "`r`n") -Encoding ascii Set-Content -Path "$scriptname" -Value ($script_content -join "`r`n") -Encoding ascii
Write-Progress -Activity "Compiling" -Completed Write-Progress -Activity "Compiling" -Completed
Update-Progress -Activity "Validating" -StatusMessage "Checking winutil.ps1 Syntax" -Percent 0 Update-Progress -Activity "Validating" -StatusMessage "Checking winutil.ps1 Syntax" -Percent 0
try { try {
$null = Get-Command -Syntax .\winutil.ps1 $null = Get-Command -Syntax .\winutil.ps1
} } catch {
catch {
Write-Warning "Syntax Validation for 'winutil.ps1' has failed" Write-Warning "Syntax Validation for 'winutil.ps1' has failed"
Write-Host "$($Error[0])" -ForegroundColor Red Write-Host "$($Error[0])" -ForegroundColor Red
} }
Write-Progress -Activity "Validating" -Completed Write-Progress -Activity "Validating" -Completed
if ($run) { if ($run) {
try { $script = "& '$workingdir\$scriptname' $Arguments"
Start-Process -FilePath "pwsh" -ArgumentList "$workingdir\$scriptname"
} catch {
Start-Process -FilePath "powershell" -ArgumentList "$workingdir\$scriptname"
}
$powershellcmd = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" }
$processCmd = if (Get-Command wt.exe -ErrorAction SilentlyContinue) { "wt.exe" } else { $powershellcmd }
Start-Process $processCmd -ArgumentList "$powershellcmd -NoProfile -Command $script"
break
} }
Pop-Location

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2022 Chris Titus Copyright (c) 2022 CT Tech Group LLC
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

File diff suppressed because one or more lines are too long

View File

@ -797,7 +797,7 @@
"content": "Google Drive", "content": "Google Drive",
"description": "File syncing across devices all tied to your google account", "description": "File syncing across devices all tied to your google account",
"link": "https://www.google.com/drive/", "link": "https://www.google.com/drive/",
"winget": "Google.Drive" "winget": "Google.GoogleDrive"
}, },
"gpuz": { "gpuz": {
"category": "Utilities", "category": "Utilities",

View File

@ -293,7 +293,7 @@
<Extensions xmlns="https://schneegans.de/windows/unattend-generator/"> <Extensions xmlns="https://schneegans.de/windows/unattend-generator/">
<ExtractScript> <ExtractScript>
param( param(
[xml] $Document [xml]$Document
); );
$scriptsDir = 'C:\Windows\Setup\Scripts\'; $scriptsDir = 'C:\Windows\Setup\Scripts\';

View File

@ -282,6 +282,14 @@
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/sound" "link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/sound"
}, },
"WPFPanelprinter": {
"Content": "Printer Panel",
"category": "Legacy Windows Panels",
"panel": "2",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/printer"
},
"WPFPanelsystem": { "WPFPanelsystem": {
"Content": "System Properties", "Content": "System Properties",
"category": "Legacy Windows Panels", "category": "Legacy Windows Panels",
@ -297,5 +305,13 @@
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/user" "link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/user"
},
"WPFWinUtilPSProfile": {
"Content": "Install CTT PowerShell Profile",
"category": "Powershell Profile",
"panel": "2",
"Order": "a083_",
"Type": "Button",
"ButtonWidth": "300"
} }
} }

View File

@ -1,169 +1,169 @@
{ {
"_default": { "_default": {
"CustomDialogFontSize": "12", "CustomDialogFontSize": "12",
"CustomDialogFontSizeHeader": "14", "CustomDialogFontSizeHeader": "14",
"CustomDialogIconSize": "25", "CustomDialogIconSize": "25",
"CustomDialogWidth": "400", "CustomDialogWidth": "400",
"CustomDialogHeight": "200", "CustomDialogHeight": "200",
"FontSize": "14", "FontSize": "12",
"FontFamily": "Arial", "FontFamily": "Arial",
"FontSizeHeading": "16", "FontSizeHeading": "16",
"HeaderFontFamily": "Consolas, Monaco", "HeaderFontFamily": "Consolas, Monaco",
"CheckBoxBulletDecoratorSize": "14", "CheckBoxBulletDecoratorSize": "14",
"CheckBoxMargin": "15,0,0,2", "CheckBoxMargin": "15,0,0,2",
"TabContentMargin": "5", "TabContentMargin": "5",
"TabButtonFontSize": "14", "TabButtonFontSize": "14",
"TabButtonWidth": "100", "TabButtonWidth": "100",
"TabButtonHeight": "25", "TabButtonHeight": "25",
"TabRowHeightInPixels": "50", "TabRowHeightInPixels": "50",
"IconFontSize": "14", "IconFontSize": "14",
"IconButtonSize": "35", "IconButtonSize": "35",
"WinUtilIconSize": "Auto", "SettingsIconFontSize": "18",
"SettingsIconFontSize": "18", "CloseIconFontSize": "18",
"CloseIconFontSize": "18",
"MicroWinLogoSize": "10", "MicroWinLogoSize": "10",
"MicrowinCheckBoxMargin": "-10,5,0,0",
"ProgressBarForegroundColor": "#FFAC1C", "ProgressBarForegroundColor": "#2e77ff",
"ProgressBarBackgroundColor": "Transparent", "ProgressBarBackgroundColor": "Transparent",
"ProgressBarTextColor": "#000000", "ProgressBarTextColor": "#232629",
"ComboBoxBackgroundColor": "#FFFFFF", "ComboBoxBackgroundColor": "#F7F7F7",
"LabelboxForegroundColor": "#000000", "LabelboxForegroundColor": "#232629",
"MainForegroundColor": "#000000", "MainForegroundColor": "#232629",
"MainBackgroundColor": "#FFFFFF", "MainBackgroundColor": "#F7F7F7",
"LabelBackgroundColor": "#FFFFFF", "LabelBackgroundColor": "#F7F7F7",
"LinkForegroundColor": "#000000", "LinkForegroundColor": "#232629",
"LinkHoverForegroundColor": "#000000", "LinkHoverForegroundColor": "#232629",
"GroupBorderBackgroundColor": "#000000", "GroupBorderBackgroundColor": "#232629",
"ComboBoxForegroundColor": "#000000", "ComboBoxForegroundColor": "#232629",
"ButtonFontSize": "12", "ButtonFontSize": "12",
"ButtonFontFamily": "Arial", "ButtonFontFamily": "Arial",
"ButtonWidth": "200", "ButtonWidth": "200",
"ButtonHeight": "25", "ButtonHeight": "25",
"ConfigTabButtonFontSize": "16", "ConfigTabButtonFontSize": "16",
"SearchBarWidth": "200", "SearchBarWidth": "200",
"SearchBarHeight": "25", "SearchBarHeight": "25",
"SearchBarTextBoxFontSize": "12", "SearchBarTextBoxFontSize": "12",
"SearchBarClearButtonFontSize": "14", "SearchBarClearButtonFontSize": "14",
"ButtonInstallBackgroundColor": "#FFFFFF", "ButtonInstallBackgroundColor": "#F7F7F7",
"ButtonTweaksBackgroundColor": "#FFFFFF", "ButtonTweaksBackgroundColor": "#F7F7F7",
"ButtonConfigBackgroundColor": "#FFFFFF", "ButtonConfigBackgroundColor": "#F7F7F7",
"ButtonUpdatesBackgroundColor": "#FFFFFF", "ButtonUpdatesBackgroundColor": "#F7F7F7",
"ButtonInstallForegroundColor": "#000000", "ButtonInstallForegroundColor": "#232629",
"ButtonTweaksForegroundColor": "#000000", "ButtonTweaksForegroundColor": "#232629",
"ButtonConfigForegroundColor": "#000000", "ButtonConfigForegroundColor": "#232629",
"ButtonUpdatesForegroundColor": "#000000", "ButtonUpdatesForegroundColor": "#232629",
"ButtonBackgroundColor": "#F5F5F5", "ButtonBackgroundColor": "#F5F5F5",
"ButtonBackgroundPressedColor": "#1A1A1A", "ButtonBackgroundPressedColor": "#1A1A1A",
"CheckboxMouseOverColor": "#999999", "CheckboxMouseOverColor": "#999999",
"ButtonBackgroundMouseoverColor": "#C2C2C2", "ButtonBackgroundMouseoverColor": "#C2C2C2",
"ButtonBackgroundSelectedColor": "#F0F0F0", "ButtonBackgroundSelectedColor": "#F0F0F0",
"ButtonForegroundColor": "#000000", "ButtonForegroundColor": "#232629",
"ToggleButtonOnColor": "#2e77ff", "ToggleButtonOnColor": "#2e77ff",
"ButtonBorderThickness": "1", "ButtonBorderThickness": "1",
"ButtonMargin": "1", "ButtonMargin": "1",
"ButtonCornerRadius": "2", "ButtonCornerRadius": "2",
"BorderColor": "#000000", "BorderColor": "#232629",
"BorderOpacity": "0.2", "BorderOpacity": "0.2",
"ShadowPulse": "Forever" "ShadowPulse": "Forever"
}, },
"Classic": { "Classic": {
"ComboBoxBackgroundColor": "#FFFFFF", "ComboBoxBackgroundColor": "#F7F7F7",
"LabelboxForegroundColor": "#000000", "LabelboxForegroundColor": "#232629",
"MainForegroundColor": "#000000", "MainForegroundColor": "#232629",
"MainBackgroundColor": "#FFFFFF", "MainBackgroundColor": "#F7F7F7",
"LabelBackgroundColor": "#FFFFFF", "LabelBackgroundColor": "#F7F7F7",
"LinkForegroundColor": "#000000", "LinkForegroundColor": "#232629",
"LinkHoverForegroundColor": "#000000", "LinkHoverForegroundColor": "#232629",
"GroupBorderBackgroundColor": "#000000", "GroupBorderBackgroundColor": "#232629",
"ComboBoxForegroundColor": "#000000", "ComboBoxForegroundColor": "#232629",
"ButtonInstallBackgroundColor": "#FFFFFF", "ButtonInstallBackgroundColor": "#F7F7F7",
"ButtonTweaksBackgroundColor": "#FFFFFF", "ButtonTweaksBackgroundColor": "#F7F7F7",
"ButtonConfigBackgroundColor": "#FFFFFF", "ButtonConfigBackgroundColor": "#F7F7F7",
"ButtonUpdatesBackgroundColor": "#FFFFFF", "ButtonUpdatesBackgroundColor": "#F7F7F7",
"ButtonInstallForegroundColor": "#000000", "ButtonInstallForegroundColor": "#232629",
"ButtonTweaksForegroundColor": "#000000", "ButtonTweaksForegroundColor": "#232629",
"ButtonConfigForegroundColor": "#000000", "ButtonConfigForegroundColor": "#232629",
"ButtonUpdatesForegroundColor": "#000000", "ButtonUpdatesForegroundColor": "#232629",
"ButtonBackgroundColor": "#F5F5F5", "ButtonBackgroundColor": "#F5F5F5",
"ButtonBackgroundPressedColor": "#1A1A1A", "ButtonBackgroundPressedColor": "#1A1A1A",
"CheckboxMouseOverColor": "#999999", "CheckboxMouseOverColor": "#999999",
"ButtonBackgroundMouseoverColor": "#C2C2C2", "ButtonBackgroundMouseoverColor": "#C2C2C2",
"ButtonBackgroundSelectedColor": "#F0F0F0", "ButtonBackgroundSelectedColor": "#F0F0F0",
"ButtonForegroundColor": "#000000", "ButtonForegroundColor": "#232629",
"ToggleButtonOnColor": "#2e77ff" "ToggleButtonOnColor": "#2e77ff"
}, },
"Matrix": { "Matrix": {
"ComboBoxBackgroundColor": "#000000", "ComboBoxBackgroundColor": "#232629",
"LabelboxForegroundColor": "#FFEE58", "LabelboxForegroundColor": "#f7f7f7",
"MainForegroundColor": "#9CCC65", "MainForegroundColor": "#F7F7F7",
"MainBackgroundColor": "#000000", "MainBackgroundColor": "#232629",
"LabelBackgroundColor": "#000000", "LabelBackgroundColor": "#232629",
"LinkForegroundColor": "#add8e6", "LinkForegroundColor": "#add8e6",
"LinkHoverForegroundColor": "#FFFFFF", "LinkHoverForegroundColor": "#F7F7F7",
"ComboBoxForegroundColor": "#FFEE58", "ComboBoxForegroundColor": "#81a1c1",
"ProgressBarForegroundColor": "#222222", "ProgressBarForegroundColor": "#222222",
"ProgressBarBackgroundColor": "Transparent", "ProgressBarBackgroundColor": "Transparent",
"ProgressBarTextColor": "#cccccc", "ProgressBarTextColor": "#cccccc",
"ButtonInstallBackgroundColor": "#222222", "ButtonInstallBackgroundColor": "#222222",
"ButtonTweaksBackgroundColor": "#333333", "ButtonTweaksBackgroundColor": "#333333",
"ButtonConfigBackgroundColor": "#444444", "ButtonConfigBackgroundColor": "#444444",
"ButtonUpdatesBackgroundColor": "#555555", "ButtonUpdatesBackgroundColor": "#555555",
"ButtonInstallForegroundColor": "#FFFFFF", "ButtonInstallForegroundColor": "#F7F7F7",
"ButtonTweaksForegroundColor": "#FFFFFF", "ButtonTweaksForegroundColor": "#F7F7F7",
"ButtonConfigForegroundColor": "#FFFFFF", "ButtonConfigForegroundColor": "#F7F7F7",
"ButtonUpdatesForegroundColor": "#FFFFFF", "ButtonUpdatesForegroundColor": "#F7F7F7",
"ButtonBackgroundColor": "#000019", "ButtonBackgroundColor": "#1E3747",
"ButtonBackgroundPressedColor": "#FFFFFF", "ButtonBackgroundPressedColor": "#F7F7F7",
"ButtonBackgroundMouseoverColor": "#A55A64", "ButtonBackgroundMouseoverColor": "#3B4252",
"ButtonBackgroundSelectedColor": "#FF5733", "ButtonBackgroundSelectedColor": "#5E81AC",
"ButtonForegroundColor": "#9CCC65", "ButtonForegroundColor": "#F7F7F7",
"ToggleButtonOnColor": "#2e77ff", "ToggleButtonOnColor": "#2e77ff",
"BorderColor": "#FFAC1C", "BorderColor": "#0060CC",
"BorderOpacity": "0.8", "BorderOpacity": "0.2",
"ShadowPulse": "0:0:3" "ShadowPulse": "0:0:3"
}, },
"Dark": { "Dark": {
"ComboBoxBackgroundColor": "#000000", "ComboBoxBackgroundColor": "#1e3747",
"LabelboxForegroundColor": "#FFEE58", "LabelboxForegroundColor": "#0567ff",
"MainForegroundColor": "#9CCC65", "MainForegroundColor": "#F7F7F7",
"MainBackgroundColor": "#000000", "MainBackgroundColor": "#121212",
"LabelBackgroundColor": "#000000", "LabelBackgroundColor": "#121212",
"LinkForegroundColor": "#add8e6", "LinkForegroundColor": "#add8e6",
"LinkHoverForegroundColor": "#FFFFFF", "LinkHoverForegroundColor": "#F7F7F7",
"ComboBoxForegroundColor": "#FFEE58", "ComboBoxForegroundColor": "#f7f7f7",
"ProgressBarForegroundColor": "#222222", "ProgressBarForegroundColor": "#222222",
"ProgressBarBackgroundColor": "Transparent", "ProgressBarBackgroundColor": "Transparent",
"ProgressBarTextColor": "#cccccc", "ProgressBarTextColor": "#cccccc",
"ButtonInstallBackgroundColor": "#222222", "ButtonInstallBackgroundColor": "#222222",
"ButtonTweaksBackgroundColor": "#333333", "ButtonTweaksBackgroundColor": "#333333",
"ButtonConfigBackgroundColor": "#444444", "ButtonConfigBackgroundColor": "#444444",
"ButtonUpdatesBackgroundColor": "#555555", "ButtonUpdatesBackgroundColor": "#555555",
"ButtonInstallForegroundColor": "#FFFFFF", "ButtonInstallForegroundColor": "#F7F7F7",
"ButtonTweaksForegroundColor": "#FFFFFF", "ButtonTweaksForegroundColor": "#F7F7F7",
"ButtonConfigForegroundColor": "#FFFFFF", "ButtonConfigForegroundColor": "#F7F7F7",
"ButtonUpdatesForegroundColor": "#FFFFFF", "ButtonUpdatesForegroundColor": "#F7F7F7",
"ButtonBackgroundColor": "#000019", "ButtonBackgroundColor": "#1E3747",
"ButtonBackgroundPressedColor": "#9CCC65", "ButtonBackgroundPressedColor": "#00CFFF",
"ButtonBackgroundMouseoverColor": "#FF5733", "ButtonBackgroundMouseoverColor": "#5E81AC",
"ButtonBackgroundSelectedColor": "#FF5733", "ButtonBackgroundSelectedColor": "#5E81AC",
"ButtonForegroundColor": "#9CCC65", "ButtonForegroundColor": "#F7F7F7",
"ToggleButtonOnColor": "#2e77ff", "ToggleButtonOnColor": "#2e77ff",
"BorderColor": "#FFAC1C" "BorderColor": "#2F373D"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 213 KiB

View File

@ -0,0 +1,65 @@
# Printer Settings
Last Updated: 2024-08-31
!!! info
The Development Documentation is auto generated for every compilation of WinUtil, meaning a part of it will always stay up-to-date. **Developers do have the ability to add custom content, which won't be updated automatically.**
<!-- BEGIN CUSTOM CONTENT -->
<!-- END CUSTOM CONTENT -->
<details>
<summary>Preview Code</summary>
```json
{
"Content": "Printer Settings",
"category": "Legacy Windows Panels",
"panel": "2",
"Type": "Button",
"ButtonWidth": "300"
}
```
</details>
## Function: Invoke-WPFControlPanel
```powershell
function Invoke-WPFControlPanel {
<#
.SYNOPSIS
Opens the requested legacy panel
.PARAMETER Panel
The panel to open
#>
param($Panel)
switch ($Panel) {
"WPFPanelcontrol" {cmd /c control}
"WPFPanelnetwork" {cmd /c ncpa.cpl}
"WPFPanelpower" {cmd /c powercfg.cpl}
"WPFPanelregion" {cmd /c intl.cpl}
"WPFPanelsound" {cmd /c mmsys.cpl}
"WPFPanelprinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
"WPFPanelsystem" {cmd /c sysdm.cpl}
"WPFPaneluser" {cmd /c "control userpasswords2"}
}
}
```
<!-- BEGIN SECOND CUSTOM CONTENT -->
<!-- END SECOND CUSTOM CONTENT -->
[View the JSON file](https://github.com/ChrisTitusTech/winutil/tree/main/../config/feature.json)

View File

@ -69,7 +69,7 @@ function Invoke-WPFTweakPS7{
Write-Host "Powershell 7 is already installed." Write-Host "Powershell 7 is already installed."
} else { } else {
Write-Host "Installing Powershell 7..." Write-Host "Installing Powershell 7..."
Invoke-WinUtilWingetProgram -Action Install -Programs @("Microsoft.PowerShell") Install-WinUtilProgramWinget -Action Install -Programs @("Microsoft.PowerShell")
} }
$targetTerminalName = "PowerShell" $targetTerminalName = "PowerShell"
} }
@ -105,10 +105,10 @@ function Invoke-WPFTweakPS7{
} }
``` ```
## Function: Invoke-WinUtilWingetProgram ## Function: Install-WinUtilProgramWinget
```powershell ```powershell
Function Invoke-WinUtilWingetProgram { Function Install-WinUtilProgramWinget {
<# <#
.SYNOPSIS .SYNOPSIS
Runs the designated action on the provided programs using Winget Runs the designated action on the provided programs using Winget

View File

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

View File

@ -29,6 +29,11 @@
* Click the `Clear Selection` button. * Click the `Clear Selection` button.
* This will unselect all checked programs. * This will unselect all checked programs.
=== "prefer Chocolatey"
* Check the `prefer Chocolatey` checkbox
* By default Winutil will use winget to install/upgrade/remove packages and fallback to Chocolatey. This option reverses the preference.
* This preference will be used for all Buttons on the Install page and persist across Winutil restarts
![Install Image](assets/Install-Tab-Dark.png#only-dark) ![Install Image](assets/Install-Tab-Dark.png#only-dark)
![Install Image](assets/Install-Tab-Light.png#only-light) ![Install Image](assets/Install-Tab-Light.png#only-light)
!!! tip !!! tip

View File

@ -1,92 +0,0 @@
function ConvertTo-Icon {
<#
.DESCRIPTION
This function will convert BMP, GIF, EXIF, JPG, PNG and TIFF to ICO file
.PARAMETER bitmapPath
The file path to bitmap image to make '.ico' file out of.
Supported file types according to Microsoft Documentation is the following:
BMP, GIF, EXIF, JPG, PNG and TIFF.
.PARAMETER iconPath
The file path to write the new '.ico' resource.
.PARAMETER overrideIconFile
An optional boolean Parameter that makes the function overrides
the Icon File Path if the file exists. Defaults to $true.
.EXAMPLE
try {
ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath "$env:TEMP\cttlogo.ico"
} catch [System.IO.FileNotFoundException] {
# Handle the thrown exception here...
}
This Example makes a '.ico' file at "$env:TEMP\cttlogo.ico" File Path using the bitmap file
found in "$env:TEMP\cttlogo.png", the function overrides the '.ico' File if it's found.
this function will throw a FileNotFound Exception at the event of not finding the provided bitmap File Path.
.EXAMPLE
try {
ConvertTo-Icon "$env:TEMP\cttlogo.png" "$env:TEMP\cttlogo.ico"
} catch [System.IO.FileNotFoundException] {
# Handle the thrown exception here...
}
This Example is the same as Example 1, but uses Positional Parameters instead.
.EXAMPLE
if (Test-Path "$env:TEMP\cttlogo.png") {
ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath "$env:TEMP\cttlogo.ico"
}
This Example is same as Example 1, but checks if the bitmap File exists before calling 'ConvertTo-Icon' Function.
This's the recommended way of using this function, as it doesn't require any try-catch blocks.
.EXAMPLE
try {
ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath "$env:TEMP\cttlogo.ico" -overrideIconFile $false
} catch [System.IO.FileNotFoundException] {
# Handle the thrown exception here...
}
This Example make use of '-overrideIconFile' Optional Parameter, the default for this parameter is $true.
By doing '-overrideIconFile $false', the 'ConvertTo-Icon' function will raise an exception that needs to be catched throw a 'catch' Code Block,
otherwise it'll crash the running PowerShell instance/process.
#>
param(
[Parameter(Mandatory, position=0)]
[string]$bitmapPath,
[Parameter(Mandatory, position=1)]
[string]$iconPath,
[Parameter(position=2)]
[bool]$overrideIconFile = $true
)
Add-Type -AssemblyName System.Drawing
if (Test-Path $bitmapPath) {
if ((Test-Path $iconPath) -AND ($overrideIconFile -eq $false)) {
Write-Host "[ConvertTo-Icon] Icon File is found at '$iconPath', and the 'overrideIconFile' Parameter is set to '$overrideIconFile'. Skipping the bitmap to icon convertion..." -ForegroundColor Yellow
return
}
# Load bitmap file into memory, and make an Icon version out of it
$b = [System.Drawing.Bitmap]::FromFile($bitmapPath)
$icon = [System.Drawing.Icon]::FromHandle($b.GetHicon())
# Create the folder for the new icon file if it doesn't exists
$iconFolder = (New-Object System.IO.FileInfo($iconPath)).Directory.FullName
[System.IO.Directory]::CreateDirectory($iconFolder) | Out-Null
# Write the Icon File and do some cleaning-up
$file = New-Object System.IO.FileStream($iconPath, 'OpenOrCreate')
$icon.Save($file)
$file.Close()
$icon.Dispose()
} else {
throw [System.IO.FileNotFoundException] "[ConvertTo-Icon] The provided bitmap File Path is not found at '$bitmapPath'."
}
}

View File

@ -13,10 +13,11 @@ function Install-WinUtilChoco {
if((Test-WinUtilPackageManager -choco) -eq "installed") { if((Test-WinUtilPackageManager -choco) -eq "installed") {
return return
} }
# Install logic taken from https://chocolatey.org/install#individual
Write-Host "Seems Chocolatey is not installed, installing now." Write-Host "Seems Chocolatey is not installed, installing now."
Set-ExecutionPolicy Bypass -Scope Process -Force; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) -ErrorAction Stop Set-ExecutionPolicy Bypass -Scope Process -Force;
powershell choco feature enable -n allowGlobalConfirmation [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
} catch { } catch {
Write-Host "===========================================" -Foregroundcolor Red Write-Host "===========================================" -Foregroundcolor Red

View File

@ -1,102 +1,258 @@
function Install-WinUtilProgramChoco { function Install-WinUtilProgramChoco {
<# <#
.SYNOPSIS .SYNOPSIS
Manages the provided programs using Chocolatey Manages the installation or uninstallation of a list of Chocolatey packages.
.PARAMETER ProgramsToInstall .PARAMETER Programs
A list of programs to manage A string array containing the programs to be installed or uninstalled.
.PARAMETER manage .PARAMETER Action
The action to perform on the programs, can be either 'Installing' or 'Uninstalling' Specifies the action to perform: "Install" or "Uninstall". The default value is "Install".
.NOTES .DESCRIPTION
The triple quotes are required any time you need a " in a normal script block. This function processes a list of programs to be managed using Chocolatey. Depending on the specified action, it either installs or uninstalls each program in the list, updating the taskbar progress accordingly. After all operations are completed, temporary output files are cleaned up.
.EXAMPLE
Install-WinUtilProgramChoco -Programs @("7zip","chrome") -Action "Uninstall"
#> #>
param( param(
[Parameter(Mandatory, Position=0)] [Parameter(Mandatory, Position = 0)]
[PsCustomObject]$ProgramsToInstall, [string[]]$Programs,
[Parameter(Position=1)] [Parameter(Position = 1)]
[String]$manage = "Installing" [String]$Action = "Install"
) )
$x = 0 function Initialize-OutputFile {
$count = $ProgramsToInstall.Count <#
.SYNOPSIS
Initializes an output file by removing any existing file and creating a new, empty file at the specified path.
# This check isn't really necessary, as there's a couple of checks before this Private Function gets called, but just to make sure ;) .PARAMETER filePath
if($count -le 0) { The full path to the file to be initialized.
throw "Private Function 'Install-WinUtilProgramChoco' expected Parameter 'ProgramsToInstall' to be of size 1 or greater, instead got $count,`nPlease double check your code and re-compile WinUtil."
.DESCRIPTION
This function ensures that the specified file is reset by removing any existing file at the provided path and then creating a new, empty file. It is useful when preparing a log or output file for subsequent operations.
.EXAMPLE
Initialize-OutputFile -filePath "C:\temp\output.txt"
#>
param ($filePath)
Remove-Item -Path $filePath -Force -ErrorAction SilentlyContinue
New-Item -ItemType File -Path $filePath | Out-Null
} }
Write-Progress -Activity "$manage Applications" -Status "Starting" -PercentComplete 0 function Run-ChocoCommand {
Write-Host "===========================================" <#
Write-Host "-- Configuring Chocolatey pacakages ---" .SYNOPSIS
Write-Host "===========================================" Executes a Chocolatey command with the specified arguments and returns the exit code.
Foreach ($Program in $ProgramsToInstall) {
Write-Progress -Activity "$manage Applications" -Status "$manage $($Program.choco) $($x + 1) of $count" -PercentComplete $($x/$count*100) .PARAMETER arguments
if($manage -eq "Installing") { The arguments to be passed to the Chocolatey command.
write-host "Starting install of $($Program.choco) with Chocolatey."
try { .DESCRIPTION
$tryUpgrade = $false This function runs a specified Chocolatey command by passing the provided arguments to the `choco` executable. It waits for the process to complete and then returns the exit code, allowing the caller to determine success or failure based on the exit code.
$installOutputFilePath = "$env:TEMP\Install-WinUtilProgramChoco.install-command.output.txt"
New-Item -ItemType File -Path $installOutputFilePath .RETURNS
$chocoInstallStatus = $(Start-Process -FilePath "choco" -ArgumentList "install $($Program.choco) -y" -Wait -PassThru -RedirectStandardOutput $installOutputFilePath).ExitCode [int]
if(($chocoInstallStatus -eq 0) -AND (Test-Path -Path $installOutputFilePath)) { The exit code of the Chocolatey command.
$keywordsFound = Get-Content -Path $installOutputFilePath | Where-Object {$_ -match "reinstall" -OR $_ -match "already installed"}
if ($keywordsFound) { .EXAMPLE
$tryUpgrade = $true $exitCode = Run-ChocoCommand -arguments "install 7zip -y"
#>
param ($arguments)
return (Start-Process -FilePath "choco" -ArgumentList $arguments -Wait -PassThru).ExitCode
}
function Check-UpgradeNeeded {
<#
.SYNOPSIS
Checks if an upgrade is needed for a Chocolatey package based on the content of a log file.
.PARAMETER filePath
The path to the log file that contains the output of a Chocolatey install command.
.DESCRIPTION
This function reads the specified log file and checks for keywords that indicate whether an upgrade is needed. It returns a boolean value indicating whether the terms "reinstall" or "already installed" are present, which suggests that the package might need an upgrade.
.RETURNS
[bool]
True if the log file indicates that an upgrade is needed; otherwise, false.
.EXAMPLE
$isUpgradeNeeded = Check-UpgradeNeeded -filePath "C:\temp\install-output.txt"
#>
param ($filePath)
return Get-Content -Path $filePath | Select-String -Pattern "reinstall|already installed" -Quiet
}
function Update-TaskbarProgress {
<#
.SYNOPSIS
Updates the taskbar progress based on the current installation progress.
.PARAMETER currentIndex
The current index of the program being installed or uninstalled.
.PARAMETER totalPrograms
The total number of programs to be installed or uninstalled.
.DESCRIPTION
This function calculates the progress of the installation or uninstallation process and updates the taskbar accordingly. The taskbar is set to "Normal" if all programs have been processed, otherwise, it is set to "Error" as a placeholder.
.EXAMPLE
Update-TaskbarProgress -currentIndex 3 -totalPrograms 10
#>
param (
[int]$currentIndex,
[int]$totalPrograms
)
$progressState = if ($currentIndex -eq $totalPrograms) { "Normal" } else { "Error" }
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state $progressState -value ($currentIndex / $totalPrograms) })
}
function Install-ChocoPackage {
<#
.SYNOPSIS
Installs a Chocolatey package and optionally upgrades it if needed.
.PARAMETER Program
A string containing the name of the Chocolatey package to be installed.
.PARAMETER currentIndex
The current index of the program in the list of programs to be managed.
.PARAMETER totalPrograms
The total number of programs to be installed.
.DESCRIPTION
This function installs a Chocolatey package by running the `choco install` command. If the installation output indicates that an upgrade might be needed, the function will attempt to upgrade the package. The taskbar progress is updated after each package is processed.
.EXAMPLE
Install-ChocoPackage -Program $Program -currentIndex 0 -totalPrograms 5
#>
param (
[string]$Program,
[int]$currentIndex,
[int]$totalPrograms
)
$installOutputFile = "$env:TEMP\Install-WinUtilProgramChoco.install-command.output.txt"
Initialize-OutputFile $installOutputFile
Write-Host "Starting installation of $Program with Chocolatey."
try {
$installStatusCode = Run-ChocoCommand "install $Program -y --log-file $installOutputFile"
if ($installStatusCode -eq 0) {
if (Check-UpgradeNeeded $installOutputFile) {
$upgradeStatusCode = Run-ChocoCommand "upgrade $Program -y"
Write-Host "$Program was" $(if ($upgradeStatusCode -eq 0) { "upgraded successfully." } else { "not upgraded." })
}
else {
Write-Host "$Program installed successfully."
} }
} }
# TODO: Implement the Upgrade part using 'choco upgrade' command, this will make choco consistent with WinGet, as WinGet tries to Upgrade when you use the install command. else {
if ($tryUpgrade) { Write-Host "Failed to install $Program."
throw "Automatic Upgrade for Choco isn't implemented yet, a feature to make it consistent with WinGet, the install command using choco simply failed because $($Program.choco) is already installed."
}
if(($chocoInstallStatus -eq 0) -AND ($tryUpgrade -eq $false)) {
Write-Host "$($Program.choco) installed successfully using Chocolatey."
$X++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value ($x/$count) })
continue
} else {
Write-Host "Failed to install $($Program.choco) using Chocolatey, Chocolatey output:`n`n$(Get-Content -Path $installOutputFilePath)."
$X++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
}
} catch {
Write-Host "Failed to install $($Program.choco) due to an error: $_"
$X++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
} }
} }
catch {
Write-Host "Failed to install $Program due to an error: $_"
}
finally {
Update-TaskbarProgress $currentIndex $totalPrograms
}
}
if($manage -eq "Uninstalling") { function Uninstall-ChocoPackage {
write-host "Starting uninstall of $($Program.choco) with Chocolatey." <#
.SYNOPSIS
Uninstalls a Chocolatey package and any related metapackages.
.PARAMETER Program
A string containing the name of the Chocolatey package to be uninstalled.
.PARAMETER currentIndex
The current index of the program in the list of programs to be managed.
.PARAMETER totalPrograms
The total number of programs to be uninstalled.
.DESCRIPTION
This function uninstalls a Chocolatey package and any related metapackages (e.g., .install or .portable variants). It updates the taskbar progress after processing each package.
.EXAMPLE
Uninstall-ChocoPackage -Program $Program -currentIndex 0 -totalPrograms 5
#>
param (
[string]$Program,
[int]$currentIndex,
[int]$totalPrograms
)
$uninstallOutputFile = "$env:TEMP\Install-WinUtilProgramChoco.uninstall-command.output.txt"
Initialize-OutputFile $uninstallOutputFile
Write-Host "Searching for metapackages of $Program (.install or .portable)"
$chocoPackages = ((choco list | Select-String -Pattern "$Program(\.install|\.portable)?").Matches.Value) -join " "
if ($chocoPackages) {
Write-Host "Starting uninstallation of $chocoPackages with Chocolatey."
try { try {
$uninstallOutputFilePath = "$env:TEMP\Install-WinUtilProgramChoco.uninstall-command.output.txt" $uninstallStatusCode = Run-ChocoCommand "uninstall $chocoPackages -y"
New-Item -ItemType File -Path $uninstallOutputFilePath Write-Host "$Program" $(if ($uninstallStatusCode -eq 0) { "uninstalled successfully." } else { "failed to uninstall." })
$chocoUninstallStatus = $(Start-Process -FilePath "choco" -ArgumentList "uninstall $($Program.choco) -y" -Wait -PassThru).ExitCode
if($chocoUninstallStatus -eq 0) {
Write-Host "$($Program.choco) uninstalled successfully using Chocolatey."
$x++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value ($x/$count) })
continue
} else {
Write-Host "Failed to uninstall $($Program.choco) using Chocolatey, Chocolatey output:`n`n$(Get-Content -Path $uninstallOutputFilePath)."
$x++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
}
} catch {
Write-Host "Failed to uninstall $($Program.choco) due to an error: $_"
$x++
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
} }
catch {
Write-Host "Failed to uninstall $Program due to an error: $_"
}
finally {
Update-TaskbarProgress $currentIndex $totalPrograms
}
}
else {
Write-Host "$Program is not installed."
}
} }
$totalPrograms = $Programs.Count
if ($totalPrograms -le 0) {
throw "Parameter 'Programs' must have at least one item."
} }
Write-Progress -Activity "$manage Applications" -Status "Finished" -Completed
# Cleanup leftovers files Write-Host "==========================================="
if(Test-Path -Path $installOutputFilePath) { Remove-Item -Path $installOutputFilePath } Write-Host "-- Configuring Chocolatey packages ---"
if(Test-Path -Path $uninstallOutputFilePath) { Remove-Item -Path $uninstallOutputFilePath } Write-Host "==========================================="
return; for ($currentIndex = 0; $currentIndex -lt $totalPrograms; $currentIndex++) {
$Program = $Programs[$currentIndex]
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($currentIndex / $totalPrograms * 100)
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($currentIndex / $totalPrograms)})
switch ($Action) {
"Install" {
Install-ChocoPackage -Program $Program -currentIndex $currentIndex -totalPrograms $totalPrograms
}
"Uninstall" {
Uninstall-ChocoPackage -Program $Program -currentIndex $currentIndex -totalPrograms $totalPrograms
}
default {
throw "Invalid action parameter value: '$Action'."
}
}
}
Set-WinUtilProgressBar -label "$($Action)ation done" -percent 100
# Cleanup Output Files
$outputFiles = @("$env:TEMP\Install-WinUtilProgramChoco.install-command.output.txt", "$env:TEMP\Install-WinUtilProgramChoco.uninstall-command.output.txt")
foreach ($filePath in $outputFiles) {
Remove-Item -Path $filePath -Force -ErrorAction SilentlyContinue
}
} }

View File

@ -1,4 +1,4 @@
Function Invoke-WinUtilWingetProgram { Function Install-WinUtilProgramWinget {
<# <#
.SYNOPSIS .SYNOPSIS
Runs the designated action on the provided programs using Winget Runs the designated action on the provided programs using Winget

View File

@ -0,0 +1,199 @@
function Invoke-WinUtilAssets {
param (
$type,
$Size,
[switch]$render
)
# Create the Viewbox and set its size
$LogoViewbox = New-Object Windows.Controls.Viewbox
$LogoViewbox.Width = $Size
$LogoViewbox.Height = $Size
# Create a Canvas to hold the paths
$canvas = New-Object Windows.Controls.Canvas
$canvas.Width = 100
$canvas.Height = 100
# Define a scale factor for the content inside the Canvas
$scaleFactor = $Size / 100
# Apply a scale transform to the Canvas content
$scaleTransform = New-Object Windows.Media.ScaleTransform($scaleFactor, $scaleFactor)
$canvas.LayoutTransform = $scaleTransform
switch ($type) {
'logo' {
$LogoPathData1 = @"
M 18.00,14.00
C 18.00,14.00 45.00,27.74 45.00,27.74
45.00,27.74 57.40,34.63 57.40,34.63
57.40,34.63 59.00,43.00 59.00,43.00
59.00,43.00 59.00,83.00 59.00,83.00
55.35,81.66 46.99,77.79 44.72,74.79
41.17,70.10 42.01,59.80 42.00,54.00
42.00,51.62 42.20,48.29 40.98,46.21
38.34,41.74 25.78,38.60 21.28,33.79
16.81,29.02 18.00,20.20 18.00,14.00 Z
"@
$LogoPath1 = New-Object Windows.Shapes.Path
$LogoPath1.Data = [Windows.Media.Geometry]::Parse($LogoPathData1)
$LogoPath1.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#0567ff")
$LogoPathData2 = @"
M 107.00,14.00
C 109.01,19.06 108.93,30.37 104.66,34.21
100.47,37.98 86.38,43.10 84.60,47.21
83.94,48.74 84.01,51.32 84.00,53.00
83.97,57.04 84.46,68.90 83.26,72.00
81.06,77.70 72.54,81.42 67.00,83.00
67.00,83.00 67.00,43.00 67.00,43.00
67.00,43.00 67.99,35.63 67.99,35.63
67.99,35.63 80.00,28.26 80.00,28.26
80.00,28.26 107.00,14.00 107.00,14.00 Z
"@
$LogoPath2 = New-Object Windows.Shapes.Path
$LogoPath2.Data = [Windows.Media.Geometry]::Parse($LogoPathData2)
$LogoPath2.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#0567ff")
$LogoPathData3 = @"
M 19.00,46.00
C 21.36,47.14 28.67,50.71 30.01,52.63
31.17,54.30 30.99,57.04 31.00,59.00
31.04,65.41 30.35,72.16 33.56,78.00
38.19,86.45 46.10,89.04 54.00,93.31
56.55,94.69 60.10,97.20 63.00,97.22
65.50,97.24 68.77,95.36 71.00,94.25
76.42,91.55 84.51,87.78 88.82,83.68
94.56,78.20 95.96,70.59 96.00,63.00
96.01,60.24 95.59,54.63 97.02,52.39
98.80,49.60 103.95,47.87 107.00,47.00
107.00,47.00 107.00,67.00 107.00,67.00
106.90,87.69 96.10,93.85 80.00,103.00
76.51,104.98 66.66,110.67 63.00,110.52
60.33,110.41 55.55,107.53 53.00,106.25
46.21,102.83 36.63,98.57 31.04,93.68
16.88,81.28 19.00,62.88 19.00,46.00 Z
"@
$LogoPath3 = New-Object Windows.Shapes.Path
$LogoPath3.Data = [Windows.Media.Geometry]::Parse($LogoPathData3)
$LogoPath3.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#a3a4a6")
$canvas.Children.Add($LogoPath1) | Out-Null
$canvas.Children.Add($LogoPath2) | Out-Null
$canvas.Children.Add($LogoPath3) | Out-Null
}
'checkmark' {
$canvas.Width = 512
$canvas.Height = 512
$scaleFactor = $Size / 2.54
$scaleTransform = New-Object Windows.Media.ScaleTransform($scaleFactor, $scaleFactor)
$canvas.LayoutTransform = $scaleTransform
# Define the circle path
$circlePathData = "M 1.27,0 A 1.27,1.27 0 1,0 1.27,2.54 A 1.27,1.27 0 1,0 1.27,0"
$circlePath = New-Object Windows.Shapes.Path
$circlePath.Data = [Windows.Media.Geometry]::Parse($circlePathData)
$circlePath.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#39ba00")
# Define the checkmark path
$checkmarkPathData = "M 0.873 1.89 L 0.41 1.391 A 0.17 0.17 0 0 1 0.418 1.151 A 0.17 0.17 0 0 1 0.658 1.16 L 1.016 1.543 L 1.583 1.013 A 0.17 0.17 0 0 1 1.599 1 L 1.865 0.751 A 0.17 0.17 0 0 1 2.105 0.759 A 0.17 0.17 0 0 1 2.097 0.999 L 1.282 1.759 L 0.999 2.022 L 0.874 1.888 Z"
$checkmarkPath = New-Object Windows.Shapes.Path
$checkmarkPath.Data = [Windows.Media.Geometry]::Parse($checkmarkPathData)
$checkmarkPath.Fill = [Windows.Media.Brushes]::White
# Add the paths to the Canvas
$canvas.Children.Add($circlePath) | Out-Null
$canvas.Children.Add($checkmarkPath) | Out-Null
}
'warning' {
$canvas.Width = 512
$canvas.Height = 512
# Define a scale factor for the content inside the Canvas
$scaleFactor = $Size / 512 # Adjust scaling based on the canvas size
$scaleTransform = New-Object Windows.Media.ScaleTransform($scaleFactor, $scaleFactor)
$canvas.LayoutTransform = $scaleTransform
# Define the circle path
$circlePathData = "M 256,0 A 256,256 0 1,0 256,512 A 256,256 0 1,0 256,0"
$circlePath = New-Object Windows.Shapes.Path
$circlePath.Data = [Windows.Media.Geometry]::Parse($circlePathData)
$circlePath.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#f41b43")
# Define the exclamation mark path
$exclamationPathData = "M 256 307.2 A 35.89 35.89 0 0 1 220.14 272.74 L 215.41 153.3 A 35.89 35.89 0 0 1 251.27 116 H 260.73 A 35.89 35.89 0 0 1 296.59 153.3 L 291.86 272.74 A 35.89 35.89 0 0 1 256 307.2 Z"
$exclamationPath = New-Object Windows.Shapes.Path
$exclamationPath.Data = [Windows.Media.Geometry]::Parse($exclamationPathData)
$exclamationPath.Fill = [Windows.Media.Brushes]::White
# Get the bounds of the exclamation mark path
$exclamationBounds = $exclamationPath.Data.Bounds
# Calculate the center position for the exclamation mark path
$exclamationCenterX = ($canvas.Width - $exclamationBounds.Width) / 2 - $exclamationBounds.X
$exclamationPath.SetValue([Windows.Controls.Canvas]::LeftProperty, $exclamationCenterX)
# Define the rounded rectangle at the bottom (dot of exclamation mark)
$roundedRectangle = New-Object Windows.Shapes.Rectangle
$roundedRectangle.Width = 80
$roundedRectangle.Height = 80
$roundedRectangle.RadiusX = 30
$roundedRectangle.RadiusY = 30
$roundedRectangle.Fill = [Windows.Media.Brushes]::White
# Calculate the center position for the rounded rectangle
$centerX = ($canvas.Width - $roundedRectangle.Width) / 2
$roundedRectangle.SetValue([Windows.Controls.Canvas]::LeftProperty, $centerX)
$roundedRectangle.SetValue([Windows.Controls.Canvas]::TopProperty, 324.34)
# Add the paths to the Canvas
$canvas.Children.Add($circlePath) | Out-Null
$canvas.Children.Add($exclamationPath) | Out-Null
$canvas.Children.Add($roundedRectangle) | Out-Null
}
default {
Write-Host "Invalid type: $type"
}
}
# Add the Canvas to the Viewbox
$LogoViewbox.Child = $canvas
if ($render) {
# Measure and arrange the canvas to ensure proper rendering
$canvas.Measure([Windows.Size]::new($canvas.Width, $canvas.Height))
$canvas.Arrange([Windows.Rect]::new(0, 0, $canvas.Width, $canvas.Height))
$canvas.UpdateLayout()
# Initialize RenderTargetBitmap correctly with dimensions
$renderTargetBitmap = New-Object Windows.Media.Imaging.RenderTargetBitmap($canvas.Width, $canvas.Height, 96, 96, [Windows.Media.PixelFormats]::Pbgra32)
# Render the canvas to the bitmap
$renderTargetBitmap.Render($canvas)
# Create a BitmapFrame from the RenderTargetBitmap
$bitmapFrame = [Windows.Media.Imaging.BitmapFrame]::Create($renderTargetBitmap)
# Create a PngBitmapEncoder and add the frame
$bitmapEncoder = [Windows.Media.Imaging.PngBitmapEncoder]::new()
$bitmapEncoder.Frames.Add($bitmapFrame)
# Save to a memory stream
$imageStream = New-Object System.IO.MemoryStream
$bitmapEncoder.Save($imageStream)
$imageStream.Position = 0
# Load the stream into a BitmapImage
$bitmapImage = [Windows.Media.Imaging.BitmapImage]::new()
$bitmapImage.BeginInit()
$bitmapImage.StreamSource = $imageStream
$bitmapImage.CacheOption = [Windows.Media.Imaging.BitmapCacheOption]::OnLoad
$bitmapImage.EndInit()
return $bitmapImage
} else {
return $LogoViewbox
}
}

View File

@ -13,6 +13,16 @@ Function Invoke-WinUtilCurrentSystem {
param( param(
$CheckBox $CheckBox
) )
if ($CheckBox -eq "choco") {
$apps = (choco list | Select-String -Pattern "^\S+").Matches.Value
$filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPFInstall*"}
$sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} | ForEach-Object {
$dependencies = @($sync.configs.applications.$($psitem.Key).choco -split ";")
if ($dependencies -in $apps) {
Write-Output $psitem.name
}
}
}
if ($checkbox -eq "winget") { if ($checkbox -eq "winget") {

View File

@ -37,28 +37,30 @@ function Remove-Features() {
Remove-Features Remove-Features
#> #>
try { try {
$featlist = (Get-WindowsOptionalFeature -Path $scratchDir).FeatureName $featlist = (Get-WindowsOptionalFeature -Path $scratchDir)
$featlist = $featlist | Where-Object { $featlist = $featlist | Where-Object {
$_ -NotLike "*Defender*" -AND $_.FeatureName -NotLike "*Defender*" -AND
$_ -NotLike "*Printing*" -AND $_.FeatureName -NotLike "*Printing*" -AND
$_ -NotLike "*TelnetClient*" -AND $_.FeatureName -NotLike "*TelnetClient*" -AND
$_ -NotLike "*PowerShell*" -AND $_.FeatureName -NotLike "*PowerShell*" -AND
$_ -NotLike "*NetFx*" -AND $_.FeatureName -NotLike "*NetFx*" -AND
$_ -NotLike "*Media*" -AND $_.FeatureName -NotLike "*Media*" -AND
$_ -NotLike "*NFS*" $_.FeatureName -NotLike "*NFS*" -AND
$_.State -ne "Disabled"
} }
foreach($feature in $featlist) { foreach($feature in $featlist) {
$status = "Removing feature $feature" $status = "Removing feature $($feature.FeatureName)"
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100) Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
Write-Debug "Removing feature $feature" Write-Debug "Removing feature $($feature.FeatureName)"
Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $feature -Remove -ErrorAction SilentlyContinue -NoRestart Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $($feature.FeatureName) -Remove -ErrorAction SilentlyContinue -NoRestart
} }
Write-Progress -Activity "Removing features" -Status "Ready" -Completed Write-Progress -Activity "Removing features" -Status "Ready" -Completed
Write-Host "You can re-enable the disabled features at any time, using either Windows Update or the SxS folder in <installation media>\Sources." Write-Host "You can re-enable the disabled features at any time, using either Windows Update or the SxS folder in <installation media>\Sources."
} catch { } catch {
Write-Host "Unable to get information about the features. MicroWin processing will continue, but features will not be processed" Write-Host "Unable to get information about the features. MicroWin processing will continue, but features will not be processed"
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
} }
} }
@ -106,6 +108,8 @@ function Remove-Packages {
$_ -NotLike "*Wifi*" $_ -NotLike "*Wifi*"
} }
$failedCount = 0
foreach ($pkg in $pkglist) { foreach ($pkg in $pkglist) {
try { try {
$status = "Removing $pkg" $status = "Removing $pkg"
@ -114,12 +118,18 @@ function Remove-Packages {
} catch { } catch {
# This can happen if the package that is being removed is a permanent one, like FodMetadata # This can happen if the package that is being removed is a permanent one, like FodMetadata
Write-Host "Could not remove OS package $($pkg)" Write-Host "Could not remove OS package $($pkg)"
$failedCount += 1
continue continue
} }
} }
Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed
if ($failedCount -gt 0)
{
Write-Host "Some packages could not be removed. Do not worry: your image will still work fine. This can happen if the package is permanent or has been superseded by a newer one."
}
} catch { } catch {
Write-Host "Unable to get information about the packages. MicroWin processing will continue, but packages will not be processed" Write-Host "Unable to get information about the packages. MicroWin processing will continue, but packages will not be processed"
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
} }
} }
@ -175,6 +185,7 @@ function Remove-ProvisionedPackages() {
{ {
# This can happen if getting AppX packages fails # This can happen if getting AppX packages fails
Write-Host "Unable to get information about the AppX packages. MicroWin processing will continue, but AppX packages will not be processed" Write-Host "Unable to get information about the AppX packages. MicroWin processing will continue, but AppX packages will not be processed"
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
} }
} }
@ -249,7 +260,7 @@ function New-Unattend {
param ( param (
[Parameter(Mandatory, Position = 0)] [string]$userName, [Parameter(Mandatory, Position = 0)] [string]$userName,
[Parameter(Position = 1)] [string] $userPassword [Parameter(Position = 1)] [string]$userPassword
) )
$unattend = @' $unattend = @'

View File

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

View File

@ -61,13 +61,13 @@ function Set-WinUtilTaskbaritem {
if ($overlay) { if ($overlay) {
switch ($overlay) { switch ($overlay) {
'logo' { 'logo' {
$sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\cttlogo.png" $sync["Form"].taskbarItemInfo.Overlay = $sync["logorender"]
} }
'checkmark' { 'checkmark' {
$sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\checkmark.png" $sync["Form"].taskbarItemInfo.Overlay = $sync["checkmarkrender"]
} }
'warning' { 'warning' {
$sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\warning.png" $sync["Form"].taskbarItemInfo.Overlay = $sync["warningrender"]
} }
'None' { 'None' {
$sync["Form"].taskbarItemInfo.Overlay = $null $sync["Form"].taskbarItemInfo.Overlay = $null

View File

@ -51,7 +51,7 @@ function Show-CustomDialog {
$buttonBackgroundColor = $sync.configs.themes.$ctttheme.ButtonInstallBackgroundColor $buttonBackgroundColor = $sync.configs.themes.$ctttheme.ButtonInstallBackgroundColor
$buttonForegroundColor = $sync.configs.themes.$ctttheme.ButtonInstallForegroundColor $buttonForegroundColor = $sync.configs.themes.$ctttheme.ButtonInstallForegroundColor
$shadowColor = [Windows.Media.ColorConverter]::ConvertFromString("#AAAAAAAA") $shadowColor = [Windows.Media.ColorConverter]::ConvertFromString("#AAAAAAAA")
$logocolor = $sync.configs.themes.$ctttheme.ButtonBackgroundPressedColor $logocolor = $sync.configs.themes.$ctttheme.LabelboxForegroundColor
# Create a custom dialog window # Create a custom dialog window
$dialog = New-Object Windows.Window $dialog = New-Object Windows.Window
@ -128,73 +128,15 @@ function Show-CustomDialog {
$grid.Children.Add($stackPanel) $grid.Children.Add($stackPanel)
[Windows.Controls.Grid]::SetRow($stackPanel, 0) # Set the row to the second row (0-based index) [Windows.Controls.Grid]::SetRow($stackPanel, 0) # Set the row to the second row (0-based index)
$viewbox = New-Object Windows.Controls.Viewbox
$viewbox.Width = $IconSize
$viewbox.Height = $IconSize
# Combine the paths into a single string
# $cttLogoPath = @"
# M174 1094 c-4 -14 -4 -55 -2 -92 3 -57 9 -75 41 -122 41 -60 45 -75 22 -84 -25 -9 -17 -21 30 -44 l45 -22 0 -103 c0 -91 3 -109 26 -155 30 -60 65 -87 204 -157 l95 -48 110 58 c184 96 205 127 205 293 l0 108 45 22 c47 23 55 36 30 46 -22 8 -18 30 9 63 13 16 34 48 46 71 20 37 21 52 15 116 l-6 73 -69 -23 c-38 -12 -137 -59 -220 -103 -82 -45 -160 -81 -171 -81 -12 0 -47 15 -78 34 -85 51 -239 127 -309 151 l-62 22 -6 -23z m500 -689 c20 -8 36 -19 36 -24 0 -18 -53 -51 -80 -51 -28 0 -80 33 -80 51 0 10 55 38 76 39 6 0 28 -7 48 -15z
# M177 711 c-19 -88 4 -242 49 -318 43 -74 107 -127 232 -191 176 -90 199 -84 28 7 -169 91 -214 129 -258 220 -29 58 -32 74 -37 190 -4 90 -8 116 -14 92z
# M1069 610 c-4 -131 -5 -137 -38 -198 -43 -79 -89 -119 -210 -181 -53 -27 -116 -61 -141 -76 -74 -43 -6 -20 115 40 221 109 296 217 294 425 -1 144 -16 137 -20 -10z
# "@
$cttLogoPath = @"
M 18.00,14.00
C 18.00,14.00 45.00,27.74 45.00,27.74
45.00,27.74 57.40,34.63 57.40,34.63
57.40,34.63 59.00,43.00 59.00,43.00
59.00,43.00 59.00,83.00 59.00,83.00
55.35,81.66 46.99,77.79 44.72,74.79
41.17,70.10 42.01,59.80 42.00,54.00
42.00,51.62 42.20,48.29 40.98,46.21
38.34,41.74 25.78,38.60 21.28,33.79
16.81,29.02 18.00,20.20 18.00,14.00 Z
M 107.00,14.00
C 109.01,19.06 108.93,30.37 104.66,34.21
100.47,37.98 86.38,43.10 84.60,47.21
83.94,48.74 84.01,51.32 84.00,53.00
83.97,57.04 84.46,68.90 83.26,72.00
81.06,77.70 72.54,81.42 67.00,83.00
67.00,83.00 67.00,43.00 67.00,43.00
67.00,43.00 67.99,35.63 67.99,35.63
67.99,35.63 80.00,28.26 80.00,28.26
80.00,28.26 107.00,14.00 107.00,14.00 Z
M 19.00,46.00
C 21.36,47.14 28.67,50.71 30.01,52.63
31.17,54.30 30.99,57.04 31.00,59.00
31.04,65.41 30.35,72.16 33.56,78.00
38.19,86.45 46.10,89.04 54.00,93.31
56.55,94.69 60.10,97.20 63.00,97.22
65.50,97.24 68.77,95.36 71.00,94.25
76.42,91.55 84.51,87.78 88.82,83.68
94.56,78.20 95.96,70.59 96.00,63.00
96.01,60.24 95.59,54.63 97.02,52.39
98.80,49.60 103.95,47.87 107.00,47.00
107.00,47.00 107.00,67.00 107.00,67.00
106.90,87.69 96.10,93.85 80.00,103.00
76.51,104.98 66.66,110.67 63.00,110.52
60.33,110.41 55.55,107.53 53.00,106.25
46.21,102.83 36.63,98.57 31.04,93.68
16.88,81.28 19.00,62.88 19.00,46.00 Z
"@
# Add SVG path
$svgPath = New-Object Windows.Shapes.Path
$svgPath.Data = [Windows.Media.Geometry]::Parse($cttLogoPath)
$svgPath.Fill = $logocolor # Set fill color to white
# Add SVG path to Viewbox
$viewbox.Child = $svgPath
# Add SVG path to the stack panel # Add SVG path to the stack panel
$stackPanel.Children.Add($viewbox) $stackPanel.Children.Add((Invoke-WinUtilAssets -Type "logo" -Size 25))
# Add "Winutil" text # Add "Winutil" text
$winutilTextBlock = New-Object Windows.Controls.TextBlock $winutilTextBlock = New-Object Windows.Controls.TextBlock
$winutilTextBlock.Text = "Winutil" $winutilTextBlock.Text = "Winutil"
$winutilTextBlock.FontSize = $HeaderFontSize $winutilTextBlock.FontSize = $HeaderFontSize
$winutilTextBlock.Foreground = $logocolor $winutilTextBlock.Foreground = $logocolor
$winutilTextBlock.Margin = New-Object Windows.Thickness(10, 5, 10, 5) # Add margins around the text block $winutilTextBlock.Margin = New-Object Windows.Thickness(10, 10, 10, 5) # Add margins around the text block
$stackPanel.Children.Add($winutilTextBlock) $stackPanel.Children.Add($winutilTextBlock)
# Add TextBlock for information with text wrapping and margins # Add TextBlock for information with text wrapping and margins
$messageTextBlock = New-Object Windows.Controls.TextBlock $messageTextBlock = New-Object Windows.Controls.TextBlock

View File

@ -41,6 +41,7 @@ function Invoke-WPFButton {
"WPFPanelpower" {Invoke-WPFControlPanel -Panel $button} "WPFPanelpower" {Invoke-WPFControlPanel -Panel $button}
"WPFPanelregion" {Invoke-WPFControlPanel -Panel $button} "WPFPanelregion" {Invoke-WPFControlPanel -Panel $button}
"WPFPanelsound" {Invoke-WPFControlPanel -Panel $button} "WPFPanelsound" {Invoke-WPFControlPanel -Panel $button}
"WPFPanelprinter" {Invoke-WPFControlPanel -Panel $button}
"WPFPanelsystem" {Invoke-WPFControlPanel -Panel $button} "WPFPanelsystem" {Invoke-WPFControlPanel -Panel $button}
"WPFPaneluser" {Invoke-WPFControlPanel -Panel $button} "WPFPaneluser" {Invoke-WPFControlPanel -Panel $button}
"WPFUpdatesdefault" {Invoke-WPFUpdatesdefault} "WPFUpdatesdefault" {Invoke-WPFUpdatesdefault}
@ -57,5 +58,6 @@ function Invoke-WPFButton {
"WPFMicrowin" {Invoke-WPFMicrowin} "WPFMicrowin" {Invoke-WPFMicrowin}
"WPFCloseButton" {Invoke-WPFCloseButton} "WPFCloseButton" {Invoke-WPFCloseButton}
"MicrowinScratchDirBT" {Invoke-ScratchDialog} "MicrowinScratchDirBT" {Invoke-ScratchDialog}
"WPFWinUtilPSProfile" {Invoke-WinUtilpsProfile}
} }
} }

View File

@ -16,6 +16,7 @@ function Invoke-WPFControlPanel {
"WPFPanelpower" {cmd /c powercfg.cpl} "WPFPanelpower" {cmd /c powercfg.cpl}
"WPFPanelregion" {cmd /c intl.cpl} "WPFPanelregion" {cmd /c intl.cpl}
"WPFPanelsound" {cmd /c mmsys.cpl} "WPFPanelsound" {cmd /c mmsys.cpl}
"WPFPanelprinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
"WPFPanelsystem" {cmd /c sysdm.cpl} "WPFPanelsystem" {cmd /c sysdm.cpl}
"WPFPaneluser" {cmd /c "control userpasswords2"} "WPFPaneluser" {cmd /c "control userpasswords2"}
} }

View File

@ -1,6 +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
@ -16,12 +16,12 @@ function Invoke-WPFGetInstalled {
return return
} }
if(((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget") { if(($sync.WPFpreferChocolatey.IsChecked -eq $false) -and ((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget") {
return return
} }
$preferChoco = $sync.WPFpreferChocolatey.IsChecked
Invoke-WPFRunspace -ArgumentList $checkbox -DebugPreference $DebugPreference -ScriptBlock { Invoke-WPFRunspace -ArgumentList $checkbox, $preferChoco -DebugPreference $DebugPreference -ScriptBlock {
param($checkbox, $DebugPreference) param($checkbox, $preferChoco, $DebugPreference)
$sync.ProcessRunning = $true $sync.ProcessRunning = $true
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" }) $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" })
@ -32,8 +32,12 @@ function Invoke-WPFGetInstalled {
if($checkbox -eq "tweaks") { if($checkbox -eq "tweaks") {
Write-Host "Getting Installed Tweaks..." Write-Host "Getting Installed Tweaks..."
} }
if ($preferChoco -and $checkbox -eq "winget") {
$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox $Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox "choco"
}
else{
$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox
}
$sync.form.Dispatcher.invoke({ $sync.form.Dispatcher.invoke({
foreach($checkbox in $Checkboxes) { foreach($checkbox in $Checkboxes) {

View File

@ -114,7 +114,7 @@ function Invoke-WPFGetIso {
# @ChrisTitusTech please copy this wiki and change the link below to your copy of the wiki # @ChrisTitusTech please copy this wiki and change the link below to your copy of the wiki
Write-Error "Failed to mount the image. Error: $($_.Exception.Message)" Write-Error "Failed to mount the image. Error: $($_.Exception.Message)"
Write-Error "This is NOT winutil's problem, your ISO might be corrupt, or there is a problem on the system" Write-Error "This is NOT winutil's problem, your ISO might be corrupt, or there is a problem on the system"
Write-Error "Please refer to this wiki for more details https://github.com/ChrisTitusTech/winutil/blob/main/wiki/Error-in-Winutil-MicroWin-during-ISO-mounting%2Cmd" Write-Host "Please refer to this wiki for more details: https://christitustech.github.io/winutil/KnownIssues/#troubleshoot-errors-during-microwin-usage" -ForegroundColor Red
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return return
} }

View File

@ -41,6 +41,8 @@ function Invoke-WPFImpex {
if ($type -eq "export") { if ($type -eq "export") {
$jsonFile = Get-WinUtilCheckBoxes -unCheck $false $jsonFile = Get-WinUtilCheckBoxes -unCheck $false
$jsonFile | ConvertTo-Json | Out-File $FileBrowser.FileName -Force $jsonFile | ConvertTo-Json | Out-File $FileBrowser.FileName -Force
$runscript = "iex ""& { `$(irm christitus.com/win) } -Config '$($FileBrowser.FileName)'"""
$runscript | Set-Clipboard
} }
if ($type -eq "import") { if ($type -eq "import") {
$jsonFile = Get-Content $Config | ConvertFrom-Json $jsonFile = Get-Content $Config | ConvertFrom-Json
@ -55,6 +57,7 @@ function Invoke-WPFImpex {
} }
} }
$flattenedJson = [string]$flattenedJson
Invoke-WPFPresets -preset $flattenedJson -imported $true Invoke-WPFPresets -preset $flattenedJson -imported $true
} }
} }

View File

@ -19,10 +19,9 @@ function Invoke-WPFInstall {
[System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) [System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
return return
} }
$ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked)
$installHandle = Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
Invoke-WPFRunspace -ArgumentList $PackagesToInstall -DebugPreference $DebugPreference -ScriptBlock { param($PackagesToInstall, $ChocoPreference, $DebugPreference)
param($PackagesToInstall, $DebugPreference)
if ($PackagesToInstall.count -eq 1) { if ($PackagesToInstall.count -eq 1) {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }) $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else { } else {
@ -30,17 +29,29 @@ function Invoke-WPFInstall {
} }
$packagesWinget, $packagesChoco = { $packagesWinget, $packagesChoco = {
$packagesWinget = [System.Collections.ArrayList]::new() $packagesWinget = [System.Collections.ArrayList]::new()
$packagesChoco = [System.Collections.Generic.List`1[System.Object]]::new() $packagesChoco = [System.Collections.ArrayList]::new()
foreach ($package in $PackagesToInstall) {
foreach ($package in $PackagesToInstall) {
if ($ChocoPreference) {
if ($package.choco -eq "na") {
$packagesWinget.add($package.winget)
Write-Host "Queueing $($package.winget) for Winget install"
} else {
$null = $packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey install"
}
}
else {
if ($package.winget -eq "na") { if ($package.winget -eq "na") {
$packagesChoco.add($package) $packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey install" Write-Host "Queueing $($package.choco) for Chocolatey install"
} else { } else {
$null = $packagesWinget.add($($package.winget)) $null = $packagesWinget.add($($package.winget))
Write-Host "Queueing $($package.winget) for Winget install" Write-Host "Queueing $($package.winget) for Winget install"
} }
} }
return $packagesWinget, $packagesChoco }
return $packagesWinget, $packagesChoco
}.Invoke($PackagesToInstall) }.Invoke($PackagesToInstall)
try { try {
@ -48,12 +59,12 @@ function Invoke-WPFInstall {
$errorPackages = @() $errorPackages = @()
if($packagesWinget.Count -gt 0) { if($packagesWinget.Count -gt 0) {
Install-WinUtilWinget Install-WinUtilWinget
$errorPackages += Invoke-WinUtilWingetProgram -Action Install -Programs $packagesWinget Install-WinUtilProgramWinget -Action Install -Programs $packagesWinget
$errorPackages| ForEach-Object {if($_.choco -ne "na") {$packagesChoco += $_}}
} }
if($packagesChoco.Count -gt 0) { if($packagesChoco.Count -gt 0) {
Install-WinUtilChoco Install-WinUtilChoco
Install-WinUtilProgramChoco -ProgramsToInstall $packagesChoco Install-WinUtilProgramChoco -Action Install -Programs $packagesChoco
} }
Write-Host "===========================================" Write-Host "==========================================="
Write-Host "-- Installs have finished ---" Write-Host "-- Installs have finished ---"

View File

@ -2,25 +2,35 @@ function Invoke-WPFInstallUpgrade {
<# <#
.SYNOPSIS .SYNOPSIS
Invokes the function that upgrades all installed programs using winget Invokes the function that upgrades all installed programs
#> #>
if((Test-WinUtilPackageManager -winget) -eq "not-installed") { if ($sync.WPFpreferChocolatey.IsChecked) {
return Install-WinUtilChoco
$chocoUpgradeStatus = (Start-Process "choco" -ArgumentList "upgrade all -y" -Wait -PassThru -NoNewWindow).ExitCode
if ($chocoUpgradeStatus -eq 0) {
Write-Host "Upgrade Successful"
}
else{
Write-Host "Error Occured. Return Code: $chocoUpgradeStatus"
}
} }
else{
if((Test-WinUtilPackageManager -winget) -eq "not-installed") {
return
}
if(Get-WinUtilInstallerProcess -Process $global:WinGetInstall) { if(Get-WinUtilInstallerProcess -Process $global:WinGetInstall) {
$msg = "[Invoke-WPFInstallUpgrade] Install process is currently running. Please check for a powershell window labeled 'Winget Install'" $msg = "[Invoke-WPFInstallUpgrade] Install process is currently running. Please check for a powershell window labeled 'Winget Install'"
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
return return
}
Update-WinUtilProgramWinget
Write-Host "==========================================="
Write-Host "-- Updates started ---"
Write-Host "-- You can close this window if desired ---"
Write-Host "==========================================="
} }
# Set-WinUtilTaskbaritem -state "Indeterminate"
Update-WinUtilProgramWinget
Write-Host "==========================================="
Write-Host "-- Updates started ---"
Write-Host "-- You can close this window if desired ---"
Write-Host "==========================================="
} }

View File

@ -11,17 +11,23 @@ function Invoke-WPFRunspace {
.PARAMETER ArgumentList .PARAMETER ArgumentList
A list of arguments to pass to the runspace A list of arguments to pass to the runspace
.PARAMETER ParameterList
A list of named parameters that should be provided.
.EXAMPLE .EXAMPLE
Invoke-WPFRunspace ` Invoke-WPFRunspace `
-ScriptBlock $sync.ScriptsInstallPrograms ` -ScriptBlock $sync.ScriptsInstallPrograms `
-ArgumentList "Installadvancedip,Installbitwarden" ` -ArgumentList "Installadvancedip,Installbitwarden" `
Invoke-WPFRunspace`
-ScriptBlock $sync.ScriptsInstallPrograms `
-ParameterList @(("PackagesToInstall", @("Installadvancedip,Installbitwarden")),("ChocoPreference", $true))
#> #>
[CmdletBinding()] [CmdletBinding()]
Param ( Param (
$ScriptBlock, $ScriptBlock,
$ArgumentList, $ArgumentList,
$ParameterList,
$DebugPreference $DebugPreference
) )
@ -31,6 +37,10 @@ function Invoke-WPFRunspace {
# Add Scriptblock and Arguments to runspace # Add Scriptblock and Arguments to runspace
$script:powershell.AddScript($ScriptBlock) $script:powershell.AddScript($ScriptBlock)
$script:powershell.AddArgument($ArgumentList) $script:powershell.AddArgument($ArgumentList)
foreach ($parameter in $ParameterList) {
$script:powershell.AddParameter($parameter[0], $parameter[1])
}
$script:powershell.AddArgument($DebugPreference) # Pass DebugPreference to the script block $script:powershell.AddArgument($DebugPreference) # Pass DebugPreference to the script block
$script:powershell.RunspacePool = $sync.runspace $script:powershell.RunspacePool = $sync.runspace
@ -45,4 +55,6 @@ function Invoke-WPFRunspace {
$sync.runspace.Close() $sync.runspace.Close()
[System.GC]::Collect() [System.GC]::Collect()
} }
# Return the handle
return $handle
} }

View File

@ -51,6 +51,9 @@ function Invoke-WPFShortcut {
$Shortcut = $WshShell.CreateShortcut($FileBrowser.FileName) $Shortcut = $WshShell.CreateShortcut($FileBrowser.FileName)
$Shortcut.TargetPath = $shell $Shortcut.TargetPath = $shell
$Shortcut.Arguments = $shellArgs $Shortcut.Arguments = $shellArgs
if (-NOT (Test-Path -Path $winutildir["logo.ico"])) {
Invoke-WebRequest -Uri "https://christitus.com/images/logo-full.ico" -OutFile $winutildir["logo.ico"]
}
if (Test-Path -Path $winutildir["logo.ico"]) { if (Test-Path -Path $winutildir["logo.ico"]) {
$shortcut.IconLocation = $winutildir["logo.ico"] $shortcut.IconLocation = $winutildir["logo.ico"]
} }

View File

@ -17,7 +17,7 @@ function Invoke-WPFTweakPS7{
Write-Host "Powershell 7 is already installed." Write-Host "Powershell 7 is already installed."
} else { } else {
Write-Host "Installing Powershell 7..." Write-Host "Installing Powershell 7..."
Invoke-WinUtilWingetProgram -Action Install -Programs @("Microsoft.PowerShell") Install-WinUtilProgramWinget -Action Install -Programs @("Microsoft.PowerShell")
} }
$targetTerminalName = "PowerShell" $targetTerminalName = "PowerShell"
} }

View File

@ -304,13 +304,6 @@ function Invoke-WPFUIElements {
$textBlock.ToolTip = $entryInfo.Link $textBlock.ToolTip = $entryInfo.Link
$textBlock.Style = $HoverTextBlockStyle $textBlock.Style = $HoverTextBlockStyle
# Add event handler for click to open link
$handler = [System.Windows.Input.MouseButtonEventHandler]{
param($sender, $e)
Start-Process $sender.ToolTip.ToString()
}
$textBlock.AddHandler([Windows.Controls.TextBlock]::MouseLeftButtonUpEvent, $handler)
$horizontalStackPanel.Children.Add($textBlock) | Out-Null $horizontalStackPanel.Children.Add($textBlock) | Out-Null
$sync[$textBlock.Name] = $textBlock $sync[$textBlock.Name] = $textBlock

View File

@ -2,43 +2,65 @@ Function Invoke-WPFUltimatePerformance {
<# <#
.SYNOPSIS .SYNOPSIS
Creates or removes the Ultimate Performance power scheme Enables or disables the Ultimate Performance power scheme based on its GUID.
.PARAMETER State .PARAMETER State
Indicates whether to enable or disable the Ultimate Performance power scheme Specifies whether to "Enable" or "Disable" the Ultimate Performance power scheme.
#> #>
param($State) param($State)
try { try {
# Check if Ultimate Performance plan is installed # GUID of the Ultimate Performance power plan
$ultimatePlan = powercfg -list | Select-String -Pattern "Ultimate Performance" $ultimateGUID = "e9a42b02-d5df-448d-aa00-03f14749eb61"
if($state -eq "Enable") {
if ($ultimatePlan) { if ($State -eq "Enable") {
Write-Host "Ultimate Performance plan is already installed." # Duplicate the Ultimate Performance power plan using its GUID
} else { $duplicateOutput = powercfg /duplicatescheme $ultimateGUID
Write-Host "Installing Ultimate Performance plan..."
powercfg -duplicatescheme e9a42b02-d5df-448d-aa00-03f14749eb61 $guid = $null
Write-Host "> Ultimate Performance plan installed." $nameFromFile = "ChrisTitus - Ultimate Power Plan"
$description = "Ultimate Power Plan, added via WinUtils"
# Extract the new GUID from the duplicateOutput
foreach ($line in $duplicateOutput) {
if ($line -match "\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b") {
$guid = $matches[0] # $matches[0] will contain the first match, which is the GUID
Write-Output "GUID: $guid has been extracted and stored in the variable."
break
}
} }
# Set the Ultimate Performance plan as active if (-not $guid) {
$ultimatePlanGUID = (powercfg -list | Select-String -Pattern "Ultimate Performance").Line.Split()[3] Write-Output "No GUID found in the duplicateOutput. Check the output format."
powercfg -setactive $ultimatePlanGUID exit 1
}
Write-Host "Ultimate Performance plan is now active." # Change the name of the power plan and set its description
$changeNameOutput = powercfg /changename $guid "$nameFromFile" "$description"
Write-Output "The power plan name and description have been changed. Output:"
Write-Output $changeNameOutput
# Set the duplicated Ultimate Performance plan as active
$setActiveOutput = powercfg /setactive $guid
Write-Output "The power plan has been set as active. Output:"
Write-Output $setActiveOutput
} Write-Host "> Ultimate Performance plan installed and set as active."
elseif($state -eq "Disable") {
if ($ultimatePlan) { } elseif ($State -eq "Disable") {
# Extract the GUID of the Ultimate Performance plan # Check if the Ultimate Performance plan is installed by GUID
$ultimatePlanGUID = $ultimatePlan.Line.Split()[3] $installedPlan = powercfg -list | Select-String -Pattern $ultimateGUID
if ($installedPlan) {
# Extract the GUID of the installed Ultimate Performance plan
$ultimatePlanGUID = $installedPlan.Line.Split()[3]
# Set a different power plan as active before deleting the Ultimate Performance plan # Set a different power plan as active before deleting the Ultimate Performance plan
$balancedPlanGUID = (powercfg -list | Select-String -Pattern "Balanced").Line.Split()[3] $balancedPlanGUID = (powercfg -list | Select-String -Pattern "Balanced").Line.Split()[3]
powercfg -setactive $balancedPlanGUID powercfg -setactive $balancedPlanGUID
# Delete the Ultimate Performance plan # Delete the Ultimate Performance plan by GUID
powercfg -delete $ultimatePlanGUID powercfg -delete $ultimatePlanGUID
Write-Host "Ultimate Performance plan has been uninstalled." Write-Host "Ultimate Performance plan has been uninstalled."
@ -48,6 +70,6 @@ Function Invoke-WPFUltimatePerformance {
} }
} }
} catch { } catch {
Write-Warning $psitem.Exception.Message Write-Error "Error occurred: $_"
} }
} }

View File

@ -28,38 +28,51 @@ function Invoke-WPFUnInstall {
$confirm = [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) $confirm = [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon)
if($confirm -eq "No") {return} if($confirm -eq "No") {return}
$ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked)
Invoke-WPFRunspace -ArgumentList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
Invoke-WPFRunspace -ArgumentList $PackagesToInstall -DebugPreference $DebugPreference -ScriptBlock { param($PackagesToInstall, $ChocoPreference, $DebugPreference)
param($PackagesToInstall, $DebugPreference)
if ($PackagesToInstall.count -eq 1) { if ($PackagesToInstall.count -eq 1) {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }) $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else { } else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
} }
$packagesWinget, $packagesChoco = { $packagesWinget, $packagesChoco = {
$packagesWinget = [System.Collections.Generic.List`1[System.Object]]::new() $packagesWinget = [System.Collections.ArrayList]::new()
$packagesChoco = [System.Collections.Generic.List`1[System.Object]]::new() $packagesChoco = [System.Collections.ArrayList]::new()
foreach ($package in $PackagesToInstall) {
if ($package.winget -eq "na") { foreach ($package in $PackagesToInstall) {
$packagesChoco.add($package) if ($ChocoPreference) {
Write-Host "Queueing $($package.choco) for Chocolatey Uninstall" if ($package.choco -eq "na") {
$packagesWinget.add($package.winget)
Write-Host "Queueing $($package.winget) for Winget uninstall"
} else { } else {
$packagesWinget.add($($package.winget)) $null = $packagesChoco.add($package.choco)
Write-Host "Queueing $($package.winget) for Winget Uninstall" Write-Host "Queueing $($package.choco) for Chocolatey uninstall"
} }
} }
return $packagesWinget, $packagesChoco else {
if ($package.winget -eq "na") {
$packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey uninstall"
} else {
$null = $packagesWinget.add($($package.winget))
Write-Host "Queueing $($package.winget) for Winget uninstall"
}
}
}
return $packagesWinget, $packagesChoco
}.Invoke($PackagesToInstall) }.Invoke($PackagesToInstall)
try { try {
$sync.ProcessRunning = $true $sync.ProcessRunning = $true
# Install all selected programs in new window # Install all selected programs in new window
if($packagesWinget.Count -gt 0) { if($packagesWinget.Count -gt 0) {
Invoke-WinUtilWingetProgram -Action Uninstall -Programs $packagesWinget Install-WinUtilProgramWinget -Action Uninstall -Programs $packagesWinget
} }
if($packagesChoco.Count -gt 0) { if($packagesChoco.Count -gt 0) {
Install-WinUtilProgramChoco -ProgramsToInstall $packagesChoco -Manage "Uninstalling" Install-WinUtilProgramChoco -Action Uninstall -Programs $packagesChoco
} }
Write-Host "===========================================" Write-Host "==========================================="

View File

@ -24,8 +24,12 @@ function Invoke-WPFtweaksbutton {
Write-Debug "Number of tweaks to process: $($Tweaks.Count)" Write-Debug "Number of tweaks to process: $($Tweaks.Count)"
Invoke-WPFRunspace -ArgumentList $Tweaks -DebugPreference $DebugPreference -ScriptBlock { # The leading "," in the ParameterList is nessecary because we only provide one argument and powershell cannot be convinced that we want a nested loop with only one argument otherwise
param($Tweaks, $DebugPreference) $tweaksHandle = Invoke-WPFRunspace -ParameterList @(,("tweaks",$tweaks)) -DebugPreference $DebugPreference -ScriptBlock {
param(
$tweaks,
$DebugPreference
)
Write-Debug "Inside Number of tweaks to process: $($Tweaks.Count)" Write-Debug "Inside Number of tweaks to process: $($Tweaks.Count)"
$sync.ProcessRunning = $true $sync.ProcessRunning = $true
@ -38,8 +42,9 @@ function Invoke-WPFtweaksbutton {
# Execute other selected tweaks # Execute other selected tweaks
for ($i = 0; $i -lt $Tweaks.Count; $i++) { for ($i = 0; $i -lt $Tweaks.Count; $i++) {
Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($i / $Tweaks.Count * 100) Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($i / $tweaks.Count * 100)
Invoke-WinUtilTweaks $tweaks[$i]$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i/$Tweaks.Count) }) Invoke-WinUtilTweaks $tweaks[$i]
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i/$Tweaks.Count) })
} }
Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100 Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100
$sync.ProcessRunning = $false $sync.ProcessRunning = $false

View File

@ -32,19 +32,19 @@ $sync.runspace.Open()
# Create classes for different exceptions # Create classes for different exceptions
class WingetFailedInstall : Exception { class WingetFailedInstall : Exception {
[string] $additionalData [string]$additionalData
WingetFailedInstall($Message) : base($Message) {} WingetFailedInstall($Message) : base($Message) {}
} }
class ChocoFailedInstall : Exception { class ChocoFailedInstall : Exception {
[string] $additionalData [string]$additionalData
ChocoFailedInstall($Message) : base($Message) {} ChocoFailedInstall($Message) : base($Message) {}
} }
class GenericException : Exception { class GenericException : Exception {
[string] $additionalData [string]$additionalData
GenericException($Message) : base($Message) {} GenericException($Message) : base($Message) {}
} }
@ -116,6 +116,14 @@ Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "feat
$xaml.SelectNodes("//*[@Name]") | ForEach-Object {$sync["$("$($psitem.Name)")"] = $sync["Form"].FindName($psitem.Name)} $xaml.SelectNodes("//*[@Name]") | ForEach-Object {$sync["$("$($psitem.Name)")"] = $sync["Form"].FindName($psitem.Name)}
#Persist the Chocolatey preference across winutil restarts
$ChocoPreferencePath = "$env:LOCALAPPDATA\winutil\preferChocolatey.ini"
$sync.WPFpreferChocolatey.Add_Checked({New-Item -Path $ChocoPreferencePath -Force })
$sync.WPFpreferChocolatey.Add_Unchecked({Remove-Item $ChocoPreferencePath -Force})
if (Test-Path $ChocoPreferencePath) {
$sync.WPFpreferChocolatey.IsChecked = $true
}
$sync.keys | ForEach-Object { $sync.keys | ForEach-Object {
if($sync.$psitem) { if($sync.$psitem) {
if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "ToggleButton") { if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "ToggleButton") {
@ -408,7 +416,7 @@ $sync["SearchBar"].Add_TextChanged({
# Retrieve the corresponding text block based on the generated name # Retrieve the corresponding text block based on the generated name
$textBlock = $sync[$textBlockName] $textBlock = $sync[$textBlockName]
if ($CheckBox.Value.Content.ToLower().Contains($textToSearch)) { if ($CheckBox.Value.Content.ToString().ToLower().Contains($textToSearch)) {
$CheckBox.Value.Visibility = "Visible" $CheckBox.Value.Visibility = "Visible"
$activeApplications += $sync.configs.applications.$checkboxName $activeApplications += $sync.configs.applications.$checkboxName
# Set the corresponding text block visibility # Set the corresponding text block visibility
@ -439,35 +447,31 @@ $sync["SearchBar"].Add_TextChanged({
} }
}) })
$sync["Form"].Add_Loaded({
param($e)
$sync["Form"].MaxWidth = [Double]::PositiveInfinity
$sync["Form"].MaxHeight = [Double]::PositiveInfinity
})
$NavLogoPanel = $sync["Form"].FindName("NavLogoPanel")
$NavLogoPanel.Children.Add((Invoke-WinUtilAssets -Type "logo" -Size 25)) | Out-Null
# Initialize the hashtable # Initialize the hashtable
$winutildir = @{} $winutildir = @{}
# Set the path for the winutil directory # Set the path for the winutil directory
$winutildir["path"] = "$env:LOCALAPPDATA\winutil\" $winutildir["path"] = "$env:LOCALAPPDATA\winutil\"
if (-NOT (Test-Path -Path $winutildir["path"])) { [System.IO.Directory]::CreateDirectory($winutildir["path"]) | Out-Null
New-Item -Path $winutildir["path"] -ItemType Directory
}
# Set the path for the logo and checkmark images
$winutildir["logo.png"] = $winutildir["path"] + "cttlogo.png"
$winutildir["logo.ico"] = $winutildir["path"] + "cttlogo.ico" $winutildir["logo.ico"] = $winutildir["path"] + "cttlogo.ico"
if (-NOT (Test-Path -Path $winutildir["logo.png"])) {
Invoke-WebRequest -Uri "https://christitus.com/images/logo-full.png" -OutFile $winutildir["logo.png"]
}
if (-NOT (Test-Path -Path $winutildir["logo.ico"])) { if (Test-Path $winutildir["logo.ico"]) {
ConvertTo-Icon -bitmapPath $winutildir["logo.png"] -iconPath $winutildir["logo.ico"] $sync["logorender"] = $winutildir["logo.ico"]
} else {
$sync["logorender"] = (Invoke-WinUtilAssets -Type "Logo" -Size 90 -Render)
} }
$sync["checkmarkrender"] = (Invoke-WinUtilAssets -Type "checkmark" -Size 512 -Render)
$winutildir["checkmark.png"] = $winutildir["path"] + "checkmark.png" $sync["warningrender"] = (Invoke-WinUtilAssets -Type "warning" -Size 512 -Render)
$winutildir["warning.png"] = $winutildir["path"] + "warning.png"
if (-NOT (Test-Path -Path $winutildir["checkmark.png"])) {
Invoke-WebRequest -Uri "https://christitus.com/images/checkmark.png" -OutFile $winutildir["checkmark.png"]
}
if (-NOT (Test-Path -Path $winutildir["warning.png"])) {
Invoke-WebRequest -Uri "https://christitus.com/images/warning.png" -OutFile $winutildir["warning.png"]
}
Set-WinUtilTaskbaritem -overlay "logo" Set-WinUtilTaskbaritem -overlay "logo"
@ -516,10 +520,10 @@ Version : <a href="https://github.com/ChrisTitusTech/winutil/releases/tag/$($sy
"@ "@
$FontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSize $FontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSize
$HeaderFontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSizeHeader $HeaderFontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSizeHeader
$IconSize = $sync.configs.themes.$ctttheme.CustomDialogIconSize $LogoSize = $sync.configs.themes.$ctttheme.CustomDialogLogoSize
$Width = $sync.configs.themes.$ctttheme.CustomDialogWidth $Width = $sync.configs.themes.$ctttheme.CustomDialogWidth
$Height = $sync.configs.themes.$ctttheme.CustomDialogHeight $Height = $sync.configs.themes.$ctttheme.CustomDialogHeight
Show-CustomDialog -Message $authorInfo -Width $Width -Height $Height -FontSize $FontSize -HeaderFontSize $HeaderFontSize -IconSize $IconSize Show-CustomDialog -Message $authorInfo -Width $Width -Height $Height -FontSize $FontSize -HeaderFontSize $HeaderFontSize -LogoSize $LogoSize
}) })
$sync["SponsorMenuItem"].Add_Click({ $sync["SponsorMenuItem"].Add_Click({
@ -542,10 +546,10 @@ $sync["SponsorMenuItem"].Add_Click({
$FontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSize $FontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSize
$HeaderFontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSizeHeader $HeaderFontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSizeHeader
$IconSize = $sync.configs.themes.$ctttheme.CustomDialogIconSize $LogoSize = $sync.configs.themes.$ctttheme.CustomDialogLogoSize
$Width = $sync.configs.themes.$ctttheme.CustomDialogWidth $Width = $sync.configs.themes.$ctttheme.CustomDialogWidth
$Height = $sync.configs.themes.$ctttheme.CustomDialogHeight $Height = $sync.configs.themes.$ctttheme.CustomDialogHeight
Show-CustomDialog -Message $authorInfo -Width $Width -Height $Height -FontSize $FontSize -HeaderFontSize $HeaderFontSize -IconSize $IconSize -EnableScroll $true Show-CustomDialog -Message $authorInfo -Width $Width -Height $Height -FontSize $FontSize -HeaderFontSize $HeaderFontSize -LogoSize $LogoSize -EnableScroll $true
}) })
$sync["Form"].ShowDialog() | out-null $sync["Form"].ShowDialog() | out-null
Stop-Transcript Stop-Transcript

View File

@ -5,6 +5,7 @@
GitHub : https://github.com/ChrisTitusTech GitHub : https://github.com/ChrisTitusTech
Version : #{replaceme} Version : #{replaceme}
#> #>
param ( param (
[switch]$Debug, [switch]$Debug,
[string]$Config, [string]$Config,
@ -27,12 +28,6 @@ if ($Run) {
$PARAM_RUN = $true $PARAM_RUN = $true
} }
$dateTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$logdir = "$env:localappdata\winutil\logs"
[System.IO.Directory]::CreateDirectory("$logdir")
Start-Transcript -Path "$logdir\winutil_$dateTime.log" -Append
# Load DLLs # Load DLLs
Add-Type -AssemblyName PresentationFramework Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Windows.Forms
@ -46,8 +41,22 @@ $sync.ProcessRunning = $false
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Output "Winutil needs to be run as Administrator. Attempting to relaunch." Write-Output "Winutil needs to be run as Administrator. Attempting to relaunch."
$argList = @()
$PSBoundParameters.GetEnumerator() | ForEach-Object {
$argList += if ($_.Value -is [switch] -and $_.Value) {
"-$($_.Key)"
} elseif ($_.Value) {
"-$($_.Key) `"$($_.Value)`""
}
}
$script = if ($MyInvocation.MyCommand.Path) {
"& { & '$($MyInvocation.MyCommand.Path)' $argList }"
} else {
"iex '& { $(irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1) } $argList'"
}
$script = if ($MyInvocation.MyCommand.Path) { "& '" + $MyInvocation.MyCommand.Path + "'" } else { "irm 'https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1' | iex"}
$powershellcmd = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" } $powershellcmd = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" }
$processCmd = if (Get-Command wt.exe -ErrorAction SilentlyContinue) { "wt.exe" } else { $powershellcmd } $processCmd = if (Get-Command wt.exe -ErrorAction SilentlyContinue) { "wt.exe" } else { $powershellcmd }
@ -56,6 +65,12 @@ if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]:
break break
} }
$dateTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$logdir = "$env:localappdata\winutil\logs"
[System.IO.Directory]::CreateDirectory("$logdir") | Out-Null
Start-Transcript -Path "$logdir\winutil_$dateTime.log" -Append -NoClobber | Out-Null
# Set PowerShell window title # Set PowerShell window title
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Admin)" $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Admin)"
clear-host clear-host

View File

@ -1,4 +1,4 @@
function Invoke-Preprocessing { function Invoke-Preprocessing {
<# <#
.SYNOPSIS .SYNOPSIS
A function that does Code Formatting using RegEx, useful when trying to force specific coding standard(s) to a project. A function that does Code Formatting using RegEx, useful when trying to force specific coding standard(s) to a project.
@ -39,7 +39,7 @@
.EXAMPLE .EXAMPLE
Invoke-Preprocessing -ThrowExceptionOnEmptyFilesList -WorkingDir "DRIVE:\Path\To\Folder\" -ExcludedFiles @('file.txt', '.\.git\', '*.png') -ProgressStatusMessage "Doing Preprocessing" Invoke-Preprocessing -ThrowExceptionOnEmptyFilesList -WorkingDir "DRIVE:\Path\To\Folder\" -ExcludedFiles @('file.txt', '.\.git\', '*.png') -ProgressStatusMessage "Doing Preprocessing"
Same as Example No. 1, but will throw an exception when 'Invoke-Preprocessing' function doesn't find any files in 'WorkingDir' (not including 'ExcludedFiles' list). Same as Example No. 1, but uses '-ThrowExceptionOnEmptyFilesList', which's an optional parameter that'll make 'Invoke-Preprocessing' throw an exception when no files are found in 'WorkingDir' (not including the ExcludedFiles, of course), useful when you want to double check your parameters & you're sure there's files to process in the 'WorkingDir'.
.EXAMPLE .EXAMPLE
Invoke-Preprocessing -Skip -WorkingDir "DRIVE:\Path\To\Folder\" -ExcludedFiles @('file.txt', '.\.git\', '*.png') -ProgressStatusMessage "Doing Preprocessing" Invoke-Preprocessing -Skip -WorkingDir "DRIVE:\Path\To\Folder\" -ExcludedFiles @('file.txt', '.\.git\', '*.png') -ProgressStatusMessage "Doing Preprocessing"
@ -47,7 +47,7 @@
Same as Example No. 1, but uses '-SkipExcludedFilesValidation', which'll skip the validation step for 'ExcludedFiles' list. This can be useful when 'ExcludedFiles' list is generated from another function, or from unreliable source (you can't guarantee every item in list is a valid path), but you want to silently continue through the function. Same as Example No. 1, but uses '-SkipExcludedFilesValidation', which'll skip the validation step for 'ExcludedFiles' list. This can be useful when 'ExcludedFiles' list is generated from another function, or from unreliable source (you can't guarantee every item in list is a valid path), but you want to silently continue through the function.
#> #>
param ( param (
[Parameter(position=0)] [Parameter(position=0)]
[switch]$SkipExcludedFilesValidation, [switch]$SkipExcludedFilesValidation,
@ -66,28 +66,86 @@
[Parameter(position=5)] [Parameter(position=5)]
[string]$ProgressActivity = "Preprocessing" [string]$ProgressActivity = "Preprocessing"
) )
if (-NOT (Test-Path -PathType Container -Path "$WorkingDir")) { if (-NOT (Test-Path -PathType Container -Path "$WorkingDir")) {
throw "[Invoke-Preprocessing] Invalid Paramter Value for 'WorkingDir', passed value: '$WorkingDir'. Either the path is a File or Non-Existing/Invlid, please double check your code." throw "[Invoke-Preprocessing] Invalid Paramter Value for 'WorkingDir', passed value: '$WorkingDir'. Either the path is a File or Non-Existing/Invlid, please double check your code."
} }
$count = $ExcludedFiles.Count $count = $ExcludedFiles.Count
if ((-NOT ($count -eq 0)) -AND (-NOT $SkipExcludedFilesValidation)) {
# Make sure there's a * at the end of folders in ExcludedFiles list
for ($i = 0; $i -lt $count; $i++) {
$excludedFile = $ExcludedFiles[$i]
$isFolder = ($excludedFile) -match '\\$'
if ($isFolder) { $ExcludedFiles[$i] = $excludedFile + '*' }
}
# Validate the ExcludedFiles List before continuing on,
# that's if there's a list in the first place, and '-SkipExcludedFilesValidation' was not provided.
if (-not $SkipExcludedFilesValidation) {
for ($i = 0; $i -lt $count; $i++) { for ($i = 0; $i -lt $count; $i++) {
$excludedFile = $ExcludedFiles[$i] $excludedFile = $ExcludedFiles[$i]
$filePath = "$(($WorkingDir -replace ('\\$', '')) + '\' + ($excludedFile -replace ('\.\\', '')))" $filePath = "$(($WorkingDir -replace ('\\$', '')) + '\' + ($excludedFile -replace ('\.\\', '')))"
if (-NOT (Get-ChildItem -Recurse -Path "$filePath" -File)) {
$failedFilesList += "'$filePath', " # Handle paths with wildcards in a different implementation
$matches = ($filePath) -match '^.*?\*'
if ($matches) {
if (-NOT (Get-ChildItem -Recurse -Path "$filePath" -File -Force)) {
$failedFilesList += "'$filePath', "
}
} else {
if (-NOT (Test-Path -Path "$filePath")) {
$failedFilesList += "'$filePath', "
}
} }
} }
$failedFilesList = $failedFilesList -replace (',\s*$', '') $failedFilesList = $failedFilesList -replace (',\s*$', '')
if (-NOT $failedFilesList -eq "") { if (-NOT $failedFilesList -eq "") {
throw "[Invoke-Preprocessing] One or more File Paths & File Patterns were not found, you can use '-SkipExcludedFilesValidation' switch to skip this check, and the failed files are: $failedFilesList" throw "[Invoke-Preprocessing] One or more File Paths and/or File Patterns were not found, you can use '-SkipExcludedFilesValidation' switch to skip this check, the failed to validate are: $failedFilesList"
} }
} }
$files = Get-ChildItem $WorkingDir -Recurse -Exclude $ExcludedFiles -File # Get Files List
[System.Collections.ArrayList]$files = Get-ChildItem $WorkingDir -Recurse -Exclude $ExcludedFiles -File -Force
$numOfFiles = $files.Count
# Only keep the 'FullName' Property for every entry in the list
for ($i = 0; $i -lt $numOfFiles; $i++) {
$file = $files[$i]
$files[$i] = $file.FullName
}
# If a file(s) are found in Exclude List,
# Remove the file from files list.
for ($j = 0; $j -lt $excludedFiles.Count; $j++) {
# Prepare some variables
$excluded = $excludedFiles[$j]
$pathToFind = ($excluded) -replace ('^\.\\', '')
$pathToFind = $WorkingDir + '\' + $pathToFind
$index = -1 # reset index on every iteration
# Handle paths with wildcards in a different implementation
$matches = ($pathToFind) -match '^.*?\*'
if ($matches) {
$filesToCheck = Get-ChildItem -Recurse -Path "$pathToFind" -File -Force
if ($filesToCheck) {
for ($k = 0; $k -lt $filesToCheck.Count; $k++) {
$fileToCheck = $filesToCheck[$k]
$index = $files.IndexOf("$fileToCheck")
if ($index -ge 0) { $files.RemoveAt($index) }
}
}
} else {
$index = $files.IndexOf("$pathToFind")
if ($index -ge 0) { $files.RemoveAt($index) }
}
}
# Make sure 'numOfFiles' is synced with the actual Number of Files found in '$files'
# This's done because previous may or may not edit the files list, so we should update it
$numOfFiles = $files.Count $numOfFiles = $files.Count
if ($numOfFiles -eq 0) { if ($numOfFiles -eq 0) {
@ -99,26 +157,11 @@
} }
for ($i = 0; $i -lt $numOfFiles; $i++) { for ($i = 0; $i -lt $numOfFiles; $i++) {
$file = $files[$i] $fullFileName = $files[$i]
# If the file is in Exclude List, don't proceed to check/modify said file.
$fileIsExcluded = $False
for ($j = 0; $j -lt $excludedFiles.Count; $j++) {
$excluded = $excludedFiles[$j]
$strToCompare = ($excluded) -replace ('^\.\\', '')
if ($file.FullName.Contains("$strToCompare")) {
$fileIsExcluded = $True
break
}
}
if ($fileIsExcluded) {
continue
}
# TODO: # TODO:
# make more formatting rules, and document them in WinUtil Official Documentation # make more formatting rules, and document them in WinUtil Official Documentation
(Get-Content "$file").TrimEnd() ` (Get-Content "$fullFileName").TrimEnd() `
-replace ('\t', ' ') ` -replace ('\t', ' ') `
-replace ('\)\s*\{', ') {') ` -replace ('\)\s*\{', ') {') `
-replace ('(?<keyword>if|for|foreach)\s*(?<condition>\([.*?]\))\s*\{', '${keyword} ${condition} {') ` -replace ('(?<keyword>if|for|foreach)\s*(?<condition>\([.*?]\))\s*\{', '${keyword} ${condition} {') `
@ -129,8 +172,8 @@
-replace ('\}\s*Catch', '} catch') ` -replace ('\}\s*Catch', '} catch') `
-replace ('\}\s*Catch\s*(?<exceptions>(\[.*?\]\s*(\,)?\s*)+)\s*\{', '} catch ${exceptions} {') ` -replace ('\}\s*Catch\s*(?<exceptions>(\[.*?\]\s*(\,)?\s*)+)\s*\{', '} catch ${exceptions} {') `
-replace ('\}\s*Catch\s*(?<exceptions>\[.*?\])\s*\{', '} catch ${exceptions} {') ` -replace ('\}\s*Catch\s*(?<exceptions>\[.*?\])\s*\{', '} catch ${exceptions} {') `
-replace ('(?<parameter_type>\[.*?\])\s*(?<str_after_type>\$.*?(,|\s*\)))', '${parameter_type}${str_after_type}') ` -replace ('(?<parameter_type>\[[^$0-9]+\])\s*(?<str_after_type>\$.*?)', '${parameter_type}${str_after_type}') `
| Set-Content "$file" | Set-Content "$fullFileName"
Write-Progress -Activity $ProgressActivity -Status "$ProgressStatusMessage - Finished $i out of $numOfFiles" -PercentComplete (($i/$numOfFiles)*100) Write-Progress -Activity $ProgressActivity -Status "$ProgressStatusMessage - Finished $i out of $numOfFiles" -PercentComplete (($i/$numOfFiles)*100)
} }

View File

@ -12,18 +12,6 @@
Run in Admin Powershell > ./windev.ps1 Run in Admin Powershell > ./windev.ps1
#> #>
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Output "Winutil needs to be run as Administrator. Attempting to relaunch."
$script = if ($MyInvocation.MyCommand.Path) { "& '" + $MyInvocation.MyCommand.Path + "'" } else { "irm 'https://github.com/ChrisTitusTech/winutil/raw/main/windev.ps1' | iex"}
$powershellcmd = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" }
$processCmd = if (Get-Command wt.exe -ErrorAction SilentlyContinue) { "wt.exe" } else { $powershellcmd }
Start-Process $processCmd -ArgumentList "$powershellcmd -ExecutionPolicy Bypass -NoProfile -Command $script" -Verb RunAs
break
}
# Function to fetch the latest release tag from the GitHub API # Function to fetch the latest release tag from the GitHub API
function Get-LatestRelease { function Get-LatestRelease {
try { try {
@ -46,7 +34,20 @@ function RedirectToLatestPreRelease {
Write-Host "Using latest Full Release" Write-Host "Using latest Full Release"
$url = "https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1" $url = "https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1"
} }
Invoke-RestMethod $url | Invoke-Expression
$script = Invoke-RestMethod $url
# Elevate Shell if necessary
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Output "Winutil needs to be run as Administrator. Attempting to relaunch."
$powershellcmd = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" }
$processCmd = if (Get-Command wt.exe -ErrorAction SilentlyContinue) { "wt.exe" } else { $powershellcmd }
Start-Process $processCmd -ArgumentList "$powershellcmd -ExecutionPolicy Bypass -NoProfile -Command $(Invoke-Expression $script)" -Verb RunAs
}
else{
Invoke-Expression $script
}
} }
# Call the redirect function # Call the redirect function

View File

@ -9,7 +9,11 @@
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
UseLayoutRounding="True" UseLayoutRounding="True"
WindowStyle="None" WindowStyle="None"
Title="Chris Titus Tech's Windows Utility" Height="800" Width="1280"> Width="Auto"
Height="Auto"
MaxWidth="1280"
MaxHeight="800"
Title="Chris Titus Tech's Windows Utility">
<WindowChrome.WindowChrome> <WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" CornerRadius="10"/> <WindowChrome CaptionHeight="0" CornerRadius="10"/>
</WindowChrome.WindowChrome> </WindowChrome.WindowChrome>
@ -213,7 +217,7 @@
<Setter TargetName="BackgroundBorder" Property="Background" Value="{ButtonBackgroundMouseoverColor}"/> <Setter TargetName="BackgroundBorder" Property="Background" Value="{ButtonBackgroundMouseoverColor}"/>
<Setter Property="Effect"> <Setter Property="Effect">
<Setter.Value> <Setter.Value>
<DropShadowEffect Opacity="1" ShadowDepth="5" Color="Gold" Direction="-100" BlurRadius="45"/> <DropShadowEffect Opacity="1" ShadowDepth="5" Color="{ButtonBackgroundMouseoverColor}" Direction="-100" BlurRadius="15"/>
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter Property="Panel.ZIndex" Value="2000"/> <Setter Property="Panel.ZIndex" Value="2000"/>
@ -224,7 +228,7 @@
<Setter TargetName="BackgroundBorder" Property="Background" Value="{ButtonBackgroundSelectedColor}"/> <Setter TargetName="BackgroundBorder" Property="Background" Value="{ButtonBackgroundSelectedColor}"/>
<Setter Property="Effect"> <Setter Property="Effect">
<Setter.Value> <Setter.Value>
<DropShadowEffect Opacity="1" ShadowDepth="2" Color="Gold" Direction="-111" BlurRadius="25"/> <DropShadowEffect Opacity="1" ShadowDepth="2" Color="{ButtonBackgroundMouseoverColor}" Direction="-111" BlurRadius="10"/>
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Trigger> </Trigger>
@ -645,8 +649,8 @@
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<DockPanel HorizontalAlignment="Stretch" Background="{MainBackgroundColor}" SnapsToDevicePixels="True" Grid.Row="0" Width="Auto"> <DockPanel HorizontalAlignment="Stretch" Background="{MainBackgroundColor}" SnapsToDevicePixels="True" Grid.Row="0" Width="Auto">
<Image Height="{WinUtilIconSize}" Width="{WinUtilIconSize}" Name="WPFIcon" <StackPanel Name="NavLogoPanel" Orientation="Horizontal" HorizontalAlignment="Left" Background="{MainBackgroundColor}" SnapsToDevicePixels="True" Margin="10,0,20,0">
SnapsToDevicePixels="True" Source="https://christitus.com/images/logo-full.png" Margin="10"/> </StackPanel>
<ToggleButton HorizontalAlignment="Left" Height="{TabButtonHeight}" Width="{TabButtonWidth}" <ToggleButton HorizontalAlignment="Left" Height="{TabButtonHeight}" Width="{TabButtonWidth}"
Background="{ButtonInstallBackgroundColor}" Foreground="white" FontWeight="Bold" Name="WPFTab1BT"> Background="{ButtonInstallBackgroundColor}" Foreground="white" FontWeight="Bold" Name="WPFTab1BT">
<ToggleButton.Content> <ToggleButton.Content>
@ -689,10 +693,10 @@
</ToggleButton> </ToggleButton>
<Grid Background="{MainBackgroundColor}" ShowGridLines="False" Width="Auto" Height="Auto" HorizontalAlignment="Stretch"> <Grid Background="{MainBackgroundColor}" ShowGridLines="False" Width="Auto" Height="Auto" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> <!-- Main content area -->
<ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> <!-- Space for options button -->
<ColumnDefinition Width="50px"/> <ColumnDefinition Width="Auto"/> <!-- Space for close button -->
<ColumnDefinition Width="50px"/> <ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!-- <!--
@ -722,7 +726,8 @@
VerticalAlignment="Center" HorizontalAlignment="Left" VerticalAlignment="Center" HorizontalAlignment="Left"
FontFamily="Segoe MDL2 Assets" FontFamily="Segoe MDL2 Assets"
FontSize="{IconFontSize}" FontSize="{IconFontSize}"
Margin="180,0,0,0">&#xE721;</TextBlock> Margin="180,0,0,0">&#xE721;
</TextBlock>
<!-- <!--
TODO: TODO:
Make this ClearButton Positioning react to Make this ClearButton Positioning react to
@ -734,7 +739,8 @@
VerticalAlignment="Center" HorizontalAlignment="Left" VerticalAlignment="Center" HorizontalAlignment="Left"
Name="SearchBarClearButton" Name="SearchBarClearButton"
Style="{StaticResource SearchBarClearButtonStyle}" Style="{StaticResource SearchBarClearButtonStyle}"
Margin="210,0,0,0" Visibility="Collapsed"/> Margin="210,0,0,0" Visibility="Collapsed">
</Button>
<ProgressBar <ProgressBar
Grid.Column="1" Grid.Column="1"
@ -773,7 +779,7 @@
FontSize="{SettingsIconFontSize}" FontSize="{SettingsIconFontSize}"
Width="{IconButtonSize}" Height="{IconButtonSize}" Width="{IconButtonSize}" Height="{IconButtonSize}"
HorizontalAlignment="Right" VerticalAlignment="Top" HorizontalAlignment="Right" VerticalAlignment="Top"
Margin="0,5,5,0" Margin="5,5,5,0"
FontFamily="Segoe MDL2 Assets" FontFamily="Segoe MDL2 Assets"
Content="&#xE713;"/> Content="&#xE713;"/>
<Popup Grid.Column="2" Name="SettingsPopup" <Popup Grid.Column="2" Name="SettingsPopup"
@ -782,8 +788,16 @@
HorizontalAlignment="Right" VerticalAlignment="Top"> HorizontalAlignment="Right" VerticalAlignment="Top">
<Border Background="{MainBackgroundColor}" BorderBrush="{MainForegroundColor}" BorderThickness="1" CornerRadius="0" Margin="0"> <Border Background="{MainBackgroundColor}" BorderBrush="{MainForegroundColor}" BorderThickness="1" CornerRadius="0" Margin="0">
<StackPanel Background="{MainBackgroundColor}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <StackPanel Background="{MainBackgroundColor}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<MenuItem FontSize="{ButtonFontSize}" Header="Import" Name="ImportMenuItem" Foreground="{MainForegroundColor}"/> <MenuItem FontSize="{ButtonFontSize}" Header="Import" Name="ImportMenuItem" Foreground="{MainForegroundColor}">
<MenuItem FontSize="{ButtonFontSize}" Header="Export" Name="ExportMenuItem" Foreground="{MainForegroundColor}"/> <MenuItem.ToolTip>
<ToolTip Content="Import Configuration from exported file."/>
</MenuItem.ToolTip>
</MenuItem>
<MenuItem FontSize="{ButtonFontSize}" Header="Export" Name="ExportMenuItem" Foreground="{MainForegroundColor}">
<MenuItem.ToolTip>
<ToolTip Content="Export Selected Elements and copy execution command to clipboard."/>
</MenuItem.ToolTip>
</MenuItem>
<Separator/> <Separator/>
<MenuItem FontSize="{ButtonFontSize}" Header="About" Name="AboutMenuItem" Foreground="{MainForegroundColor}"/> <MenuItem FontSize="{ButtonFontSize}" Header="About" Name="AboutMenuItem" Foreground="{MainForegroundColor}"/>
<MenuItem FontSize="{ButtonFontSize}" Header="Sponsors" Name="SponsorMenuItem" Foreground="{MainForegroundColor}"/> <MenuItem FontSize="{ButtonFontSize}" Header="Sponsors" Name="SponsorMenuItem" Foreground="{MainForegroundColor}"/>
@ -819,6 +833,9 @@
<Button Name="WPFUninstall" Content=" Uninstall Selected" Margin="2"/> <Button Name="WPFUninstall" Content=" Uninstall Selected" Margin="2"/>
<Button Name="WPFGetInstalled" Content=" Get Installed" Margin="2"/> <Button Name="WPFGetInstalled" Content=" Get Installed" Margin="2"/>
<Button Name="WPFClearInstallSelection" Content=" Clear Selection" Margin="2"/> <Button Name="WPFClearInstallSelection" Content=" Clear Selection" Margin="2"/>
<CheckBox Name="WPFpreferChocolatey" VerticalAlignment="Center" VerticalContentAlignment="Center">
<TextBlock Text="Prefer Chocolatey" ToolTip="Prefers Chocolatey as Download Engine instead of Winget" VerticalAlignment="Center" />
</CheckBox>
</StackPanel> </StackPanel>
<ScrollViewer x:Name="scrollViewer" Grid.Row="1" Grid.Column="0" Margin="{TabContentMargin}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" <ScrollViewer x:Name="scrollViewer" Grid.Row="1" Grid.Column="0" Margin="{TabContentMargin}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
@ -851,7 +868,7 @@
<Label Content="Recommended Selections:" FontSize="{FontSize}" VerticalAlignment="Center" Margin="2"/> <Label Content="Recommended Selections:" FontSize="{FontSize}" VerticalAlignment="Center" Margin="2"/>
<Button Name="WPFstandard" Content=" Standard " Margin="2"/> <Button Name="WPFstandard" Content=" Standard " Margin="2"/>
<Button Name="WPFminimal" Content=" Minimal " Margin="2"/> <Button Name="WPFminimal" Content=" Minimal " Margin="2"/>
<Button Name="WPFclear" Content=" Clear " Margin="2"/> <Button Name="WPFClearTweaksSelection" Content=" Clear " Margin="2"/>
<Button Name="WPFGetInstalledTweaks" Content=" Get Installed " Margin="2"/> <Button Name="WPFGetInstalledTweaks" Content=" Get Installed " Margin="2"/>
</StackPanel> </StackPanel>
@ -870,18 +887,10 @@
</Grid> </Grid>
</ScrollViewer> </ScrollViewer>
<Border Grid.Row="1" Background="{MainBackgroundColor}" BorderBrush="{BorderColor}" BorderThickness="1" CornerRadius="5" HorizontalAlignment="Stretch" Padding="10"> <Border Grid.Row="1" Background="{MainBackgroundColor}" BorderBrush="{BorderColor}" BorderThickness="1" CornerRadius="5" HorizontalAlignment="Stretch" Padding="10">
<Grid> <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="0">
<Grid.ColumnDefinitions> <Button Name="WPFTweaksbutton" Content="Run Tweaks" Margin="5"/>
<ColumnDefinition Width="1*" /> <Button Name="WPFUndoall" Content="Undo Selected Tweaks" Margin="5"/>
<ColumnDefinition Width="1*" /> </StackPanel>
</Grid.ColumnDefinitions>
<!-- Buttons on the left half -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="0">
<Button Name="WPFTweaksbutton" Content="Run Tweaks" Margin="5"/>
<Button Name="WPFUndoall" Content="Undo Selected Tweaks" Margin="5"/>
</StackPanel>
</Grid>
</Border> </Border>
</Grid> </Grid>
</TabItem> </TabItem>
@ -902,19 +911,19 @@
<Border Grid.Row="0" Grid.Column="0" Style="{StaticResource BorderStyle}"> <Border Grid.Row="0" Grid.Column="0" Style="{StaticResource BorderStyle}">
<StackPanel Background="{MainBackgroundColor}" SnapsToDevicePixels="True"> <StackPanel Background="{MainBackgroundColor}" SnapsToDevicePixels="True">
<Button Name="WPFUpdatesdefault" FontSize="{ConfigTabButtonFontSize}" Height="Auto" Width="Auto" Content="Default (Out of Box) Settings" Margin="20,4,20,10" Padding="10"/> <Button Name="WPFUpdatesdefault" FontSize="{ConfigTabButtonFontSize}" Height="Auto" Width="Auto" Content="Default (Out of Box) Settings" Margin="20,4,20,10" Padding="10"/>
<TextBlock Margin="20,0,20,0" Padding="10" TextWrapping="WrapWithOverflow" MaxWidth="300">This is the default settings that come with Windows. <LineBreak/><LineBreak/> No modifications are made and will remove any custom windows update settings.<LineBreak/><LineBreak/>Note: If you still encounter update errors, reset all updates in the config tab. That will restore ALL Microsoft Update Services from their servers and reinstall them to default settings.</TextBlock> <TextBlock Foreground="{ComboBoxForegroundColor}" Margin="20,0,20,0" Padding="10" TextWrapping="WrapWithOverflow" MaxWidth="300">This is the default settings that come with Windows. <LineBreak/><LineBreak/> No modifications are made and will remove any custom windows update settings.<LineBreak/><LineBreak/>Note: If you still encounter update errors, reset all updates in the config tab. That will restore ALL Microsoft Update Services from their servers and reinstall them to default settings.</TextBlock>
</StackPanel> </StackPanel>
</Border> </Border>
<Border Grid.Row="0" Grid.Column="1" Style="{StaticResource BorderStyle}"> <Border Grid.Row="0" Grid.Column="1" Style="{StaticResource BorderStyle}">
<StackPanel Background="{MainBackgroundColor}" SnapsToDevicePixels="True"> <StackPanel Background="{MainBackgroundColor}" SnapsToDevicePixels="True">
<Button Name="WPFUpdatessecurity" FontSize="{ConfigTabButtonFontSize}" Height="Auto" Width="Auto" Content="Security (Recommended) Settings" Margin="20,4,20,10" Padding="10"/> <Button Name="WPFUpdatessecurity" FontSize="{ConfigTabButtonFontSize}" Height="Auto" Width="Auto" Content="Security (Recommended) Settings" Margin="20,4,20,10" Padding="10"/>
<TextBlock Margin="20,0,20,0" Padding="10" TextWrapping="WrapWithOverflow" MaxWidth="300">This is my recommended setting I use on all computers.<LineBreak/><LineBreak/> It will delay feature updates by 2 years and will install security updates 4 days after release.<LineBreak/><LineBreak/>Feature Updates: Adds features and often bugs to systems when they are released. You want to delay these as long as possible.<LineBreak/><LineBreak/>Security Updates: Typically these are pressing security flaws that need to be patched quickly. You only want to delay these a couple of days just to see if they are safe and don't break other systems. You don't want to go without these for ANY extended periods of time.</TextBlock> <TextBlock Foreground="{ComboBoxForegroundColor}" Margin="20,0,20,0" Padding="10" TextWrapping="WrapWithOverflow" MaxWidth="300">This is my recommended setting I use on all computers.<LineBreak/><LineBreak/> It will delay feature updates by 2 years and will install security updates 4 days after release.<LineBreak/><LineBreak/>Feature Updates: Adds features and often bugs to systems when they are released. You want to delay these as long as possible.<LineBreak/><LineBreak/>Security Updates: Typically these are pressing security flaws that need to be patched quickly. You only want to delay these a couple of days just to see if they are safe and don't break other systems. You don't want to go without these for ANY extended periods of time.</TextBlock>
</StackPanel> </StackPanel>
</Border> </Border>
<Border Grid.Row="0" Grid.Column="2" Style="{StaticResource BorderStyle}"> <Border Grid.Row="0" Grid.Column="2" Style="{StaticResource BorderStyle}">
<StackPanel Background="{MainBackgroundColor}" SnapsToDevicePixels="True"> <StackPanel Background="{MainBackgroundColor}" SnapsToDevicePixels="True">
<Button Name="WPFUpdatesdisable" FontSize="{ConfigTabButtonFontSize}" Height="Auto" Width="Auto" Content="Disable ALL Updates (NOT RECOMMENDED!)" Margin="20,4,20,10" Padding="10,10,10,10"/> <Button Name="WPFUpdatesdisable" FontSize="{ConfigTabButtonFontSize}" Height="Auto" Width="Auto" Content="Disable ALL Updates (NOT RECOMMENDED!)" Margin="20,4,20,10" Padding="10,10,10,10"/>
<TextBlock Margin="20,0,20,0" Padding="10" TextWrapping="WrapWithOverflow" MaxWidth="300">This completely disables ALL Windows Updates and is NOT RECOMMENDED.<LineBreak/><LineBreak/> However, it can be suitable if you use your system for a select purpose and do not actively browse the internet. <LineBreak/><LineBreak/>Note: Your system will be easier to hack and infect without security updates.</TextBlock> <TextBlock Foreground="{ComboBoxForegroundColor}" Margin="20,0,20,0" Padding="10" TextWrapping="WrapWithOverflow" MaxWidth="300">This completely disables ALL Windows Updates and is NOT RECOMMENDED.<LineBreak/><LineBreak/> However, it can be suitable if you use your system for a select purpose and do not actively browse the internet. <LineBreak/><LineBreak/>Note: Your system will be easier to hack and infect without security updates.</TextBlock>
<TextBlock Text=" " Margin="20,0,20,0" Padding="10" TextWrapping="WrapWithOverflow" MaxWidth="300"/> <TextBlock Text=" " Margin="20,0,20,0" Padding="10" TextWrapping="WrapWithOverflow" MaxWidth="300"/>
</StackPanel> </StackPanel>
</Border> </Border>
@ -937,12 +946,12 @@
HorizontalAlignment="Stretch"> HorizontalAlignment="Stretch">
<StackPanel Name="MicrowinMain" Background="{MainBackgroundColor}" SnapsToDevicePixels="True" Grid.Column="0" Grid.Row="0"> <StackPanel Name="MicrowinMain" Background="{MainBackgroundColor}" SnapsToDevicePixels="True" Grid.Column="0" Grid.Row="0">
<StackPanel Background="Transparent" SnapsToDevicePixels="True" Margin="1"> <StackPanel Background="Transparent" SnapsToDevicePixels="True" Margin="1">
<CheckBox x:Name="WPFMicrowinDownloadFromGitHub" Content="Download oscdimg.exe from CTT Github repo" IsChecked="False" Margin="{CheckBoxMargin}" /> <CheckBox x:Name="WPFMicrowinDownloadFromGitHub" Content="Download oscdimg.exe from CTT Github repo" IsChecked="False" Margin="{MicrowinCheckBoxMargin}" />
<TextBlock Margin="5" Padding="1" TextWrapping="Wrap" Foreground="{ComboBoxForegroundColor}"> <TextBlock Margin="5" Padding="1" TextWrapping="Wrap" Foreground="{ComboBoxForegroundColor}">
Choose a Windows ISO file that you've downloaded <LineBreak/> Choose a Windows ISO file that you've downloaded <LineBreak/>
Check the status in the console Check the status in the console
</TextBlock> </TextBlock>
<CheckBox x:Name="WPFMicrowinISOScratchDir" Content="Use ISO directory for ScratchDir " IsChecked="False" Margin="{CheckBoxMargin}" <CheckBox x:Name="WPFMicrowinISOScratchDir" Content="Use ISO directory for ScratchDir " IsChecked="False" Margin="{MicrowinCheckBoxMargin}"
ToolTip="Use ISO directory for ScratchDir " /> ToolTip="Use ISO directory for ScratchDir " />
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@ -989,7 +998,7 @@
<TextBlock Margin="6" Padding="1" TextWrapping="Wrap">Choose Windows SKU</TextBlock> <TextBlock Margin="6" Padding="1" TextWrapping="Wrap">Choose Windows SKU</TextBlock>
<ComboBox x:Name = "MicrowinWindowsFlavors" Margin="1" /> <ComboBox x:Name = "MicrowinWindowsFlavors" Margin="1" />
<Rectangle Fill="{MainForegroundColor}" Height="2" HorizontalAlignment="Stretch" Margin="0,10,0,10"/> <Rectangle Fill="{MainForegroundColor}" Height="2" HorizontalAlignment="Stretch" Margin="0,10,0,10"/>
<CheckBox Name="MicrowinInjectDrivers" Content="Inject drivers (I KNOW WHAT I'M DOING)" Margin="-10,5,0,0" IsChecked="False" ToolTip="Path to unpacked drivers all sys and inf files for devices that need drivers"/> <CheckBox Name="MicrowinInjectDrivers" Content="Inject drivers (I KNOW WHAT I'M DOING)" Margin="{MicrowinCheckBoxMargin}" IsChecked="False" ToolTip="Path to unpacked drivers all sys and inf files for devices that need drivers"/>
<TextBox Name="MicrowinDriverLocation" Background="Transparent" BorderThickness="1" BorderBrush="{MainForegroundColor}" <TextBox Name="MicrowinDriverLocation" Background="Transparent" BorderThickness="1" BorderBrush="{MainForegroundColor}"
Margin="6" Margin="6"
Text="" Text=""
@ -998,9 +1007,9 @@
Foreground="{LabelboxForegroundColor}" Foreground="{LabelboxForegroundColor}"
ToolTip="Path to unpacked drivers all sys and inf files for devices that need drivers" ToolTip="Path to unpacked drivers all sys and inf files for devices that need drivers"
/> />
<CheckBox Name="MicrowinImportDrivers" Content="Import drivers from current system" Margin="{CheckBoxMargin}" IsChecked="False" ToolTip="Export all third-party drivers from your system and inject them to the MicroWin image"/> <CheckBox Name="MicrowinImportDrivers" Content="Import drivers from current system" Margin="{MicrowinCheckBoxMargin}" IsChecked="False" ToolTip="Export all third-party drivers from your system and inject them to the MicroWin image"/>
<Rectangle Fill="{MainForegroundColor}" Height="2" HorizontalAlignment="Stretch" Margin="0,10,0,10"/> <Rectangle Fill="{MainForegroundColor}" Height="2" HorizontalAlignment="Stretch" Margin="0,10,0,10"/>
<CheckBox Name="WPFMicrowinCopyToUsb" Content="Copy to Ventoy" Margin="{CheckBoxMargin}" IsChecked="False" ToolTip="Copy to USB disk with a label Ventoy"/> <CheckBox Name="WPFMicrowinCopyToUsb" Content="Copy to Ventoy" Margin="{MicrowinCheckBoxMargin}" IsChecked="False" ToolTip="Copy to USB disk with a label Ventoy"/>
<Rectangle Fill="{MainForegroundColor}" Height="2" HorizontalAlignment="Stretch" Margin="0,10,0,10"/> <Rectangle Fill="{MainForegroundColor}" Height="2" HorizontalAlignment="Stretch" Margin="0,10,0,10"/>
<TextBlock Margin="6" Padding="1" TextWrapping="Wrap"><Bold>Custom user settings (leave empty for default user)</Bold></TextBlock> <TextBlock Margin="6" Padding="1" TextWrapping="Wrap"><Bold>Custom user settings (leave empty for default user)</Bold></TextBlock>
<TextBlock Margin="6" Padding="1" TextWrapping="Wrap">User name (20 characters max.):</TextBlock> <TextBlock Margin="6" Padding="1" TextWrapping="Wrap">User name (20 characters max.):</TextBlock>