Compare commits

..

23 Commits

Author SHA1 Message Date
18466bc496 Update functions/public/Invoke-WPFUIElements.ps1
Co-authored-by: Mr.k <mineshtine28546271@gmail.com>
2024-08-20 15:00:52 +02:00
a17080f13b Merge branch 'ChrisTitusTech:main' into compact 2024-08-19 22:47:01 +02:00
c056bbcfe4 last fixes & add notes 2024-08-19 22:46:12 +02:00
6175c0889c fix typo 2024-08-19 13:46:21 +02:00
210f321a34 preprocessing 2024-08-19 13:40:24 +02:00
f0b4660478 Merge branch 'main' into compact 2024-08-19 13:34:33 +02:00
c24129387e fixes 2024-08-16 16:32:22 +02:00
80ca474891 fix border styling 2024-08-16 08:51:26 +02:00
a22d6b0d10 cleanup 2024-08-15 23:53:05 +02:00
4c6990b515 filter out unneeded categories 2024-08-15 22:30:57 +02:00
3f48c8aa70 fix ? issue in search 2024-08-15 21:52:43 +02:00
cdf36857c5 add image logic 2024-08-11 19:56:04 +02:00
e6e449af94 hotfixes 2024-08-11 18:23:05 +02:00
506c015496 some fixes 2024-08-11 14:06:46 +02:00
3be1999c22 hotfix
fix missing elements
fix var naming
2024-08-10 07:00:46 +02:00
b15f31fdf8 hotfix 2024-08-09 23:39:01 +02:00
47e80010d1 hotfixes
- reworked function calling
- working on correct theming support
2024-08-09 22:30:45 +02:00
1132d53944 move naming from winutil to wpf 2024-08-09 19:40:14 +02:00
bb39be794b fix toggle style 2024-08-07 21:27:07 +02:00
ec4cb1d520 removed unused replacementlogics 2024-08-07 00:31:43 +02:00
eaa19eba8a Merge branch 'ChrisTitusTech:main' into compact 2024-07-31 19:24:16 +02:00
dfe7dc4044 refractor
- removed Get-TabXaml.ps1
- removed compilation part from compile.ps1
- removed existing changes from main.ps1
- added Invoke-WinUtilUIElements.ps1
- refractor existing changes into new function
- modified inputXML to call function
2024-07-31 19:21:45 +02:00
4402c5cf31 try1: apps panel 2024-07-27 12:31:34 +02:00
74 changed files with 1608 additions and 2875 deletions

View File

@ -1,128 +0,0 @@
# 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.

117
.github/CONTRIBUTING.md vendored Normal file
View File

@ -0,0 +1,117 @@
# How to Contribute?
## Testing
* Test the latest changes to WinUtil by running the pre-release and reporting issues you are encountering to help us continually improve WinUtil!
#### **Run the latest pre-release**
```ps1
irm christitus.com/windev | iex
```
!!! bug "Keep in mind"
This is a pre-release and should be treated as such. It exists for developers to test the utility and report or fix bugs before they get added to the stable release. Don't use it in production!
## Issues
* If you encounter any challenges or problems with the script, I kindly request that you submit them via the "Issues" tab on the GitHub repository. By filling out the provided template, you can provide specific details about the issue, allowing me (and others in the community) to promptly address any bugs or consider feature requests.
## Contribute Code
* Pull requests are now handled directly on the **MAIN branch**. This was done since we can now select specific releases to launch via releases in GitHub.
* If you're doing code changes, then you can submit a PR to `main` branch, but I am very selective about these.
!!! warning "Important"
Do not use a code formatter, make massive amounts of line changes, or make multiple feature changes. EACH FEATURE CHANGE SHOULD BE IT'S OWN PULL REQUEST!
* When creating pull requests, it is essential to thoroughly document all changes made. This includes, but is not limited to, documenting any additions made to the `tweaks` section and corresponding `undo tweak`, so users are able to remove the newly added tweaks if necessary, and comprehensive documentation is required for all code changes. Document your changes and briefly explain why you made your changes in your Pull Request Description. Failure to adhere to this format may result in the denial of the pull request. Additionally, any code lacking sufficient documentation may also be denied.
* By following these guidelines, we can maintain a high standard of quality and ensure that the codebase remains organized and well-documented.
!!! note
When creating a function, please include "WPF" or "WinUtil" in the file name so it can be loaded into the runspace.
## Walk through
* This is a guide for beginners. If you are still having issues, look at the following official GitHub documentation:
* [Commit through WEB](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/about-commits)
* [Commit through GitHub Desktop](https://docs.github.com/en/desktop/making-changes-in-a-branch/committing-and-reviewing-changes-to-your-project-in-github-desktop#about-commits)
* [Create a Pull Request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request)
### Overview
``` mermaid
%%{init: {"flowchart": {"curve": "cardinal"}} }%%
graph TD
  A[Fork Project] --> B[Clone Repository];
  B --> C[Create New Branch];
  C --> D[Make Changes];
  D --> G[Test Changes];
  G --> H{Tests Passed?};
  H -->|Yes| E[Commit Changes];
  H -->|No| J[Fix Issues];
  J --> G;
  E --> F[Push Branch];
  F --> K[Create Pull Request];
  K --> L[Fill out PR template];
classDef default stroke:#333,stroke-width:4px,font-size:12pt;
```
!!! info
This is a diagram to guide you through the process. It may vary depending on the type of change you're making.
### Fork the Repo
* Fork the WinUtil Repository [here](https://github.com/ChrisTitusTech/winutil) to create a copy that will be available in your repository list.
![Fork Image](assets/Fork-Button-Dark.png#only-dark)
![Fork Image](assets/Fork-Button-Light.png#only-light)
### Clone the Fork
!!! tip
While you can make your changes directly through the Web, we recommend cloning the repo to your device using the application GitHub Desktop (available in WinUtil) to test your fork easily.
* Install GitHub Desktop if it is not already installed.
* Log in using the same GitHub account you used to fork WinUtil.
* Choose the fork under "Your Repositories" and press "clone {repo name}"
* Create a new branch and name it something relatable to your changes.
* Now you can modify WinUtil to your liking using your preferred text editor.
### Testing your changes
* To test to see if your changes work as intended run following commands in a powershell teminal as admin:
* Change the directory where you are running the commands to the forked project.
* `cd {path to the folder with the compile.ps1}`
* Run the following command to compile and run WinUtil:
* `.\Compile.ps1 -run`
![Compile](assets/Compile.png)
* After seeing that your changes work properly, feel free to commit the changes to the repository and make a PR. For help on that, follow the documentation below.
### Committing the changes
* Before committing your changes, please discard changes made to the `winutil.ps1` file, like the following:
![Push Commit Image](assets/Discard-GHD.png)
* Now, commit your changes once you are happy with the result.
![Commit Image](assets/Commit-GHD.png)
* Push the changes to upload them to your fork on github.com.
![Push Commit Image](assets/Push-Commit.png)
### Making a PR
* To make a PR on your repo under a new branch linking to the main branch, a button will show and say Preview and Create pull request. Click that button and fill in all the information that is provided on the template. Once all the information is filled in correctly, check your PR to make sure there is not a WinUtil.ps1 file attached to the PR. Once everything is good, make the PR and wait for Chris (the maintainer) to accept or deny your PR. Once it is accepted by Chris, you will be able to see your changes in the "/windev" build.
* If you do not see your feature in the main "/win" build, that is fine. All new changes go into the /windev build to make sure everything is working OK before going fully public.
* Congratulations! You just submitted your first PR. Thank you so much for contributing to WinUtil.

View File

@ -2,12 +2,12 @@
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: 'bug' labels: ''
assignees: '' assignees: ''
--- ---
## Describe the bug ## Describe the bug
<!-- A clear and concise description of what the bug is. --> A clear and concise description of what the bug is.
## To Reproduce ## To Reproduce
Steps to reproduce the behavior: Steps to reproduce the behavior:
@ -17,10 +17,10 @@ Steps to reproduce the behavior:
4. See error 4. See error
## Expected behavior ## Expected behavior
<!-- A clear and concise description of what you expected to happen. --> A clear and concise description of what you expected to happen.
## Screenshots ## Screenshots
<!-- If applicable, add screenshots to help explain your problem. --> If applicable, add screenshots to help explain your problem.
## Additional context ## Additional context
<!-- Add any other context about the problem here. --> Add any other context about the problem here.

View File

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

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2022 CT Tech Group LLC Copyright (c) 2022 Chris Titus
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

View File

@ -1,4 +1,7 @@
<!--Before you make this PR have you followed the docs here? - https://christitustech.github.io/winutil/contribute/ --> # Pull Request
## Title
[Provide a succinct and descriptive title for the pull request.]
## Type of Change ## Type of Change
- [ ] New feature - [ ] New feature
@ -10,20 +13,20 @@
- [ ] UI/UX improvement - [ ] UI/UX improvement
## Description ## Description
<!--[Provide a detailed explanation of the changes you have made. Include the reasons behind these changes and any relevant context. Link any related issues.]--> [Provide a detailed explanation of the changes you have made. Include the reasons behind these changes and any relevant context. Link any related issues.]
## Testing ## Testing
<!--[Detail the testing you have performed to ensure that these changes function as intended. Include information about any added tests.]--> [Detail the testing you have performed to ensure that these changes function as intended. Include information about any added tests.]
## Impact ## Impact
<!--[Discuss the impact of your changes on the project. This might include effects on performance, new dependencies, or changes in behaviour.]--> [Discuss the impact of your changes on the project. This might include effects on performance, new dependencies, or changes in behaviour.]
## Issue related to PR ## Issue related to PR
<!--[What issue/discussion is related to this PR (if any)]--> [What issue/discussion is related to this PR (if any)]
- Resolves # - Resolves #
## Additional Information ## Additional Information
<!--[Any additional information that reviewers should be aware of.]--> [Any additional information that reviewers should be aware of.]
## Checklist ## Checklist
- [ ] My code adheres to the coding and style guidelines of the project. - [ ] My code adheres to the coding and style guidelines of the project.

3
.github/mkdocs.yml vendored
View File

@ -11,9 +11,6 @@ nav:
- Known Issues: 'KnownIssues.md' - Known Issues: 'KnownIssues.md'
- FAQ: 'faq.md' - FAQ: 'faq.md'
not_in_nav: |
dev/
theme: theme:
name: material name: material
custom_dir: '../overrides' custom_dir: '../overrides'

View File

@ -1,54 +0,0 @@
tag-prefix: ''
categories:
- title: '🚀 Features'
labels:
- 'feature'
- 'enhancement'
- title: '🐛 Bug Fixes'
labels:
- 'fix'
- 'bugfix'
- 'bug'
- title: '📚 Documentation'
label: 'documentation'
- title: '🔒 Security'
label: 'security'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
template: |
## Changes
$CHANGES
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

@ -15,33 +15,18 @@ jobs:
contents: read contents: read
steps: steps:
- run: echo "command=false" >> $GITHUB_ENV - name: Check for /close comment
id: check_comment
- name: Check for /close command
id: check_close_command
run: | run: |
if [[ "${{ contains(github.event.comment.body, '/close') }}" == "true" ]]; then if [[ "${{ contains(github.event.comment.body, '/close') }}" == "true" ]]; then
echo "command=true" >> $GITHUB_ENV echo "comment=true" >> $GITHUB_ENV
echo "close_command=true" >> $GITHUB_ENV
echo "reopen_command=false" >> $GITHUB_ENV
else else
echo "close_command=false" >> $GITHUB_ENV echo "comment=false" >> $GITHUB_ENV
fi
- name: Check for /open or /reopen command
id: check_reopen_command
run: |
if [[ "${{ contains(github.event.comment.body, '/open') }}" == "true" ]] || [[ "${{ contains(github.event.comment.body, '/reopen') }}" == "true" ]]; then
echo "command=true" >> $GITHUB_ENV
echo "reopen_command=true" >> $GITHUB_ENV
echo "close_command=false" >> $GITHUB_ENV
else
echo "reopen_command=false" >> $GITHUB_ENV
fi fi
- name: Check if the user is allowed - name: Check if the user is allowed
id: check_user id: check_user
if: env.command == 'true' if: env.comment == 'true'
run: | run: |
ALLOWED_USERS=("ChrisTitusTech" "og-mrk" "Marterich" "MyDrift-user" "Real-MullaC") ALLOWED_USERS=("ChrisTitusTech" "og-mrk" "Marterich" "MyDrift-user" "Real-MullaC")
if [[ " ${ALLOWED_USERS[@]} " =~ " ${{ github.event.comment.user.login }} " ]]; then if [[ " ${ALLOWED_USERS[@]} " =~ " ${{ github.event.comment.user.login }} " ]]; then
@ -51,23 +36,10 @@ jobs:
fi fi
- name: Close issue if conditions are met - name: Close issue if conditions are met
if: env.close_command == 'true' && env.user == 'true' if: env.comment == 'true' && env.user == 'true'
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }} ISSUE_NUMBER: ${{ github.event.issue.number }}
run: | run: |
echo Closing the issue... echo Closing the issue...
if [[ "${{ contains(github.event.comment.body, 'not planned') }}" == "true" ]]; then
gh issue close $ISSUE_NUMBER --repo ${{ github.repository }} --reason 'not planned'
else
gh issue close $ISSUE_NUMBER --repo ${{ github.repository }} gh issue close $ISSUE_NUMBER --repo ${{ github.repository }}
fi
- name: Reopen issue if conditions are met
if: env.reopen_command == 'true' && env.user == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: |
echo Reopening the issue...
gh issue reopen $ISSUE_NUMBER --repo ${{ github.repository }}

View File

@ -22,8 +22,8 @@ jobs:
exempt-issue-labels: "Keep Issue Open" exempt-issue-labels: "Keep Issue Open"
# Split it into two weeks, after one week the issue will be marked as stale, # Split it into two weeks, after one week the issue will be marked as stale,
# after another week have pasted without any update.. the issue will then be closed. # after another week have pasted without any update.. the issue will then be closed.
days-before-issue-stale: 90 days-before-issue-stale: 7
days-before-issue-close: 365 days-before-issue-close: 7
# NEVER mark PRs as Stale or Close + this workflow should never have write permissions on PRs, EVER! # NEVER mark PRs as Stale or Close + this workflow should never have write permissions on PRs, EVER!
days-before-pr-stale: -1 days-before-pr-stale: -1
days-before-pr-close: -1 days-before-pr-close: -1

View File

@ -7,7 +7,6 @@ on:
- '.github/requirements.txt' - '.github/requirements.txt'
- 'docs/**' - 'docs/**'
- 'overrides/**' - 'overrides/**'
- '.github/CONTRIBUTING.md'
workflow_dispatch: workflow_dispatch:
jobs: jobs:

View File

@ -74,27 +74,16 @@ jobs:
name: winutil name: winutil
path: ./winutil.ps1 path: ./winutil.ps1
- name: Generate Release Notes
id: generate_notes
uses: release-drafter/release-drafter@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
config-name: release-drafter.yml
version: ${{ env.VERSION }} # Pass the version variable
- 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: "![GitHub Downloads (specific asset, specific tag)](https://img.shields.io/github/downloads/ChrisTitusTech/winutil/${{ env.VERSION }}/winutil.ps1)"
${{ steps.generate_notes.outputs.body }}
![GitHub Downloads (specific asset, specific tag)](https://img.shields.io/github/downloads/ChrisTitusTech/winutil/${{ env.VERSION }}/winutil.ps1)
append_body: false append_body: false
files: ./winutil.ps1 files: ./winutil.ps1
prerelease: true prerelease: true
generate_release_notes: true
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,21 +1,12 @@
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
@ -50,11 +41,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"
. $preprocessingFilePath . "$(($workingdir -replace ('\\$', '')) + '\' + ($preprocessingFilePath -replace ('\.\\', '')))"
$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 -ThrowExceptionOnEmptyFilesList Invoke-Preprocessing -WorkingDir "$workingdir" -ExcludedFiles $excludedFiles -ProgressStatusMessage $msg
} }
# Create the script in memory. # Create the script in memory.
@ -65,81 +56,96 @@ 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 "scripts\start.ps1").replace('#{replaceme}',"$(Get-Date -Format yy.MM.dd)")) $script_content.Add($(Get-Content "$workingdir\scripts\start.ps1").replace('#{replaceme}',"$(Get-Date -Format yy.MM.dd)"))
Update-Progress "Adding: Functions" 20 Update-Progress "Adding: Functions" 20
Get-ChildItem "functions" -Recurse -File | ForEach-Object { Get-ChildItem "$workingdir\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 "config" | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object { Get-ChildItem "$workingdir\config" | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object {
$json = (Get-Content $psitem.FullName -Raw)
$jsonAsObject = $json | ConvertFrom-Json $json = (Get-Content $psitem.FullName).replace("'","''")
# Replace every XML Special Character so it'll render correctly in final build
# Only do so if json files has content to be displayed (for example the applications, tweaks, features json files)
# Make an Array List containing every name at first level of Json File
$jsonAsObject = $json | convertfrom-json
$firstLevelJsonList = [System.Collections.ArrayList]::new()
$jsonAsObject.PSObject.Properties.Name | ForEach-Object {$null = $firstLevelJsonList.Add($_)}
# Note:
# Avoid using HTML Entity Codes, for example '&rdquo;' (stands for "Right Double Quotation Mark"),
# Use **HTML decimal/hex codes instead**, as using HTML Entity Codes will result in XML parse Error when running the compiled script.
for ($i = 0; $i -lt $firstLevelJsonList.Count; $i += 1) {
$firstLevelName = $firstLevelJsonList[$i]
if ($jsonAsObject.$firstLevelName.content -ne $null) {
$jsonAsObject.$firstLevelName.content = $jsonAsObject.$firstLevelName.content.replace('&','&#38;').replace('“','&#8220;').replace('”','&#8221;').replace("'",'&#39;').replace('<','&#60;').replace('>','&#62;').replace('—','&#8212;')
$jsonAsObject.$firstLevelName.content = $jsonAsObject.$firstLevelName.content.replace('&#39;&#39;',"&#39;") # resolves the Double Apostrophe caused by the first replace function in the main loop
}
if ($jsonAsObject.$firstLevelName.description -ne $null) {
$jsonAsObject.$firstLevelName.description = $jsonAsObject.$firstLevelName.description.replace('&','&#38;').replace('“','&#8220;').replace('”','&#8221;').replace("'",'&#39;').replace('<','&#60;').replace('>','&#62;').replace('—','&#8212;')
$jsonAsObject.$firstLevelName.description = $jsonAsObject.$firstLevelName.description.replace('&#39;&#39;',"&#39;") # resolves the Double Apostrophe caused by the first replace function in the main loop
}
}
# Add 'WPFInstall' as a prefix to every entry-name in 'applications.json' file # Add 'WPFInstall' as a prefix to every entry-name in 'applications.json' file
if ($psitem.Name -eq "applications.json") { if ($psitem.Name -eq "applications.json") {
foreach ($appEntryName in $jsonAsObject.PSObject.Properties.Name) { for ($i = 0; $i -lt $firstLevelJsonList.Count; $i += 1) {
$appEntryName = $firstLevelJsonList[$i]
$appEntryContent = $jsonAsObject.$appEntryName $appEntryContent = $jsonAsObject.$appEntryName
# Remove the entire app entry, so we could add it later with a different name
$jsonAsObject.PSObject.Properties.Remove($appEntryName) $jsonAsObject.PSObject.Properties.Remove($appEntryName)
# Add the app entry, but with a different name (WPFInstall + The App Entry Name)
$jsonAsObject | Add-Member -MemberType NoteProperty -Name "WPFInstall$appEntryName" -Value $appEntryContent $jsonAsObject | Add-Member -MemberType NoteProperty -Name "WPFInstall$appEntryName" -Value $appEntryContent
} }
} }
# Line 90 requires no whitespace inside the here-strings, to keep formatting of the JSON in the final script. # The replace at the end is required, as without it the output of 'converto-json' will be somewhat weird for Multiline Strings
$json = @" # Most Notably is the scripts in some json files, making it harder for users who want to review these scripts, which're found in the compiled script
$($jsonAsObject | ConvertTo-Json -Depth 3) $json = ($jsonAsObject | convertto-json -Depth 3).replace('\r\n',"`r`n")
"@
$sync.configs.$($psitem.BaseName) = $json | ConvertFrom-Json $sync.configs.$($psitem.BaseName) = $json | convertfrom-json
$script_content.Add($(Write-Output "`$sync.configs.$($psitem.BaseName) = @'`n$json`n'@ `| ConvertFrom-Json" )) $script_content.Add($(Write-output "`$sync.configs.$($psitem.BaseName) = '$json' `| convertfrom-json" ))
} }
# Read the entire XAML file as a single string, preserving line breaks $xaml = (Get-Content "$workingdir\xaml\inputXML.xaml").replace("'","''")
$xaml = Get-Content "$workingdir\xaml\inputXML.xaml" -Raw
Update-Progress "Adding: Xaml " 90 Update-Progress "Adding: Xaml " 90
# Add the XAML content to $script_content using a here-string $script_content.Add($(Write-output "`$inputXML = '$xaml'"))
$script_content.Add(@"
`$inputXML = @'
$xaml
'@
"@)
$script_content.Add($(Get-Content "scripts\main.ps1")) $script_content.Add($(Get-Content "$workingdir\scripts\main.ps1"))
if ($Debug) { if ($Debug) {
Update-Progress "Writing debug files" 95 Update-Progress "Writing debug files" 95
$appXamlContent | Out-File -FilePath "xaml\inputApp.xaml" -Encoding ascii $appXamlContent | Out-File -FilePath "$workingdir\xaml\inputApp.xaml" -Encoding ascii
$tweaksXamlContent | Out-File -FilePath "xaml\inputTweaks.xaml" -Encoding ascii $tweaksXamlContent | Out-File -FilePath "$workingdir\xaml\inputTweaks.xaml" -Encoding ascii
$featuresXamlContent | Out-File -FilePath "xaml\inputFeatures.xaml" -Encoding ascii $featuresXamlContent | Out-File -FilePath "$workingdir\xaml\inputFeatures.xaml" -Encoding ascii
} else { } else {
Update-Progress "Removing temporary files" 99 Update-Progress "Removing temporary files" 99
Remove-Item "xaml\inputApp.xaml" -ErrorAction SilentlyContinue Remove-Item "$workingdir\xaml\inputApp.xaml" -ErrorAction SilentlyContinue
Remove-Item "xaml\inputTweaks.xaml" -ErrorAction SilentlyContinue Remove-Item "$workingdir\xaml\inputTweaks.xaml" -ErrorAction SilentlyContinue
Remove-Item "xaml\inputFeatures.xaml" -ErrorAction SilentlyContinue Remove-Item "$workingdir\xaml\inputFeatures.xaml" -ErrorAction SilentlyContinue
} }
Set-Content -Path "$scriptname" -Value ($script_content -join "`r`n") -Encoding ascii Set-Content -Path "$workingdir\$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) {
$script = "& '$workingdir\$scriptname' $Arguments" try {
Start-Process -FilePath "pwsh" -ArgumentList "$workingdir\$scriptname"
$powershellcmd = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" } } catch {
$processCmd = if (Get-Command wt.exe -ErrorAction SilentlyContinue) { "wt.exe" } else { $powershellcmd } Start-Process -FilePath "powershell" -ArgumentList "$workingdir\$scriptname"
}
Start-Process $processCmd -ArgumentList "$powershellcmd -NoProfile -Command $script"
break
} }
Pop-Location

File diff suppressed because one or more lines are too long

View File

@ -87,6 +87,14 @@
"link": "https://anydesk.com/", "link": "https://anydesk.com/",
"winget": "AnyDeskSoftwareGmbH.AnyDesk" "winget": "AnyDeskSoftwareGmbH.AnyDesk"
}, },
"ATLauncher": {
"category": "Games",
"choco": "na",
"content": "ATLauncher",
"description": "ATLauncher is a Launcher for Minecraft which integrates multiple different ModPacks to allow you to download and install ModPacks easily and quickly.",
"link": "https://github.com/ATLauncher/ATLauncher",
"winget": "ATLauncher.ATLauncher"
},
"audacity": { "audacity": {
"category": "Multimedia Tools", "category": "Multimedia Tools",
"choco": "audacity", "choco": "audacity",
@ -503,6 +511,14 @@
"link": "https://www.epicgames.com/store/en-US/", "link": "https://www.epicgames.com/store/en-US/",
"winget": "EpicGames.EpicGamesLauncher" "winget": "EpicGames.EpicGamesLauncher"
}, },
"errorlookup": {
"category": "Utilities",
"choco": "na",
"content": "Windows Error Code Lookup",
"description": "ErrorLookup is a tool for looking up Windows error codes and their descriptions.",
"link": "https://github.com/HenryPP/ErrorLookup",
"winget": "Henry++.ErrorLookup"
},
"esearch": { "esearch": {
"category": "Utilities", "category": "Utilities",
"choco": "everything", "choco": "everything",
@ -797,7 +813,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.GoogleDrive" "winget": "Google.Drive"
}, },
"gpuz": { "gpuz": {
"category": "Utilities", "category": "Utilities",
@ -2855,6 +2871,14 @@
"link": "https://www.kicad.org/", "link": "https://www.kicad.org/",
"winget": "KiCad.KiCad" "winget": "KiCad.KiCad"
}, },
"FormatFactory": {
"category": "Utilities",
"choco": "formatfactory",
"content": "Format Factory",
"description":"FormatFactory is an ad-supported freeware multimedia converter that can convert video, audio, and picture files. It is also capable of ripping DVDs and CDs to other file formats, as well as creating .iso images. It can also join multiple video files together into one.",
"link": "http://www.pcfreetime.com/formatfactory/",
"winget": "na"
},
"dropox": { "dropox": {
"category": "Utilities", "category": "Utilities",
"choco": "na", "choco": "na",

View File

@ -46,23 +46,5 @@
"Secondary": "94.140.15.16", "Secondary": "94.140.15.16",
"Primary6": "2a10:50c0::bad1:ff", "Primary6": "2a10:50c0::bad1:ff",
"Secondary6": "2a10:50c0::bad2:ff" "Secondary6": "2a10:50c0::bad2:ff"
},
"dns0.eu_Open":{
"Primary": "193.110.81.254",
"Secondary": "185.253.5.254",
"Primary6": "2a0f:fc80::ffff",
"Secondary6": "2a0f:fc81::ffff"
},
"dns0.eu_ZERO":{
"Primary": "193.110.81.9",
"Secondary": "185.253.5.9",
"Primary6": "2a0f:fc80::9",
"Secondary6": "2a0f:fc81::9"
},
"dns0.eu_KIDS":{
"Primary": "193.110.81.1",
"Secondary": "185.253.5.1",
"Primary6": "2a0f:fc80::1",
"Secondary6": "2a0f:fc81::1"
} }
} }

View File

@ -282,14 +282,6 @@
"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",
@ -305,21 +297,5 @@
"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"
},
"WPFWinUtilSSHServer": {
"Content": "Enable OpenSSH Server",
"category": "Remote Access",
"panel": "2",
"Order": "a084_",
"Type": "Button",
"ButtonWidth": "300"
},
} }

View File

@ -14,7 +14,7 @@
"WPFTweaksDeleteTempFiles", "WPFTweaksDeleteTempFiles",
"WPFTweaksEndTaskOnTaskbar", "WPFTweaksEndTaskOnTaskbar",
"WPFTweaksRestorePoint", "WPFTweaksRestorePoint",
"WPFTweaksIPv46", "WPFTweaksTeredo",
"WPFTweaksPowershell7Tele" "WPFTweaksPowershell7Tele"
], ],
"Minimal": [ "Minimal": [

View File

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

View File

@ -1600,6 +1600,13 @@
"Value": "0", "Value": "0",
"OriginalValue": "1" "OriginalValue": "1"
}, },
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "EdgeEnhanceImagesEnabled",
"Type": "DWord",
"Value": "0",
"OriginalValue": "1"
},
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "PersonalizationReportingEnabled", "Name": "PersonalizationReportingEnabled",
@ -1649,6 +1656,13 @@
"Value": "0", "Value": "0",
"OriginalValue": "1" "OriginalValue": "1"
}, },
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "EdgeFollowEnabled",
"Type": "DWord",
"Value": "0",
"OriginalValue": "1"
},
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "EdgeShoppingAssistantEnabled", "Name": "EdgeShoppingAssistantEnabled",
@ -1712,6 +1726,13 @@
"Value": "0", "Value": "0",
"OriginalValue": "1" "OriginalValue": "1"
}, },
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "ConfigureDoNotTrack",
"Type": "DWord",
"Value": "1",
"OriginalValue": "0"
},
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "WalletDonationEnabled", "Name": "WalletDonationEnabled",
@ -2409,6 +2430,12 @@
"Order": "a001_", "Order": "a001_",
"InvokeScript": [ "InvokeScript": [
" "
# Check if the user has administrative privileges
if (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Host \"Please run this script as an administrator.\"
return
}
# Check if System Restore is enabled for the main drive # Check if System Restore is enabled for the main drive
try { try {
# Try getting restore points to check if System Restore is enabled # Try getting restore points to check if System Restore is enabled
@ -2686,9 +2713,6 @@
reg delete \"HKEY_USERS\\Default\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" /v \"OneDriveSetup\" /f reg delete \"HKEY_USERS\\Default\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" /v \"OneDriveSetup\" /f
reg unload \"hku\\Default\" reg unload \"hku\\Default\"
Write-Host \"Removing autostart key\"
reg delete \"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\" /v \"OneDrive\" /f
Write-Host \"Removing startmenu entry\" Write-Host \"Removing startmenu entry\"
Remove-Item -Force -ErrorAction SilentlyContinue \"$env:userprofile\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\OneDrive.lnk\" Remove-Item -Force -ErrorAction SilentlyContinue \"$env:userprofile\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\OneDrive.lnk\"
@ -2740,48 +2764,6 @@
], ],
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveOnedrive" "link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveOnedrive"
}, },
"WPFTweaksRazerBlock": {
"Content": "Block Razer Software Installs",
"Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.",
"category": "z__Advanced Tweaks - CAUTION",
"panel": "1",
"Order": "a031_",
"registry": [
{
"Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DriverSearching",
"Name": "SearchOrderConfig",
"Value": "0",
"OriginalValue": "1",
"Type": "DWord"
},
{
"Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Device Installer",
"Name": "DisableCoInstallers",
"Value": "1",
"OriginalValue": "0",
"Type": "DWord"
}
],
"InvokeScript": [
"
$RazerPath = \"C:\\Windows\\Installer\\Razer\"
Remove-Item $RazerPath -Recurse -Force
New-Item -Path \"C:\\Windows\\Installer\\\" -Name \"Razer\" -ItemType \"directory\"
$Acl = Get-Acl $RazerPath
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule(\"NT AUTHORITY\\SYSTEM\",\"Write\",\"ContainerInherit,ObjectInherit\",\"None\",\"Deny\")
$Acl.SetAccessRule($Ar)
Set-Acl $RazerPath $Acl
"
],
"UndoScript": [
"
$RazerPath = \"C:\\Windows\\Installer\\Razer\"
Remove-Item $RazerPath -Recurse -Force
New-Item -Path \"C:\\Windows\\Installer\\\" -Name \"Razer\" -ItemType \"directory\"
"
],
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/RazerBlock"
},
"WPFTweaksDisableNotifications": { "WPFTweaksDisableNotifications": {
"Content": "Disable Notification Tray/Calendar", "Content": "Disable Notification Tray/Calendar",
"Description": "Disables all Notifications INCLUDING Calendar", "Description": "Disables all Notifications INCLUDING Calendar",
@ -3159,29 +3141,12 @@
], ],
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DVR" "link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DVR"
}, },
"WPFTweaksIPv46": { "WPFTweaksTeredo": {
"Content": "Prefer IPv4 over IPv6", "Content": "Disable Teredo",
"Description": "To set the IPv4 preference can have latency and security benefits on private networks where IPv6 is not configured.", "Description": "Teredo network tunneling is a ipv6 feature that can cause additional latency.",
"category": "Essential Tweaks", "category": "Essential Tweaks",
"panel": "1", "panel": "1",
"Order": "a005_", "Order": "a005_",
"registry": [
{
"Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters",
"Name": "DisabledComponents",
"Value": "32",
"OriginalValue": "0",
"Type": "DWord"
}
],
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/IPv46"
},
"WPFTweaksTeredo": {
"Content": "Disable Teredo",
"Description": "Teredo network tunneling is a ipv6 feature that can cause additional latency, but may cause problems with some games",
"category": "z__Advanced Tweaks - CAUTION",
"panel": "1",
"Order": "a023_",
"registry": [ "registry": [
{ {
"Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters", "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters",
@ -3197,7 +3162,7 @@
"UndoScript": [ "UndoScript": [
"netsh interface teredo set state default" "netsh interface teredo set state default"
], ],
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/Teredo" "link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/Teredo"
}, },
"WPFTweaksDisableipsix": { "WPFTweaksDisableipsix": {
"Content": "Disable IPv6", "Content": "Disable IPv6",
@ -3414,9 +3379,25 @@
"panel": "1", "panel": "1",
"Order": "a040_", "Order": "a040_",
"Type": "Combobox", "Type": "Combobox",
"ComboItems": "Default DHCP Google Cloudflare Cloudflare_Malware Cloudflare_Malware_Adult Open_DNS Quad9 AdGuard_Ads_Trackers AdGuard_Ads_Trackers_Malware_Adult dns0.eu_Open dns0.eu_ZERO dns0.eu_KIDS", "ComboItems": "Default DHCP Google Cloudflare Cloudflare_Malware Cloudflare_Malware_Adult Open_DNS Quad9 AdGuard_Ads_Trackers AdGuard_Ads_Trackers_Malware_Adult",
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/changedns" "link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/changedns"
}, },
"WPFTweaksbutton": {
"Content": "Run Tweaks",
"category": "z__Advanced Tweaks - CAUTION",
"panel": "1",
"Order": "a041_",
"Type": "Button",
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/button"
},
"WPFUndoall": {
"Content": "Undo Selected Tweaks",
"category": "z__Advanced Tweaks - CAUTION",
"panel": "1",
"Order": "a042_",
"Type": "Button",
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/Undoall"
},
"WPFAddUltPerf": { "WPFAddUltPerf": {
"Content": "Add and Activate Ultimate Performance Profile", "Content": "Add and Activate Ultimate Performance Profile",
"category": "Performance Plans", "category": "Performance Plans",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

After

Width:  |  Height:  |  Size: 152 KiB

View File

@ -1,117 +1,3 @@
# How to Contribute? --8<-- ".github/CONTRIBUTING.md"
## Testing <!-- The content is sourced from "CONTRIBUTING.md," located in the root directory of the project. -->
* Test the latest changes to WinUtil by running the pre-release and reporting issues you are encountering to help us continually improve WinUtil!
#### **Run the latest pre-release**
```ps1
irm christitus.com/windev | iex
```
!!! bug "Keep in mind"
This is a pre-release and should be treated as such. It exists for developers to test the utility and report or fix bugs before they get added to the stable release. Don't use it in production!
## Issues
* If you encounter any challenges or problems with the script, I kindly request that you submit them via the "Issues" tab on the GitHub repository. By filling out the provided template, you can provide specific details about the issue, allowing me (and others in the community) to promptly address any bugs or consider feature requests.
## Contribute Code
* Pull requests are now handled directly on the **MAIN branch**. This was done since we can now select specific releases to launch via releases in GitHub.
* If you're doing code changes, then you can submit a PR to `main` branch, but I am very selective about these.
!!! warning "Important"
Do not use a code formatter, make massive amounts of line changes, or make multiple feature changes. EACH FEATURE CHANGE SHOULD BE IT'S OWN PULL REQUEST!
* When creating pull requests, it is essential to thoroughly document all changes made. This includes, but is not limited to, documenting any additions made to the `tweaks` section and corresponding `undo tweak`, so users are able to remove the newly added tweaks if necessary, and comprehensive documentation is required for all code changes. Document your changes and briefly explain why you made your changes in your Pull Request Description. Failure to adhere to this format may result in the denial of the pull request. Additionally, any code lacking sufficient documentation may also be denied.
* By following these guidelines, we can maintain a high standard of quality and ensure that the codebase remains organized and well-documented.
!!! note
When creating a function, please include "WPF" or "WinUtil" in the file name so it can be loaded into the runspace.
## Walk through
* This is a guide for beginners. If you are still having issues, look at the following official GitHub documentation:
* [Commit through WEB](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/about-commits)
* [Commit through GitHub Desktop](https://docs.github.com/en/desktop/making-changes-in-a-branch/committing-and-reviewing-changes-to-your-project-in-github-desktop#about-commits)
* [Create a Pull Request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request)
### Overview
``` mermaid
%%{init: {"flowchart": {"curve": "cardinal"}} }%%
graph TD
  A[Fork Project] --> B[Clone Repository];
  B --> C[Create New Branch];
  C --> D[Make Changes];
  D --> G[Test Changes];
  G --> H{Tests Passed?};
  H -->|Yes| E[Commit Changes];
  H -->|No| J[Fix Issues];
  J --> G;
  E --> F[Push Branch];
  F --> K[Create Pull Request];
  K --> L[Fill out PR template];
classDef default stroke:#333,stroke-width:4px,font-size:12pt;
```
!!! info
This is a diagram to guide you through the process. It may vary depending on the type of change you're making.
### Fork the Repo
* Fork the WinUtil Repository [here](https://github.com/ChrisTitusTech/winutil) to create a copy that will be available in your repository list.
![Fork Image](assets/Fork-Button-Dark.png#only-dark#gh-dark-mode-only)
![Fork Image](assets/Fork-Button-Light.png#only-light#gh-light-mode-only)
### Clone the Fork
!!! tip
While you can make your changes directly through the Web, we recommend cloning the repo to your device using the application GitHub Desktop (available in WinUtil) to test your fork easily.
* Install GitHub Desktop if it is not already installed.
* Log in using the same GitHub account you used to fork WinUtil.
* Choose the fork under "Your Repositories" and press "clone {repo name}"
* Create a new branch and name it something relatable to your changes.
* Now you can modify WinUtil to your liking using your preferred text editor.
### Testing your changes
* To test to see if your changes work as intended run following commands in a powershell teminal as admin:
* Change the directory where you are running the commands to the forked project.
* `cd {path to the folder with the compile.ps1}`
* Run the following command to compile and run WinUtil:
* `.\Compile.ps1 -run`
![Compile](assets/Compile.png)
* After seeing that your changes work properly, feel free to commit the changes to the repository and make a PR. For help on that, follow the documentation below.
### Committing the changes
* Before committing your changes, please discard changes made to the `winutil.ps1` file, like the following:
![Push Commit Image](assets/Discard-GHD.png)
* Now, commit your changes once you are happy with the result.
![Commit Image](assets/Commit-GHD.png)
* Push the changes to upload them to your fork on github.com.
![Push Commit Image](assets/Push-Commit.png)
### Making a PR
* To make a PR on your repo under a new branch linking to the main branch, a button will show and say Preview and Create pull request. Click that button and fill in all the information that is provided on the template. Once all the information is filled in correctly, check your PR to make sure there is not a WinUtil.ps1 file attached to the PR. Once everything is good, make the PR and wait for Chris (the maintainer) to accept or deny your PR. Once it is accepted by Chris, you will be able to see your changes in the "/windev" build.
* If you do not see your feature in the main "/win" build, that is fine. All new changes go into the /windev build to make sure everything is working OK before going fully public.
* Congratulations! You just submitted your first PR. Thank you so much for contributing to WinUtil.

View File

@ -1,65 +0,0 @@
# 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

@ -1,63 +0,0 @@
# Prefer IPv4 over IPv6
Last Updated: 2024-08-27
!!! 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.**
## Description
To set the IPv4 preference can have latency and security benefits on private networks where IPv6 is not configured.
<!-- BEGIN CUSTOM CONTENT -->
<!-- END CUSTOM CONTENT -->
<details>
<summary>Preview Code</summary>
```json
{
"Content": "Prefer IPv4 over IPv6",
"Description": "To set the IPv4 preference can have latency and security benefits on private networks where IPv6 is not configured.",
"category": "Essential Tweaks",
"panel": "1",
"Order": "a005_",
"registry": [
{
"Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters",
"Name": "DisabledComponents",
"Value": "32",
"OriginalValue": "0",
"Type": "DWord"
}
],
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/IPv46"
}
```
</details>
## Registry Changes
Applications and System Components store and retrieve configuration data to modify windows settings, so we can use the registry to change many settings in one place.
You can find information about the registry on [Wikipedia](https://www.wikiwand.com/en/Windows_Registry) and [Microsoft's Website](https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry).
### Registry Key: DisabledComponents
**Type:** DWord
**Original Value:** 0
**New Value:** 32
<!-- BEGIN SECOND CUSTOM CONTENT -->
<!-- END SECOND CUSTOM CONTENT -->
[View the JSON file](https://github.com/ChrisTitusTech/winutil/tree/main/config/tweaks.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..."
Install-WinUtilProgramWinget -Action Install -Programs @("Microsoft.PowerShell") Invoke-WinUtilWingetProgram -Action Install -Programs @("Microsoft.PowerShell")
} }
$targetTerminalName = "PowerShell" $targetTerminalName = "PowerShell"
} }
@ -105,10 +105,10 @@ function Invoke-WPFTweakPS7{
} }
``` ```
## Function: Install-WinUtilProgramWinget ## Function: Invoke-WinUtilWingetProgram
```powershell ```powershell
Function Install-WinUtilProgramWinget { Function Invoke-WinUtilWingetProgram {
<# <#
.SYNOPSIS .SYNOPSIS
Runs the designated action on the provided programs using Winget Runs the designated action on the provided programs using Winget

View File

@ -1,13 +1,13 @@
# Disable Teredo # Disable Teredo
Last Updated: 2024-08-27 Last Updated: 2024-08-07
!!! info !!! 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.** 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.**
## Description ## Description
Teredo network tunneling is a ipv6 feature that can cause additional latency, but may cause problems with some games Teredo network tunneling is a ipv6 feature that can cause additional latency.
<!-- BEGIN CUSTOM CONTENT --> <!-- BEGIN CUSTOM CONTENT -->
@ -19,10 +19,10 @@ Teredo network tunneling is a ipv6 feature that can cause additional latency, bu
```json ```json
{ {
"Content": "Disable Teredo", "Content": "Disable Teredo",
"Description": "Teredo network tunneling is a ipv6 feature that can cause additional latency, but may cause problems with some games", "Description": "Teredo network tunneling is a ipv6 feature that can cause additional latency.",
"category": "z__Advanced Tweaks - CAUTION", "category": "Essential Tweaks",
"panel": "1", "panel": "1",
"Order": "a023_", "Order": "a005_",
"registry": [ "registry": [
{ {
"Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters", "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters",
@ -38,7 +38,7 @@ Teredo network tunneling is a ipv6 feature that can cause additional latency, bu
"UndoScript": [ "UndoScript": [
"netsh interface teredo set state default" "netsh interface teredo set state default"
], ],
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/Teredo" "link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/Teredo"
} }
``` ```

View File

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

View File

@ -29,14 +29,8 @@
* Click the `Clear Selection` button. * Click the `Clear Selection` button.
* This will unselect all checked programs. * This will unselect all checked programs.
=== "prefer Chocolatey" ![Install Image](assets/Install-Tab-Dark.png#only-dark)
* Check the `prefer Chocolatey` checkbox ![Install Image](assets/Install-Tab-Light.png#only-light)
* 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#gh-dark-mode-only)
![Install Image](assets/Install-Tab-Light.png#only-light#gh-light-mode-only)
!!! tip !!! tip
If you have trouble finding an application, press `ctrl + f` and search the name of it. Applications will filter depending on your input. If you have trouble finding an application, press `ctrl + f` and search the name of it. Applications will filter depending on your input.
@ -44,8 +38,8 @@
## Tweaks ## Tweaks
--- ---
![Tweaks Image](assets/Tweaks-Tab-Dark.png#only-dark#gh-dark-mode-only) ![Tweaks Image](assets/Tweaks-Tab-Dark.png#only-dark)
![Tweaks Image](assets/Tweaks-Tab-Light.png#only-light#gh-light-mode-only) ![Tweaks Image](assets/Tweaks-Tab-Light.png#only-light)
### Run Tweaks ### Run Tweaks
* **Open Tweaks Tab**: Navigate to the 'Tweaks' tab in the application. * **Open Tweaks Tab**: Navigate to the 'Tweaks' tab in the application.
@ -142,10 +136,6 @@ Open old-school Windows panels directly from WinUtil. Following Panels are avail
* System Properties * System Properties
* User Accounts * User Accounts
### Remote Access
Enables OpenSSH server on your windows machine.
## Updates ## Updates
--- ---
@ -180,8 +170,8 @@ The utility provides three distinct settings for managing Windows updates: Defau
* **MicroWin** lets you customize your Windows 10 and 11 installation images by debloating them however you want. * **MicroWin** lets you customize your Windows 10 and 11 installation images by debloating them however you want.
![Microwin](assets/Microwin-Dark.png#only-dark#gh-dark-mode-only) ![Microwin](assets/Microwin-Dark.png#only-dark)
![Microwin](assets/Microwin-Light.png#only-light#gh-light-mode-only) ![Microwin](assets/Microwin-Light.png#only-light)
#### Basic usage #### Basic usage
@ -239,12 +229,12 @@ With MicroWin, you can also configure your user before proceeding if you don't w
* Some features are available through automation. This allows you to save your config file, pass it to WinUtil, walk away and come back to a finished system. Here is how you can set it up currently with Winutil >24.01.15 * Some features are available through automation. This allows you to save your config file, pass it to WinUtil, walk away and come back to a finished system. Here is how you can set it up currently with Winutil >24.01.15
* On the Install Tab, click "Get Installed", this will get all installed apps **supported by Winutil** on the system. * On the Install Tab, click "Get Installed", this will get all installed apps **supported by Winutil** on the system.
![GetInstalled](assets/Get-Installed-Dark.png#only-dark#gh-dark-mode-only) ![GetInstalled](assets/Get-Installed-Dark.png#only-dark)
![GetInstalled](assets/Get-Installed-Light.png#only-light#gh-light-mode-only) ![GetInstalled](assets/Get-Installed-Light.png#only-light)
* Click on the Settings cog in the upper right corner and choose Export. Choose file file and location; this will export the setting file. * Click on the Settings cog in the upper right corner and choose Export. Choose file file and location; this will export the setting file.
![SettingsExport](assets/Settings-Export-Dark.png#only-dark#gh-dark-mode-only) ![SettingsExport](assets/Settings-Export-Dark.png#only-dark)
![SettingsExport](assets/Settings-Export-Light.png#only-light#gh-light-mode-only) ![SettingsExport](assets/Settings-Export-Light.png#only-light)
* Copy this file to a USB or somewhere you can use it after Windows installation. * Copy this file to a USB or somewhere you can use it after Windows installation.

View File

@ -0,0 +1,92 @@
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

@ -16,72 +16,136 @@ Function Get-WinUtilToggleStatus {
if($ToggleSwitch -eq "WPFToggleDarkMode") { if($ToggleSwitch -eq "WPFToggleDarkMode") {
$app = (Get-ItemProperty -path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize').AppsUseLightTheme $app = (Get-ItemProperty -path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize').AppsUseLightTheme
$system = (Get-ItemProperty -path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize').SystemUsesLightTheme $system = (Get-ItemProperty -path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize').SystemUsesLightTheme
return $app -eq 0 -and $system -eq 0 if($app -eq 0 -and $system -eq 0) {
return $true
} else {
return $false
}
} }
if($ToggleSwitch -eq "WPFToggleBingSearch") { if($ToggleSwitch -eq "WPFToggleBingSearch") {
$bingsearch = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Search').BingSearchEnabled $bingsearch = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Search').BingSearchEnabled
return $bingsearch -ne 0 if($bingsearch -eq 0) {
return $false
} else {
return $true
}
} }
if($ToggleSwitch -eq "WPFToggleNumLock") { if($ToggleSwitch -eq "WPFToggleNumLock") {
$numlockvalue = (Get-ItemProperty -path 'HKCU:\Control Panel\Keyboard').InitialKeyboardIndicators $numlockvalue = (Get-ItemProperty -path 'HKCU:\Control Panel\Keyboard').InitialKeyboardIndicators
return $numlockvalue -eq 2 if($numlockvalue -eq 2) {
return $true
} else {
return $false
}
} }
if($ToggleSwitch -eq "WPFToggleVerboseLogon") { if($ToggleSwitch -eq "WPFToggleVerboseLogon") {
$VerboseStatusvalue = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System').VerboseStatus $VerboseStatusvalue = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System').VerboseStatus
return $VerboseStatusvalue -eq 1 if($VerboseStatusvalue -eq 1) {
return $true
} else {
return $false
}
} }
if($ToggleSwitch -eq "WPFToggleShowExt") { if($ToggleSwitch -eq "WPFToggleShowExt") {
$hideextvalue = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').HideFileExt $hideextvalue = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').HideFileExt
return $hideextvalue -eq 0 if($hideextvalue -eq 0) {
return $true
} else {
return $false
}
} }
if($ToggleSwitch -eq "WPFToggleSnapWindow") { if($ToggleSwitch -eq "WPFToggleSnapWindow") {
$hidesnap = (Get-ItemProperty -path 'HKCU:\Control Panel\Desktop').WindowArrangementActive $hidesnap = (Get-ItemProperty -path 'HKCU:\Control Panel\Desktop').WindowArrangementActive
return $hidesnap -ne 0 if($hidesnap -eq 0) {
return $false
} else {
return $true
}
} }
if($ToggleSwitch -eq "WPFToggleSnapFlyout") { if($ToggleSwitch -eq "WPFToggleSnapFlyout") {
$hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').EnableSnapAssistFlyout $hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').EnableSnapAssistFlyout
return $hidesnap -ne 0 if($hidesnap -eq 0) {
return $false
} else {
return $true
}
} }
if($ToggleSwitch -eq "WPFToggleSnapSuggestion") { if($ToggleSwitch -eq "WPFToggleSnapSuggestion") {
$hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').SnapAssist $hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').SnapAssist
return $hidesnap -ne 0 if($hidesnap -eq 0) {
return $false
} else {
return $true
}
} }
if($ToggleSwitch -eq "WPFToggleMouseAcceleration") { if($ToggleSwitch -eq "WPFToggleMouseAcceleration") {
$MouseSpeed = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseSpeed $MouseSpeed = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseSpeed
$MouseThreshold1 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold1 $MouseThreshold1 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold1
$MouseThreshold2 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold2 $MouseThreshold2 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold2
return $MouseSpeed -eq 1 -and $MouseThreshold1 -eq 6 -and $MouseThreshold2 -eq 10 if($MouseSpeed -eq 1 -and $MouseThreshold1 -eq 6 -and $MouseThreshold2 -eq 10) {
return $true
} else {
return $false
}
} }
if($ToggleSwitch -eq "WPFToggleTaskbarSearch") { if($ToggleSwitch -eq "WPFToggleTaskbarSearch") {
$SearchButton = (Get-ItemProperty -path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search").SearchboxTaskbarMode $SearchButton = (Get-ItemProperty -path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search").SearchboxTaskbarMode
return $SearchButton -ne 0 if($SearchButton -eq 0) {
return $false
} else {
return $true
}
} }
if ($ToggleSwitch -eq "WPFToggleStickyKeys") { if ($ToggleSwitch -eq "WPFToggleStickyKeys") {
$StickyKeys = (Get-ItemProperty -path 'HKCU:\Control Panel\Accessibility\StickyKeys').Flags $StickyKeys = (Get-ItemProperty -path 'HKCU:\Control Panel\Accessibility\StickyKeys').Flags
return $StickyKeys -ne 58 if($StickyKeys -eq 58) {
return $false
} else {
return $true
}
} }
if ($ToggleSwitch -eq "WPFToggleTaskView") { if ($ToggleSwitch -eq "WPFToggleTaskView") {
$TaskView = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').ShowTaskViewButton $TaskView = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').ShowTaskViewButton
return $TaskView -ne 0 if($TaskView -eq 0) {
return $false
} else {
return $true
}
} }
if ($ToggleSwitch -eq "WPFToggleHiddenFiles") { if ($ToggleSwitch -eq "WPFToggleHiddenFiles") {
$HiddenFiles = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').Hidden $HiddenFiles = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').Hidden
return $HiddenFiles -ne 0 if($HiddenFiles -eq 0) {
return $false
} else {
return $true
}
} }
if ($ToggleSwitch -eq "WPFToggleTaskbarWidgets") { if ($ToggleSwitch -eq "WPFToggleTaskbarWidgets") {
$TaskbarWidgets = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced").TaskBarDa $TaskbarWidgets = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced").TaskBarDa
return $TaskbarWidgets -ne 0 if($TaskbarWidgets -eq 0) {
return $false
} else {
return $true
}
} }
if ($ToggleSwitch -eq "WPFToggleTaskbarAlignment") { if ($ToggleSwitch -eq "WPFToggleTaskbarAlignment") {
$TaskbarAlignment = (Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced").TaskbarAl $TaskbarAlignment = (Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced").TaskbarAl
return $TaskbarAlignment -ne 0 if($TaskbarAlignment -eq 0) {
return $false
} else {
return $true
}
} }
if ($ToggleSwitch -eq "WPFToggleDetailedBSoD") { if ($ToggleSwitch -eq "WPFToggleDetailedBSoD") {
$DetailedBSoD1 = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisplayParameters $DetailedBSoD1 = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisplayParameters
$DetailedBSoD2 = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisableEmoticon $DetailedBSoD2 = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisableEmoticon
return !(($DetailedBSoD1 -eq 0) -or ($DetailedBSoD2 -eq 0) -or !$DetailedBSoD1 -or !$DetailedBSoD2) if (($DetailedBSoD1 -eq 0) -or ($DetailedBSoD2 -eq 0) -or !$DetailedBSoD1 -or !$DetailedBSoD2) {
return $false
} else {
return $true
}
} }
} }

View File

@ -13,11 +13,10 @@ 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; Set-ExecutionPolicy Bypass -Scope Process -Force; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) -ErrorAction Stop
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; powershell choco feature enable -n allowGlobalConfirmation
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,258 +1,102 @@
function Install-WinUtilProgramChoco { function Install-WinUtilProgramChoco {
<# <#
.SYNOPSIS .SYNOPSIS
Manages the installation or uninstallation of a list of Chocolatey packages. Manages the provided programs using Chocolatey
.PARAMETER Programs .PARAMETER ProgramsToInstall
A string array containing the programs to be installed or uninstalled. A list of programs to manage
.PARAMETER Action .PARAMETER manage
Specifies the action to perform: "Install" or "Uninstall". The default value is "Install". The action to perform on the programs, can be either 'Installing' or 'Uninstalling'
.DESCRIPTION .NOTES
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. The triple quotes are required any time you need a " in a normal script block.
.EXAMPLE
Install-WinUtilProgramChoco -Programs @("7zip","chrome") -Action "Uninstall"
#> #>
param( param(
[Parameter(Mandatory, Position=0)] [Parameter(Mandatory, Position=0)]
[string[]]$Programs, [PsCustomObject]$ProgramsToInstall,
[Parameter(Position=1)] [Parameter(Position=1)]
[String]$Action = "Install" [String]$manage = "Installing"
) )
function Initialize-OutputFile { $x = 0
<# $count = $ProgramsToInstall.Count
.SYNOPSIS
Initializes an output file by removing any existing file and creating a new, empty file at the specified path.
.PARAMETER filePath # This check isn't really necessary, as there's a couple of checks before this Private Function gets called, but just to make sure ;)
The full path to the file to be initialized. if($count -le 0) {
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
}
function Run-ChocoCommand {
<#
.SYNOPSIS
Executes a Chocolatey command with the specified arguments and returns the exit code.
.PARAMETER arguments
The arguments to be passed to the Chocolatey command.
.DESCRIPTION
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.
.RETURNS
[int]
The exit code of the Chocolatey command.
.EXAMPLE
$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."
}
}
else {
Write-Host "Failed to install $Program."
}
}
catch {
Write-Host "Failed to install $Program due to an error: $_"
}
finally {
Update-TaskbarProgress $currentIndex $totalPrograms
}
}
function Uninstall-ChocoPackage {
<#
.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 {
$uninstallStatusCode = Run-ChocoCommand "uninstall $chocoPackages -y"
Write-Host "$Program" $(if ($uninstallStatusCode -eq 0) { "uninstalled successfully." } else { "failed to uninstall." })
}
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 "Starting" -PercentComplete 0
Write-Host "===========================================" Write-Host "==========================================="
Write-Host "-- Configuring Chocolatey packages ---" Write-Host "-- Configuring Chocolatey pacakages ---"
Write-Host "===========================================" Write-Host "==========================================="
Foreach ($Program in $ProgramsToInstall) {
for ($currentIndex = 0; $currentIndex -lt $totalPrograms; $currentIndex++) { Write-Progress -Activity "$manage Applications" -Status "$manage $($Program.choco) $($x + 1) of $count" -PercentComplete $($x/$count*100)
$Program = $Programs[$currentIndex] if($manage -eq "Installing") {
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($currentIndex / $totalPrograms * 100) write-host "Starting install of $($Program.choco) with Chocolatey."
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($currentIndex / $totalPrograms)}) try {
$tryUpgrade = $false
switch ($Action) { $installOutputFilePath = "$env:TEMP\Install-WinUtilProgramChoco.install-command.output.txt"
"Install" { New-Item -ItemType File -Path $installOutputFilePath
Install-ChocoPackage -Program $Program -currentIndex $currentIndex -totalPrograms $totalPrograms $chocoInstallStatus = $(Start-Process -FilePath "choco" -ArgumentList "install $($Program.choco) -y" -Wait -PassThru -RedirectStandardOutput $installOutputFilePath).ExitCode
} if(($chocoInstallStatus -eq 0) -AND (Test-Path -Path $installOutputFilePath)) {
"Uninstall" { $keywordsFound = Get-Content -Path $installOutputFilePath | Where-Object {$_ -match "reinstall" -OR $_ -match "already installed"}
Uninstall-ChocoPackage -Program $Program -currentIndex $currentIndex -totalPrograms $totalPrograms if ($keywordsFound) {
} $tryUpgrade = $true
default {
throw "Invalid action parameter value: '$Action'."
} }
} }
# 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.
if ($tryUpgrade) {
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."
} }
Set-WinUtilProgressBar -label "$($Action)ation done" -percent 100 if(($chocoInstallStatus -eq 0) -AND ($tryUpgrade -eq $false)) {
# Cleanup Output Files Write-Host "$($Program.choco) installed successfully using Chocolatey."
$outputFiles = @("$env:TEMP\Install-WinUtilProgramChoco.install-command.output.txt", "$env:TEMP\Install-WinUtilProgramChoco.uninstall-command.output.txt") $X++
foreach ($filePath in $outputFiles) { $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value ($x/$count) })
Remove-Item -Path $filePath -Force -ErrorAction SilentlyContinue 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) })
} }
} }
if($manage -eq "Uninstalling") {
write-host "Starting uninstall of $($Program.choco) with Chocolatey."
try {
$uninstallOutputFilePath = "$env:TEMP\Install-WinUtilProgramChoco.uninstall-command.output.txt"
New-Item -ItemType File -Path $uninstallOutputFilePath
$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) })
}
}
}
Write-Progress -Activity "$manage Applications" -Status "Finished" -Completed
# Cleanup leftovers files
if(Test-Path -Path $installOutputFilePath) { Remove-Item -Path $installOutputFilePath }
if(Test-Path -Path $uninstallOutputFilePath) { Remove-Item -Path $uninstallOutputFilePath }
return;
}

View File

@ -1,199 +0,0 @@
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,16 +13,6 @@ 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

@ -21,11 +21,6 @@ Function Invoke-WinUtilDarkMode {
$Path = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" $Path = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize"
Set-ItemProperty -Path $Path -Name AppsUseLightTheme -Value $DarkMoveValue Set-ItemProperty -Path $Path -Name AppsUseLightTheme -Value $DarkMoveValue
Set-ItemProperty -Path $Path -Name SystemUsesLightTheme -Value $DarkMoveValue Set-ItemProperty -Path $Path -Name SystemUsesLightTheme -Value $DarkMoveValue
Invoke-WinUtilExplorerRefresh
# Update Winutil Theme if the Theme Button shows the Icon for Auto
if ($sync.ThemeButton.Content -eq [char]0xF08C) {
Invoke-WinutilThemeChange -theme "Auto"
}
} catch [System.Security.SecurityException] { } catch [System.Security.SecurityException] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception" Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] { } catch [System.Management.Automation.ItemNotFoundException] {

View File

@ -1,33 +0,0 @@
function Invoke-WinUtilExplorerRefresh {
<#
.SYNOPSIS
Refreshes the Windows Explorer
#>
Invoke-WPFRunspace -DebugPreference $DebugPreference -ScriptBlock {
# Send the WM_SETTINGCHANGE message to all windows
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessageTimeout(
IntPtr hWnd,
uint Msg,
IntPtr wParam,
string lParam,
uint fuFlags,
uint uTimeout,
out IntPtr lpdwResult);
}
"@
$HWND_BROADCAST = [IntPtr]0xffff
$WM_SETTINGCHANGE = 0x1A
$SMTO_ABORTIFHUNG = 0x2
$timeout = 100
# Send the broadcast message to all windows
[Win32]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [IntPtr]::Zero, "ImmersiveColorSet", $SMTO_ABORTIFHUNG, $timeout, [ref]([IntPtr]::Zero))
}
}

View File

@ -7,9 +7,7 @@ function Invoke-WinUtilGPU {
"*NVIDIA GeForce*Laptop*", "*NVIDIA GeForce*Laptop*",
"*NVIDIA GeForce*GT*", "*NVIDIA GeForce*GT*",
"*AMD Radeon(TM)*", "*AMD Radeon(TM)*",
"*Intel(R) HD Graphics*",
"*UHD*" "*UHD*"
) )
foreach ($gpu in $gpuInfo) { foreach ($gpu in $gpuInfo) {

View File

@ -25,56 +25,6 @@ function Test-CompatibleImage() {
} }
} }
function Get-FidoLangFromCulture {
param (
[Parameter(Mandatory, Position = 0)] [string]$langName
)
switch -Wildcard ($langName)
{
"ar*" { return "Arabic" }
"pt-BR" { return "Brazilian Portuguese" }
"bg*" { return "Bulgarian" }
{($_ -eq "zh-CH") -or ($_ -like "zh-Hans*") -or ($_ -eq "zh-SG") -or ($_ -eq "zh-CHS")} { return "Chinese (Simplified)" }
{($_ -eq "zh") -or ($_ -eq "zh-Hant") -or ($_ -eq "zh-HK") -or ($_ -eq "zh-MO") -or ($_ -eq "zh-TW") -or ($_ -eq "zh-CHT")} { return "Chinese (Traditional)" }
"hr*" { return "Croatian" }
"cs*" { return "Czech" }
"da*" { return "Danish" }
"nl*" { return "Dutch" }
"en-US" { return "English" }
{($_ -like "en*") -and ($_ -ne "en-US")} { return "English International" }
"et*" { return "Estonian" }
"fi*" { return "Finnish" }
{($_ -like "fr*") -and ($_ -ne "fr-CA")} { return "French" }
"fr-CA" { return "French Canadian" }
"de*" { return "German" }
"el*" { return "Greek" }
"he*" { return "Hebrew" }
"hu*" { return "Hungarian" }
"it*" { return "Italian" }
"ja*" { return "Japanese" }
"ko*" { return "Korean" }
"lv*" { return "Latvian" }
"lt*" { return "Lituanian" }
"nb*" { return "Norwegian" }
"pl*" { return "Polish" }
{($_ -like "pt*") -and ($_ -ne "pt-BR")} { return "Portuguese" }
"ro*" { return "Romanian" }
"ru*" { return "Russian" }
"sr-Latn*" { return "Serbian Latin" }
"sk*" { return "Slovak" }
"sl*" { return "Slovenian" }
{($_ -like "es*") -and ($_ -ne "es-MX")} { return "Spanish" }
"es-MX" { return "Spanish (Mexico)" }
"sv*" { return "Swedish" }
"th*" { return "Thai" }
"tr*" { return "Turkish" }
"uk*" { return "Ukrainian" }
default { return "English" }
}
}
function Remove-Features() { function Remove-Features() {
<# <#
.SYNOPSIS .SYNOPSIS
@ -87,31 +37,28 @@ function Remove-Features() {
Remove-Features Remove-Features
#> #>
try { try {
$featlist = (Get-WindowsOptionalFeature -Path $scratchDir) $featlist = (Get-WindowsOptionalFeature -Path $scratchDir).FeatureName
$featlist = $featlist | Where-Object { $featlist = $featlist | Where-Object {
$_.FeatureName -NotLike "*Defender*" -AND $_ -NotLike "*Defender*" -AND
$_.FeatureName -NotLike "*Printing*" -AND $_ -NotLike "*Printing*" -AND
$_.FeatureName -NotLike "*TelnetClient*" -AND $_ -NotLike "*TelnetClient*" -AND
$_.FeatureName -NotLike "*PowerShell*" -AND $_ -NotLike "*PowerShell*" -AND
$_.FeatureName -NotLike "*NetFx*" -AND $_ -NotLike "*NetFx*" -AND
$_.FeatureName -NotLike "*Media*" -AND $_ -NotLike "*Media*" -AND
$_.FeatureName -NotLike "*NFS*" -AND $_ -NotLike "*NFS*"
$_.FeatureName -NotLike "*SearchEngine*" -AND
$_.State -ne "Disabled"
} }
foreach($feature in $featlist) { foreach($feature in $featlist) {
$status = "Removing feature $($feature.FeatureName)" $status = "Removing feature $feature"
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.FeatureName)" Write-Debug "Removing feature $feature"
Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $($feature.FeatureName) -Remove -ErrorAction SilentlyContinue -NoRestart Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $feature -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
} }
} }
@ -145,7 +92,6 @@ function Remove-Packages {
$_ -NotLike "*ParentalControls*" -AND $_ -NotLike "*ParentalControls*" -AND
$_ -NotLike "*Win32WebViewHost*" -AND $_ -NotLike "*Win32WebViewHost*" -AND
$_ -NotLike "*InputApp*" -AND $_ -NotLike "*InputApp*" -AND
$_ -NotLike "*DirectPlay*" -AND
$_ -NotLike "*AccountsControl*" -AND $_ -NotLike "*AccountsControl*" -AND
$_ -NotLike "*AsyncTextService*" -AND $_ -NotLike "*AsyncTextService*" -AND
$_ -NotLike "*CapturePicker*" -AND $_ -NotLike "*CapturePicker*" -AND
@ -160,8 +106,6 @@ 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"
@ -170,18 +114,12 @@ 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
} }
} }
@ -217,8 +155,7 @@ function Remove-ProvisionedPackages() {
$_.PackageName -NotLike "*Paint*" -and $_.PackageName -NotLike "*Paint*" -and
$_.PackageName -NotLike "*Gaming*" -and $_.PackageName -NotLike "*Gaming*" -and
$_.PackageName -NotLike "*Extension*" -and $_.PackageName -NotLike "*Extension*" -and
$_.PackageName -NotLike "*SecHealthUI*" -and $_.PackageName -NotLike "*SecHealthUI*"
$_.PackageName -NotLike "*ScreenSketch*"
} }
$counter = 0 $counter = 0
@ -238,7 +175,6 @@ 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
} }
} }

View File

@ -1,81 +0,0 @@
function Invoke-WinUtilSSHServer {
<#
.SYNOPSIS
Enables OpenSSH server to remote into your windows device
#>
# Get the latest version of OpenSSH Server
$FeatureName = Get-WindowsCapability -Online | Where-Object { $_.Name -like "OpenSSH.Server*" }
# Install the OpenSSH Server feature if not already installed
if ($FeatureName.State -ne "Installed") {
Write-Host "Enabling OpenSSH Server"
Add-WindowsCapability -Online -Name $FeatureName.Name
}
# Sets up the OpenSSH Server service
Write-Host "Starting the services"
Start-Service -Name sshd
Set-Service -Name sshd -StartupType Automatic
# Sets up the ssh-agent service
Start-Service 'ssh-agent'
Set-Service -Name 'ssh-agent' -StartupType 'Automatic'
# Confirm the required services are running
$SSHDaemonService = Get-Service -Name sshd
$SSHAgentService = Get-Service -Name 'ssh-agent'
if ($SSHDaemonService.Status -eq 'Running') {
Write-Host "OpenSSH Server is running."
} else {
try {
Write-Host "OpenSSH Server is not running. Attempting to restart..."
Restart-Service -Name sshd -Force
Write-Host "OpenSSH Server has been restarted successfully."
} catch {
Write-Host "Failed to restart OpenSSH Server: $_"
}
}
if ($SSHAgentService.Status -eq 'Running') {
Write-Host "ssh-agent is running."
} else {
try {
Write-Host "ssh-agent is not running. Attempting to restart..."
Restart-Service -Name sshd -Force
Write-Host "ssh-agent has been restarted successfully."
} catch {
Write-Host "Failed to restart ssh-agent : $_"
}
}
#Adding Firewall rule for port 22
Write-Host "Setting up firewall rules"
$firewallRule = (Get-NetFirewallRule -Name 'sshd').Enabled
if ($firewallRule) {
Write-Host "Firewall rule for OpenSSH Server (sshd) already exists."
} else {
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
Write-Host "Firewall rule for OpenSSH Server created and enabled."
}
# Check for the authorized_keys file
$sshFolderPath = "$env:HOMEDRIVE\$env:HOMEPATH\.ssh"
$authorizedKeysPath = "$sshFolderPath\authorized_keys"
if (-not (Test-Path -Path $sshFolderPath)) {
Write-Host "Creating ssh directory..."
New-Item -Path $sshFolderPath -ItemType Directory -Force
}
if (-not (Test-Path -Path $authorizedKeysPath)) {
Write-Host "Creating authorized_keys file..."
New-Item -Path $authorizedKeysPath -ItemType File -Force
Write-Host "authorized_keys file created at $authorizedKeysPath."
} else {
Write-Host "authorized_keys file already exists at $authorizedKeysPath."
}
Write-Host "OpenSSH server was successfully enabled."
Write-Host "The config file can be located at C:\ProgramData\ssh\sshd_config "
Write-Host "Add your public keys to this file -> $authorizedKeysPath"
}

View File

@ -14,7 +14,7 @@ function Invoke-WinUtilSnapFlyout {
Write-Host "Disabling Snap Assist Flyout On startup" Write-Host "Disabling Snap Assist Flyout On startup"
$value = 0 $value = 0
} }
# taskkill.exe /F /IM "explorer.exe"
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" $Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
taskkill.exe /F /IM "explorer.exe" taskkill.exe /F /IM "explorer.exe"
Set-ItemProperty -Path $Path -Name EnableSnapAssistFlyout -Value $value Set-ItemProperty -Path $Path -Name EnableSnapAssistFlyout -Value $value

View File

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

View File

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

View File

@ -1,180 +0,0 @@
function Invoke-WinutilThemeChange {
<#
.SYNOPSIS
Toggles between light and dark themes for a Windows utility application.
.DESCRIPTION
This function toggles the theme of the user interface between 'Light' and 'Dark' modes,
modifying various UI elements such as colors, margins, corner radii, font families, etc.
If the '-init' switch is used, it initializes the theme based on the system's current dark mode setting.
.PARAMETER init
A switch parameter. If set to $true, the function initializes the theme based on the systems current dark mode setting.
.EXAMPLE
Invoke-WinutilThemeChange
# Toggles the theme between 'Light' and 'Dark'.
.EXAMPLE
Invoke-WinutilThemeChange -init
# Initializes the theme based on the system's dark mode and applies the shared theme.
#>
param (
[switch]$init = $false,
[string]$theme
)
function Set-WinutilTheme {
<#
.SYNOPSIS
Applies the specified theme to the application's user interface.
.DESCRIPTION
This internal function applies the given theme by setting the relevant properties
like colors, font families, corner radii, etc., in the UI. It uses the
'Set-ThemeResourceProperty' helper function to modify the application's resources.
.PARAMETER currentTheme
The name of the theme to be applied. Common values are "Light", "Dark", or "shared".
#>
param (
[string]$currentTheme
)
function Set-ThemeResourceProperty {
<#
.SYNOPSIS
Sets a specific UI property in the application's resources.
.DESCRIPTION
This helper function sets a property (e.g., color, margin, corner radius) in the
application's resources, based on the provided type and value. It includes
error handling to manage potential issues while setting a property.
.PARAMETER Name
The name of the resource property to modify (e.g., "MainBackgroundColor", "ButtonBackgroundMouseoverColor").
.PARAMETER Value
The value to assign to the resource property (e.g., "#FFFFFF" for a color).
.PARAMETER Type
The type of the resource, such as "ColorBrush", "CornerRadius", "GridLength", or "FontFamily".
#>
param($Name, $Value, $Type)
try {
# Set the resource property based on its type
$sync.Form.Resources[$Name] = switch ($Type) {
"ColorBrush" { [Windows.Media.SolidColorBrush]::new($Value) }
"Color" {
# Convert hex string to RGB values
$hexColor = $Value.TrimStart("#")
$r = [Convert]::ToInt32($hexColor.Substring(0,2), 16)
$g = [Convert]::ToInt32($hexColor.Substring(2,2), 16)
$b = [Convert]::ToInt32($hexColor.Substring(4,2), 16)
[Windows.Media.Color]::FromRgb($r, $g, $b)
}
"CornerRadius" { [System.Windows.CornerRadius]::new($Value) }
"GridLength" { [System.Windows.GridLength]::new($Value) }
"Thickness" {
# Parse the Thickness value (supports 1, 2, or 4 inputs)
$values = $Value -split ","
switch ($values.Count) {
1 { [System.Windows.Thickness]::new([double]$values[0]) }
2 { [System.Windows.Thickness]::new([double]$values[0], [double]$values[1]) }
4 { [System.Windows.Thickness]::new([double]$values[0], [double]$values[1], [double]$values[2], [double]$values[3]) }
}
}
"FontFamily" { [Windows.Media.FontFamily]::new($Value) }
"Double" { [double]$Value }
default { $Value }
}
}
catch {
# Log a warning if there's an issue setting the property
Write-Warning "Failed to set property $($Name): $_"
}
}
# Retrieve all theme properties from the theme configuration
$themeProperties = $sync.configs.themes.$currentTheme.PSObject.Properties
foreach ($_ in $themeProperties) {
# Apply properties that deal with colors
if ($_.Name -like "*color*") {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "ColorBrush"
# For certain color properties, also set complementary values (e.g., BorderColor -> CBorderColor) This is required because e.g DropShadowEffect requires a <Color> and not a <SolidColorBrush> object
if ($_.Name -in @("BorderColor", "ButtonBackgroundMouseoverColor")) {
Set-ThemeResourceProperty -Name "C$($_.Name)" -Value $_.Value -Type "Color"
}
}
# Apply corner radius properties
elseif ($_.Name -like "*Radius*") {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "CornerRadius"
}
# Apply row height properties
elseif ($_.Name -like "*RowHeight*") {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "GridLength"
}
# Apply thickness or margin properties
elseif (($_.Name -like "*Thickness*") -or ($_.Name -like "*margin")) {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "Thickness"
}
# Apply font family properties
elseif ($_.Name -like "*FontFamily*") {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "FontFamily"
}
# Apply any other properties as doubles (numerical values)
else {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "Double"
}
}
}
$LightPreferencePath = "$env:LOCALAPPDATA\winutil\LightTheme.ini"
$DarkPreferencePath = "$env:LOCALAPPDATA\winutil\DarkTheme.ini"
if ($init) {
Set-WinutilTheme -currentTheme "shared"
if (Test-Path $LightPreferencePath) {
$theme = "Light"
}
elseif (Test-Path $DarkPreferencePath) {
$theme = "Dark"
}
else {
$theme = "Auto"
}
}
switch ($theme) {
"Auto" {
$systemUsesDarkMode = Get-WinUtilToggleStatus WPFToggleDarkMode
if ($systemUsesDarkMode) {
Set-WinutilTheme -currentTheme "Dark"
}
else{
Set-WinutilTheme -currentTheme "Light"
}
$themeButtonIcon = [char]0xF08C
Remove-Item $LightPreferencePath -Force -ErrorAction SilentlyContinue
Remove-Item $DarkPreferencePath -Force -ErrorAction SilentlyContinue
}
"Dark" {
Set-WinutilTheme -currentTheme $theme
$themeButtonIcon = [char]0xE708
$null = New-Item $DarkPreferencePath -Force
Remove-Item $LightPreferencePath -Force -ErrorAction SilentlyContinue
}
"Light" {
Set-WinutilTheme -currentTheme $theme
$themeButtonIcon = [char]0xE706
$null = New-Item $LightPreferencePath -Force
Remove-Item $DarkPreferencePath -Force -ErrorAction SilentlyContinue
}
}
# Update the theme selector button with the appropriate icon
$ThemeButton = $sync.Form.FindName("ThemeButton")
$ThemeButton.Content = [string]$themeButtonIcon
}

View File

@ -36,12 +36,7 @@ function Set-WinUtilRegistry {
} }
Write-Host "Set $Path\$Name to $Value" Write-Host "Set $Path\$Name to $Value"
if ($Value -ne "<RemoveEntry>"){
Set-ItemProperty -Path $Path -Name $Name -Type $Type -Value $Value -Force -ErrorAction Stop | Out-Null Set-ItemProperty -Path $Path -Name $Name -Type $Type -Value $Value -Force -ErrorAction Stop | Out-Null
}
else{
Remove-ItemProperty -Path $Path -Name $Name -Force -ErrorAction Stop | Out-Null
}
} catch [System.Security.SecurityException] { } catch [System.Security.SecurityException] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception" Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] { } catch [System.Management.Automation.ItemNotFoundException] {

View File

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

View File

@ -0,0 +1,50 @@
function Set-WinUtilUITheme {
<#
.SYNOPSIS
Sets the theme of the XAML file
.PARAMETER inputXML
A string representing the XAML object to modify
.PARAMETER themeName
The name of the theme to set the XAML to. Defaults to 'matrix'
.EXAMPLE
Set-WinUtilUITheme -inputXAML $inputXAML
#>
param
(
[Parameter(Mandatory, position=0)]
[string]$inputXML,
[Parameter(position=1)]
[string]$themeName = 'matrix'
)
try {
# Convert the JSON to a PowerShell object
$themes = $sync.configs.themes
# Select the specified theme
$selectedTheme = $themes.$themeName
if ($selectedTheme) {
# Loop through all key-value pairs in the selected theme
foreach ($property in $selectedTheme.PSObject.Properties) {
$key = $property.Name
$value = $property.Value
# Add curly braces around the key
$formattedKey = "{$key}"
# Replace the key with the value in the input XML
$inputXML = $inputXML.Replace($formattedKey, $value)
}
} else {
Write-Host "Theme '$themeName' not found."
}
} catch {
Write-Warning "Unable to apply theme"
Write-Warning $psitem.Exception.StackTrace
}
return $inputXML;
}

View File

@ -33,25 +33,25 @@ function Show-CustomDialog {
#> #>
param( param(
[string]$Message, [string]$Message,
[int]$Width = $sync.Form.Resources.CustomDialogWidth, [int]$Width = 300,
[int]$Height = $sync.Form.Resources.CustomDialogHeight, [int]$Height = 200,
[int]$FontSize = $sync.Form.Resources.CustomDialogFontSize, [int]$FontSize = 10,
[int]$HeaderFontSize = $sync.Form.Resources.CustomDialogFontSizeHeader, [int]$HeaderFontSize = 14,
[int]$IconSize = $sync.Form.Resources.CustomDialogLogoSize, [int]$IconSize = 25,
[bool]$EnableScroll = $false [bool]$EnableScroll = $false
) )
Add-Type -AssemblyName PresentationFramework Add-Type -AssemblyName PresentationFramework
# Define theme colors # Define theme colors
$foregroundColor = $sync.Form.Resources.MainForegroundColor $foregroundColor = $sync.configs.themes.$ctttheme.MainForegroundColor
$backgroundColor = $sync.Form.Resources.MainBackgroundColor $backgroundColor = $sync.configs.themes.$ctttheme.MainBackgroundColor
$font = New-Object Windows.Media.FontFamily("Consolas") $font = New-Object Windows.Media.FontFamily("Consolas")
$borderColor = $sync.Form.Resources.BorderColor # ButtonInstallBackgroundColor $borderColor = $sync.configs.themes.$ctttheme.BorderColor # ButtonInstallBackgroundColor
$buttonBackgroundColor = $sync.Form.Resources.ButtonInstallBackgroundColor $buttonBackgroundColor = $sync.configs.themes.$ctttheme.ButtonInstallBackgroundColor
$buttonForegroundColor = $sync.Form.Resources.ButtonInstallForegroundColor $buttonForegroundColor = $sync.configs.themes.$ctttheme.ButtonInstallForegroundColor
$shadowColor = [Windows.Media.ColorConverter]::ConvertFromString("#AAAAAAAA") $shadowColor = [Windows.Media.ColorConverter]::ConvertFromString("#AAAAAAAA")
$logocolor = $sync.Form.Resources.LabelboxForegroundColor $logocolor = $sync.configs.themes.$ctttheme.ButtonBackgroundPressedColor
# Create a custom dialog window # Create a custom dialog window
$dialog = New-Object Windows.Window $dialog = New-Object Windows.Window
@ -128,15 +128,73 @@ 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((Invoke-WinUtilAssets -Type "logo" -Size 25)) $stackPanel.Children.Add($viewbox)
# 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, 10, 10, 5) # Add margins around the text block $winutilTextBlock.Margin = New-Object Windows.Thickness(10, 5, 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
@ -162,7 +220,7 @@ function Show-CustomDialog {
$hyperlink.NavigateUri = New-Object System.Uri($match.Groups[1].Value) $hyperlink.NavigateUri = New-Object System.Uri($match.Groups[1].Value)
$hyperlink.Inlines.Add($match.Groups[2].Value) $hyperlink.Inlines.Add($match.Groups[2].Value)
$hyperlink.TextDecorations = [Windows.TextDecorations]::None # Remove underline $hyperlink.TextDecorations = [Windows.TextDecorations]::None # Remove underline
$hyperlink.Foreground = $sync.Form.Resources.LinkForegroundColor $hyperlink.Foreground = $sync.configs.themes.$ctttheme.LinkForegroundColor
$hyperlink.Add_Click({ $hyperlink.Add_Click({
param($sender, $args) param($sender, $args)
@ -170,11 +228,11 @@ function Show-CustomDialog {
}) })
$hyperlink.Add_MouseEnter({ $hyperlink.Add_MouseEnter({
param($sender, $args) param($sender, $args)
$sender.Foreground = $sync.Form.Resources.LinkHoverForegroundColor $sender.Foreground = $sync.configs.themes.$ctttheme.LinkHoverForegroundColor
}) })
$hyperlink.Add_MouseLeave({ $hyperlink.Add_MouseLeave({
param($sender, $args) param($sender, $args)
$sender.Foreground = $sync.Form.Resources.LinkForegroundColor $sender.Foreground = $sync.configs.themes.$ctttheme.LinkForegroundColor
}) })
$messageTextBlock.Inlines.Add($hyperlink) $messageTextBlock.Inlines.Add($hyperlink)

View File

@ -11,7 +11,7 @@ Function Update-WinUtilProgramWinget {
$host.ui.RawUI.WindowTitle = """Winget Install""" $host.ui.RawUI.WindowTitle = """Winget Install"""
Start-Transcript "$logdir\winget-update_$dateTime.log" -Append Start-Transcript $ENV:TEMP\winget-update.log -Append
winget upgrade --all --accept-source-agreements --accept-package-agreements --scope=machine --silent winget upgrade --all --accept-source-agreements --accept-package-agreements --scope=machine --silent
} }

View File

@ -19,14 +19,15 @@ function Invoke-WPFButton {
} }
Switch -Wildcard ($Button) { Switch -Wildcard ($Button) {
"WPFTab?BT" {Invoke-WPFTab $Button} "WPFTab?BT" {Invoke-WPFTab $Button}
"WPFInstall" {Invoke-WPFInstall} "WPFinstall" {Invoke-WPFInstall}
"WPFUninstall" {Invoke-WPFUnInstall} "WPFuninstall" {Invoke-WPFUnInstall}
"WPFInstallUpgrade" {Invoke-WPFInstallUpgrade} "WPFInstallUpgrade" {Invoke-WPFInstallUpgrade}
"WPFStandard" {Invoke-WPFPresets "Standard" -checkboxfilterpattern "WPFTweak*"} "WPFstandard" {Invoke-WPFPresets "Standard"}
"WPFMinimal" {Invoke-WPFPresets "Minimal" -checkboxfilterpattern "WPFTweak*"} "WPFminimal" {Invoke-WPFPresets "Minimal"}
"WPFClearTweaksSelection" {Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFTweak*"} "WPFclear" {Invoke-WPFPresets -preset $null -imported $true}
"WPFClearInstallSelection" {Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFInstall*"} "WPFclearWinget" {Invoke-WPFPresets -preset $null -imported $true -CheckBox "WPFInstall"}
"WPFtweaksbutton" {Invoke-WPFtweaksbutton} "WPFtweaksbutton" {Invoke-WPFtweaksbutton}
"WPFOOSUbutton" {Invoke-WPFOOSU} "WPFOOSUbutton" {Invoke-WPFOOSU}
"WPFAddUltPerf" {Invoke-WPFUltimatePerformance -State "Enable"} "WPFAddUltPerf" {Invoke-WPFUltimatePerformance -State "Enable"}
@ -40,7 +41,6 @@ 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,7 +57,5 @@ function Invoke-WPFButton {
"WPFMicrowin" {Invoke-WPFMicrowin} "WPFMicrowin" {Invoke-WPFMicrowin}
"WPFCloseButton" {Invoke-WPFCloseButton} "WPFCloseButton" {Invoke-WPFCloseButton}
"MicrowinScratchDirBT" {Invoke-ScratchDialog} "MicrowinScratchDirBT" {Invoke-ScratchDialog}
"WPFWinUtilPSProfile" {Invoke-WinUtilpsProfile}
"WPFWinUtilSSHServer" {Invoke-WinUtilSSHServer}
} }
} }

View File

@ -16,7 +16,6 @@ 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(($sync.WPFpreferChocolatey.IsChecked -eq $false) -and ((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget") { if(((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget") {
return return
} }
$preferChoco = $sync.WPFpreferChocolatey.IsChecked
Invoke-WPFRunspace -ArgumentList $checkbox, $preferChoco -DebugPreference $DebugPreference -ScriptBlock { Invoke-WPFRunspace -ArgumentList $checkbox -DebugPreference $DebugPreference -ScriptBlock {
param($checkbox, $preferChoco, $DebugPreference) param($checkbox, $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,12 +32,8 @@ 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 "choco"
}
else{
$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox $Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox
}
$sync.form.Dispatcher.invoke({ $sync.form.Dispatcher.invoke({
foreach($checkbox in $Checkboxes) { foreach($checkbox in $Checkboxes) {

View File

@ -62,8 +62,6 @@ function Invoke-WPFGetIso {
} }
} }
if ($sync["ISOmanual"].IsChecked) {
# Open file dialog to let user choose the ISO file
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.initialDirectory = $initialDirectory $openFileDialog.initialDirectory = $initialDirectory
@ -76,66 +74,6 @@ function Invoke-WPFGetIso {
$sync.BusyMessage.Visibility="Hidden" $sync.BusyMessage.Visibility="Hidden"
return return
} }
} elseif ($sync["ISOdownloader"].IsChecked) {
# Create folder browsers for user-specified locations
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
$isoDownloaderFBD = New-Object System.Windows.Forms.FolderBrowserDialog
$isoDownloaderFBD.Description = "Please specify the path to download the ISO file to:"
$isoDownloaderFBD.ShowNewFolderButton = $true
if ($isoDownloaderFBD.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK)
{
return
}
# Grab the location of the selected path
$targetFolder = $isoDownloaderFBD.SelectedPath
# Auto download newest ISO
# Credit: https://github.com/pbatard/Fido
$fidopath = "$env:temp\Fido.ps1"
$originalLocation = $PSScriptRoot
Invoke-WebRequest "https://github.com/pbatard/Fido/raw/master/Fido.ps1" -OutFile $fidopath
Set-Location -Path $env:temp
# Detect if the first option ("System language") has been selected and get a Fido-approved language from the current culture
$lang = if ($sync["ISOLanguage"].SelectedIndex -eq 0) {
Get-FidoLangFromCulture -langName (Get-Culture).Name
} else {
$sync["ISOLanguage"].SelectedItem
}
& $fidopath -Win 'Windows 11' -Rel $sync["ISORelease"].SelectedItem -Arch "x64" -Lang $lang -Ed "Windows 11 Home/Pro/Edu"
if (-not $?)
{
Write-Host "Could not download the ISO file. Look at the output of the console for more information."
$msg = "The ISO file could not be downloaded"
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
return
}
Set-Location $originalLocation
# Use the FullName property to only grab the file names. Using this property is necessary as, without it, you're passing the usual output of Get-ChildItem
# to the variable, and let's be honest, that does NOT exist in the file system
$filePath = (Get-ChildItem -Path "$env:temp" -Filter "Win11*.iso").FullName | Sort-Object LastWriteTime -Descending | Select-Object -First 1
$fileName = [IO.Path]::GetFileName("$filePath")
if (($targetFolder -ne "") -and (Test-Path "$targetFolder"))
{
try
{
# "Let it download to $env:TEMP and then we **move** it to the file path." - CodingWonders
$destinationFilePath = "$targetFolder\$fileName"
Write-Host "Moving ISO file. Please wait..."
Move-Item -Path "$filePath" -Destination "$destinationFilePath" -Force
$filePath = $destinationFilePath
}
catch
{
Write-Host "Unable to move the ISO file to the location you specified. The downloaded ISO is in the `"$env:TEMP`" folder"
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
}
}
}
Write-Host "File path $($filePath)" Write-Host "File path $($filePath)"
if (-not (Test-Path -Path "$filePath" -PathType Leaf)) { if (-not (Test-Path -Path "$filePath" -PathType Leaf)) {
@ -176,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-Host "Please refer to this wiki for more details: https://christitustech.github.io/winutil/KnownIssues/#troubleshoot-errors-during-microwin-usage" -ForegroundColor Red 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"
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
return return
} }

View File

@ -19,59 +19,42 @@ function Invoke-WPFImpex {
$Config = $null $Config = $null
) )
function ConfigDialog { if ($type -eq "export") {
if (!$Config) { $FileBrowser = New-Object System.Windows.Forms.SaveFileDialog
switch ($type) {
"export" { $FileBrowser = New-Object System.Windows.Forms.SaveFileDialog }
"import" { $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog }
} }
if ($type -eq "import") {
$FileBrowser = New-Object System.Windows.Forms.OpenFileDialog
}
if (-not $Config) {
$FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop') $FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop')
$FileBrowser.Filter = "JSON Files (*.json)|*.json" $FileBrowser.Filter = "JSON Files (*.json)|*.json"
$FileBrowser.ShowDialog() | Out-Null $FileBrowser.ShowDialog() | Out-Null
if($FileBrowser.FileName -eq "") { if($FileBrowser.FileName -eq "") {
return $null return
} else { } else {
return $FileBrowser.FileName $Config = $FileBrowser.FileName
}
} else {
return $Config
} }
} }
switch ($type) { if ($type -eq "export") {
"export" { $jsonFile = Get-WinUtilCheckBoxes -unCheck $false
try { $jsonFile | ConvertTo-Json | Out-File $FileBrowser.FileName -Force
$Config = ConfigDialog
if ($Config) {
$jsonFile = Get-WinUtilCheckBoxes -unCheck $false | ConvertTo-Json
$jsonFile | Out-File $Config -Force
"iex ""& { `$(irm christitus.com/win) } -Config '$Config'""" | Set-Clipboard
} }
} catch { if ($type -eq "import") {
Write-Error "An error occurred while exporting: $_"
}
}
"import" {
try {
$Config = ConfigDialog
if ($Config) {
try {
if ($Config -match '^https?://') {
$jsonFile = (Invoke-WebRequest "$Config").Content | ConvertFrom-Json
} else {
$jsonFile = Get-Content $Config | ConvertFrom-Json $jsonFile = Get-Content $Config | ConvertFrom-Json
$flattenedJson = @()
$jsonFile.PSObject.Properties | ForEach-Object {
$category = $_.Name
foreach ($checkboxName in $_.Value) {
if ($category -ne "Install") {
$flattenedJson += $checkboxName
} }
} catch {
Write-Error "Failed to load the JSON file from the specified path or URL: $_"
return
} }
$flattenedJson = $jsonFile.PSObject.Properties.Where({ $_.Name -ne "Install" }).ForEach({ $_.Value }) }
Invoke-WPFPresets -preset $flattenedJson -imported $true Invoke-WPFPresets -preset $flattenedJson -imported $true
} }
} catch {
Write-Error "An error occurred while importing: $_"
}
}
}
} }

View File

@ -19,9 +19,10 @@ 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 {
param($PackagesToInstall, $ChocoPreference, $DebugPreference) Invoke-WPFRunspace -ArgumentList $PackagesToInstall -DebugPreference $DebugPreference -ScriptBlock {
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 {
@ -29,28 +30,16 @@ function Invoke-WPFInstall {
} }
$packagesWinget, $packagesChoco = { $packagesWinget, $packagesChoco = {
$packagesWinget = [System.Collections.ArrayList]::new() $packagesWinget = [System.Collections.ArrayList]::new()
$packagesChoco = [System.Collections.ArrayList]::new() $packagesChoco = [System.Collections.Generic.List`1[System.Object]]::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.choco) $packagesChoco.add($package)
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)
@ -59,12 +48,12 @@ function Invoke-WPFInstall {
$errorPackages = @() $errorPackages = @()
if($packagesWinget.Count -gt 0) { if($packagesWinget.Count -gt 0) {
Install-WinUtilWinget Install-WinUtilWinget
Install-WinUtilProgramWinget -Action Install -Programs $packagesWinget $errorPackages += Invoke-WinUtilWingetProgram -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 -Action Install -Programs $packagesChoco Install-WinUtilProgramChoco -ProgramsToInstall $packagesChoco
} }
Write-Host "===========================================" Write-Host "==========================================="
Write-Host "-- Installs have finished ---" Write-Host "-- Installs have finished ---"

View File

@ -2,20 +2,9 @@ function Invoke-WPFInstallUpgrade {
<# <#
.SYNOPSIS .SYNOPSIS
Invokes the function that upgrades all installed programs Invokes the function that upgrades all installed programs using winget
#> #>
if ($sync.WPFpreferChocolatey.IsChecked) {
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") { if((Test-WinUtilPackageManager -winget) -eq "not-installed") {
return return
} }
@ -26,6 +15,8 @@ function Invoke-WPFInstallUpgrade {
return return
} }
# Set-WinUtilTaskbaritem -state "Indeterminate"
Update-WinUtilProgramWinget Update-WinUtilProgramWinget
Write-Host "===========================================" Write-Host "==========================================="
@ -33,4 +24,3 @@ function Invoke-WPFInstallUpgrade {
Write-Host "-- You can close this window if desired ---" Write-Host "-- You can close this window if desired ---"
Write-Host "===========================================" Write-Host "==========================================="
} }
}

View File

@ -263,8 +263,11 @@ public class PowerManagement {
# reg delete "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\$_" /f | Out-Null # reg delete "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\$_" /f | Out-Null
# When in Offline Image # When in Offline Image
if (Test-Path "HKLM:\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\$_")
{
reg delete "HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\$_" /f | Out-Null reg delete "HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\$_" /f | Out-Null
} }
}
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "SearchboxTaskbarMode" /t REG_DWORD /d 0 /f reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "SearchboxTaskbarMode" /t REG_DWORD /d 0 /f
Write-Host "Setting all services to start manually" Write-Host "Setting all services to start manually"

View File

@ -10,20 +10,14 @@ function Invoke-WPFPresets {
.PARAMETER imported .PARAMETER imported
If the preset is imported from a file, defaults to false If the preset is imported from a file, defaults to false
.PARAMETER checkboxfilterpattern .PARAMETER checkbox
The Pattern to use when filtering through CheckBoxes, defaults to "**" The checkbox to set the options to, defaults to 'WPFTweaks'
#> #>
param( param(
[Parameter(position=0)] $preset,
[Array]$preset = "", [bool]$imported = $false
[Parameter(position=1)]
[bool]$imported = $false,
[Parameter(position=2)]
[string]$checkboxfilterpattern = "**"
) )
if($imported -eq $true) { if($imported -eq $true) {
@ -32,14 +26,13 @@ function Invoke-WPFPresets {
$CheckBoxesToCheck = $sync.configs.preset.$preset $CheckBoxesToCheck = $sync.configs.preset.$preset
} }
$CheckBoxes = ($sync.GetEnumerator()).where{ $_.Value -is [System.Windows.Controls.CheckBox] -and $_.Name -notlike "WPFToggle*" -and $_.Name -like "$checkboxfilterpattern"} $CheckBoxes = $sync.GetEnumerator() | Where-Object { $_.Value -is [System.Windows.Controls.CheckBox] -and $_.Name -notlike "WPFToggle*" }
Write-Debug "Getting checkboxes to set, number of checkboxes: $($CheckBoxes.Count)" Write-Debug "Getting checkboxes to set $($CheckBoxes.Count)"
if ($CheckBoxesToCheck -ne "") { $CheckBoxesToCheck | ForEach-Object {
$debugMsg = "CheckBoxes to Check are: " if ($_ -ne $null) {
$CheckBoxesToCheck | ForEach-Object { $debugMsg += "$_, " } Write-Debug $_
$debugMsg = $debugMsg -replace (',\s*$', '') }
Write-Debug "$debugMsg"
} }
foreach ($CheckBox in $CheckBoxes) { foreach ($CheckBox in $CheckBoxes) {
@ -51,7 +44,7 @@ function Invoke-WPFPresets {
} }
# Check if the checkbox name exists in the flattened JSON hashtable # Check if the checkbox name exists in the flattened JSON hashtable
if ($CheckBoxesToCheck -contains $checkboxName) { if ($CheckBoxesToCheck.Contains($checkboxName)) {
# If it exists, set IsChecked to true # If it exists, set IsChecked to true
$sync.$checkboxName.IsChecked = $true $sync.$checkboxName.IsChecked = $true
Write-Debug "$checkboxName is checked" Write-Debug "$checkboxName is checked"

View File

@ -11,23 +11,17 @@ 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
) )
@ -37,10 +31,6 @@ 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
@ -55,6 +45,4 @@ function Invoke-WPFRunspace {
$sync.runspace.Close() $sync.runspace.Close()
[System.GC]::Collect() [System.GC]::Collect()
} }
# Return the handle
return $handle
} }

View File

@ -51,9 +51,6 @@ 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

@ -15,25 +15,23 @@ function Invoke-WPFToggle {
# Use this to get the name of the button # Use this to get the name of the button
#[System.Windows.MessageBox]::Show("$Button","Chris Titus Tech's Windows Utility","OK","Info") #[System.Windows.MessageBox]::Show("$Button","Chris Titus Tech's Windows Utility","OK","Info")
$ToggleStatus = (Get-WinUtilToggleStatus $Button)
Switch -Wildcard ($Button) { Switch -Wildcard ($Button) {
"WPFToggleDarkMode" {Invoke-WinUtilDarkMode $ToggleStatus} "WPFToggleDarkMode" {Invoke-WinUtilDarkMode -DarkMoveEnabled $(Get-WinUtilToggleStatus WPFToggleDarkMode)}
"WPFToggleBingSearch" {Invoke-WinUtilBingSearch $ToggleStatus} "WPFToggleBingSearch" {Invoke-WinUtilBingSearch $(Get-WinUtilToggleStatus WPFToggleBingSearch)}
"WPFToggleNumLock" {Invoke-WinUtilNumLock $ToggleStatus} "WPFToggleNumLock" {Invoke-WinUtilNumLock $(Get-WinUtilToggleStatus WPFToggleNumLock)}
"WPFToggleVerboseLogon" {Invoke-WinUtilVerboseLogon $ToggleStatus} "WPFToggleVerboseLogon" {Invoke-WinUtilVerboseLogon $(Get-WinUtilToggleStatus WPFToggleVerboseLogon)}
"WPFToggleShowExt" {Invoke-WinUtilShowExt $ToggleStatus} "WPFToggleShowExt" {Invoke-WinUtilShowExt $(Get-WinUtilToggleStatus WPFToggleShowExt)}
"WPFToggleSnapWindow" {Invoke-WinUtilSnapWindow $ToggleStatus} "WPFToggleSnapWindow" {Invoke-WinUtilSnapWindow $(Get-WinUtilToggleStatus WPFToggleSnapWindow)}
"WPFToggleSnapFlyout" {Invoke-WinUtilSnapFlyout $ToggleStatus} "WPFToggleSnapFlyout" {Invoke-WinUtilSnapFlyout $(Get-WinUtilToggleStatus WPFToggleSnapFlyout)}
"WPFToggleSnapSuggestion" {Invoke-WinUtilSnapSuggestion $ToggleStatus} "WPFToggleSnapSuggestion" {Invoke-WinUtilSnapSuggestion $(Get-WinUtilToggleStatus WPFToggleSnapSuggestion)}
"WPFToggleMouseAcceleration" {Invoke-WinUtilMouseAcceleration $ToggleStatus} "WPFToggleMouseAcceleration" {Invoke-WinUtilMouseAcceleration $(Get-WinUtilToggleStatus WPFToggleMouseAcceleration)}
"WPFToggleStickyKeys" {Invoke-WinUtilStickyKeys $ToggleStatus} "WPFToggleStickyKeys" {Invoke-WinUtilStickyKeys $(Get-WinUtilToggleStatus WPFToggleStickyKeys)}
"WPFToggleTaskbarWidgets" {Invoke-WinUtilTaskbarWidgets $ToggleStatus} "WPFToggleTaskbarWidgets" {Invoke-WinUtilTaskbarWidgets $(Get-WinUtilToggleStatus WPFToggleTaskbarWidgets)}
"WPFToggleTaskbarSearch" {Invoke-WinUtilTaskbarSearch $ToggleStatus} "WPFToggleTaskbarSearch" {Invoke-WinUtilTaskbarSearch $(Get-WinUtilToggleStatus WPFToggleTaskbarSearch)}
"WPFToggleTaskView" {Invoke-WinUtilTaskView $ToggleStatus} "WPFToggleTaskView" {Invoke-WinUtilTaskView $(Get-WinUtilToggleStatus WPFToggleTaskView)}
"WPFToggleHiddenFiles" {Invoke-WinUtilHiddenFiles $ToggleStatus} "WPFToggleHiddenFiles" {Invoke-WinUtilHiddenFiles $(Get-WinUtilToggleStatus WPFToggleHiddenFiles)}
"WPFToggleTaskbarAlignment" {Invoke-WinUtilTaskbarAlignment $ToggleStatus} "WPFToggleTaskbarAlignment" {Invoke-WinUtilTaskbarAlignment $(Get-WinUtilToggleStatus WPFToggleTaskbarAlignment)}
"WPFToggleDetailedBSoD" {Invoke-WinUtilDetailedBSoD $ToggleStatus} "WPFToggleDetailedBSoD" {Invoke-WinUtilDetailedBSoD $(Get-WinUtilToggleStatus WPFToggleDetailedBSoD)}
} }
} }

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..."
Install-WinUtilProgramWinget -Action Install -Programs @("Microsoft.PowerShell") Invoke-WinUtilWingetProgram -Action Install -Programs @("Microsoft.PowerShell")
} }
$targetTerminalName = "PowerShell" $targetTerminalName = "PowerShell"
} }

View File

@ -15,43 +15,17 @@ function Invoke-WPFUIElements {
#> #>
param( param(
[Parameter(Mandatory, position=0)] [Parameter(Mandatory)]
[PSCustomObject]$configVariable, [PSCustomObject]$configVariable,
[Parameter(Mandatory, position=1)] [Parameter(Mandatory)]
[string]$targetGridName, [string]$targetGridName,
[Parameter(Mandatory, position=2)] [Parameter(Mandatory)]
[int]$columncount [int]$columncount
) )
$window = $sync["Form"] $theme = $sync.configs.themes.$ctttheme
$theme = $sync.Form.Resources
$borderstyle = $window.FindResource("BorderStyle")
$HoverTextBlockStyle = $window.FindResource("HoverTextBlockStyle")
$ColorfulToggleSwitchStyle = $window.FindResource("ColorfulToggleSwitchStyle")
if (!$borderstyle -or !$HoverTextBlockStyle -or !$ColorfulToggleSwitchStyle) {
throw "Failed to retrieve Styles using 'FindResource' from main window element."
}
$targetGrid = $window.FindName($targetGridName)
if (!$targetGrid) {
throw "Failed to retrieve Target Grid by name, provided name: $targetGrid"
}
# Clear existing ColumnDefinitions and Children
$targetGrid.ColumnDefinitions.Clear() | Out-Null
$targetGrid.Children.Clear() | Out-Null
# Add ColumnDefinitions to the target Grid
for ($i = 0; $i -lt $columncount; $i++) {
$colDef = New-Object Windows.Controls.ColumnDefinition
$colDef.Width = New-Object Windows.GridLength(1, [Windows.GridUnitType]::Star)
$targetGrid.ColumnDefinitions.Add($colDef) | Out-Null
}
# Convert PSCustomObject to Hashtable # Convert PSCustomObject to Hashtable
$configHashtable = @{} $configHashtable = @{}
@ -91,6 +65,22 @@ function Invoke-WPFUIElements {
# Store application data in an array under the category # Store application data in an array under the category
$organizedData[$entryObject.Panel][$entryObject.Category] += $entryObject $organizedData[$entryObject.Panel][$entryObject.Category] += $entryObject
}
# Retrieve the main window and the target Grid by name
$window = $sync["Form"]
$targetGrid = $window.FindName($targetGridName)
# Clear existing ColumnDefinitions and Children
$targetGrid.ColumnDefinitions.Clear() | Out-Null
$targetGrid.Children.Clear() | Out-Null
# Add ColumnDefinitions to the target Grid
for ($i = 0; $i -lt $columncount; $i++) {
$colDef = New-Object Windows.Controls.ColumnDefinition
$colDef.Width = New-Object Windows.GridLength(1, [Windows.GridUnitType]::Star)
$targetGrid.ColumnDefinitions.Add($colDef) | Out-Null
}
# Only apply the logic for distributing entries across columns if the targetGridName is "appspanel" # Only apply the logic for distributing entries across columns if the targetGridName is "appspanel"
if ($targetGridName -eq "appspanel") { if ($targetGridName -eq "appspanel") {
@ -98,7 +88,6 @@ function Invoke-WPFUIElements {
$entrycount = $configHashtable.Keys.Count + $organizedData["0"].Keys.Count $entrycount = $configHashtable.Keys.Count + $organizedData["0"].Keys.Count
$maxcount = [Math]::Round($entrycount / $columncount + 0.5) $maxcount = [Math]::Round($entrycount / $columncount + 0.5)
} }
}
# Iterate through 'organizedData' by panel, category, and application # Iterate through 'organizedData' by panel, category, and application
$count = 0 $count = 0
@ -107,7 +96,7 @@ function Invoke-WPFUIElements {
$border = New-Object Windows.Controls.Border $border = New-Object Windows.Controls.Border
$border.VerticalAlignment = "Stretch" # Ensure the border stretches vertically $border.VerticalAlignment = "Stretch" # Ensure the border stretches vertically
[System.Windows.Controls.Grid]::SetColumn($border, $panelcount) [System.Windows.Controls.Grid]::SetColumn($border, $panelcount)
$border.style = $borderstyle $border.style = $window.FindResource("BorderStyle")
$targetGrid.Children.Add($border) | Out-Null $targetGrid.Children.Add($border) | Out-Null
# Create a StackPanel inside the Border # Create a StackPanel inside the Border
@ -127,7 +116,7 @@ function Invoke-WPFUIElements {
$border = New-Object Windows.Controls.Border $border = New-Object Windows.Controls.Border
$border.VerticalAlignment = "Stretch" # Ensure the border stretches vertically $border.VerticalAlignment = "Stretch" # Ensure the border stretches vertically
[System.Windows.Controls.Grid]::SetColumn($border, $panelcount) [System.Windows.Controls.Grid]::SetColumn($border, $panelcount)
$border.style = $borderstyle $border.style = $window.FindResource("BorderStyle")
$targetGrid.Children.Add($border) | Out-Null $targetGrid.Children.Add($border) | Out-Null
# Create a new StackPanel inside the Border # Create a new StackPanel inside the Border
@ -159,7 +148,7 @@ function Invoke-WPFUIElements {
$border = New-Object Windows.Controls.Border $border = New-Object Windows.Controls.Border
$border.VerticalAlignment = "Stretch" # Ensure the border stretches vertically $border.VerticalAlignment = "Stretch" # Ensure the border stretches vertically
[System.Windows.Controls.Grid]::SetColumn($border, $panelcount) [System.Windows.Controls.Grid]::SetColumn($border, $panelcount)
$border.style = $borderstyle $border.style = $window.FindResource("BorderStyle")
$targetGrid.Children.Add($border) | Out-Null $targetGrid.Children.Add($border) | Out-Null
# Create a new StackPanel inside the Border # Create a new StackPanel inside the Border
@ -179,14 +168,13 @@ function Invoke-WPFUIElements {
$checkBox.Name = $entryInfo.Name $checkBox.Name = $entryInfo.Name
$checkBox.HorizontalAlignment = "Right" $checkBox.HorizontalAlignment = "Right"
$dockPanel.Children.Add($checkBox) | Out-Null $dockPanel.Children.Add($checkBox) | Out-Null
$checkBox.Style = $ColorfulToggleSwitchStyle $checkBox.Style = $window.FindResource("ColorfulToggleSwitchStyle")
$label = New-Object Windows.Controls.Label $label = New-Object Windows.Controls.Label
$label.Content = $entryInfo.Content $label.Content = $entryInfo.Content
$label.ToolTip = $entryInfo.Description $label.ToolTip = $entryInfo.Description
$label.HorizontalAlignment = "Left" $label.HorizontalAlignment = "Left"
$label.FontSize = $theme.FontSize $label.FontSize = $theme.FontSize
$label.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
$dockPanel.Children.Add($label) | Out-Null $dockPanel.Children.Add($label) | Out-Null
$stackPanel.Children.Add($dockPanel) | Out-Null $stackPanel.Children.Add($dockPanel) | Out-Null
@ -207,14 +195,14 @@ function Invoke-WPFUIElements {
$toggleButton.HorizontalAlignment = "Left" $toggleButton.HorizontalAlignment = "Left"
$toggleButton.Height = $theme.TabButtonHeight $toggleButton.Height = $theme.TabButtonHeight
$toggleButton.Width = $theme.TabButtonWidth $toggleButton.Width = $theme.TabButtonWidth
$toggleButton.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "ButtonInstallBackgroundColor") $toggleButton.Background = $theme.ButtonInstallBackgroundColor
$toggleButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor") $toggleButton.Foreground = [Windows.Media.Brushes]::White
$toggleButton.FontWeight = [Windows.FontWeights]::Bold $toggleButton.FontWeight = [Windows.FontWeights]::Bold
$textBlock = New-Object Windows.Controls.TextBlock $textBlock = New-Object Windows.Controls.TextBlock
$textBlock.FontSize = $theme.TabButtonFontSize $textBlock.FontSize = $theme.TabButtonFontSize
$textBlock.Background = [Windows.Media.Brushes]::Transparent $textBlock.Background = [Windows.Media.Brushes]::Transparent
$textBlock.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "ButtonInstallForegroundColor") $textBlock.Foreground = $theme.ButtonInstallForegroundColor
$underline = New-Object Windows.Documents.Underline $underline = New-Object Windows.Documents.Underline
$underline.Inlines.Add($entryInfo.name -replace "(.).*", "`$1") $underline.Inlines.Add($entryInfo.name -replace "(.).*", "`$1")
@ -250,7 +238,7 @@ function Invoke-WPFUIElements {
$comboBox.Width = $theme.ButtonWidth $comboBox.Width = $theme.ButtonWidth
$comboBox.HorizontalAlignment = "Left" $comboBox.HorizontalAlignment = "Left"
$comboBox.VerticalAlignment = "Center" $comboBox.VerticalAlignment = "Center"
$comboBox.Margin = $theme.ButtonMargin $comboBox.Margin = "5,5"
foreach ($comboitem in ($entryInfo.ComboItems -split " ")) { foreach ($comboitem in ($entryInfo.ComboItems -split " ")) {
$comboBoxItem = New-Object Windows.Controls.ComboBoxItem $comboBoxItem = New-Object Windows.Controls.ComboBoxItem
@ -272,7 +260,8 @@ function Invoke-WPFUIElements {
$button.Name = $entryInfo.Name $button.Name = $entryInfo.Name
$button.Content = $entryInfo.Content $button.Content = $entryInfo.Content
$button.HorizontalAlignment = "Left" $button.HorizontalAlignment = "Left"
$button.Margin = $theme.ButtonMargin $button.Margin = "5"
$button.Padding = "20,5"
$button.FontSize = $theme.ButtonFontSize $button.FontSize = $theme.ButtonFontSize
if ($entryInfo.ButtonWidth) { if ($entryInfo.ButtonWidth) {
$button.Width = $entryInfo.ButtonWidth $button.Width = $entryInfo.ButtonWidth
@ -292,7 +281,7 @@ function Invoke-WPFUIElements {
$checkBox.FontSize = $theme.FontSize $checkBox.FontSize = $theme.FontSize
$checkBox.ToolTip = $entryInfo.Description $checkBox.ToolTip = $entryInfo.Description
$checkBox.Margin = $theme.CheckBoxMargin $checkBox.Margin = $theme.CheckBoxMargin
if ($entryInfo.Checked -eq $true) { if ($entryInfo.Checked) {
$checkBox.IsChecked = $entryInfo.Checked $checkBox.IsChecked = $entryInfo.Checked
} }
$horizontalStackPanel.Children.Add($checkBox) | Out-Null $horizontalStackPanel.Children.Add($checkBox) | Out-Null
@ -302,7 +291,14 @@ function Invoke-WPFUIElements {
$textBlock.Name = $checkBox.Name + "Link" $textBlock.Name = $checkBox.Name + "Link"
$textBlock.Text = "(?)" $textBlock.Text = "(?)"
$textBlock.ToolTip = $entryInfo.Link $textBlock.ToolTip = $entryInfo.Link
$textBlock.Style = $HoverTextBlockStyle $textBlock.Style = $window.FindResource("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

View File

@ -2,65 +2,43 @@ Function Invoke-WPFUltimatePerformance {
<# <#
.SYNOPSIS .SYNOPSIS
Enables or disables the Ultimate Performance power scheme based on its GUID. Creates or removes the Ultimate Performance power scheme
.PARAMETER State .PARAMETER State
Specifies whether to "Enable" or "Disable" the Ultimate Performance power scheme. Indicates whether to enable or disable the Ultimate Performance power scheme
#> #>
param($State) param($State)
try { try {
# GUID of the Ultimate Performance power plan # Check if Ultimate Performance plan is installed
$ultimateGUID = "e9a42b02-d5df-448d-aa00-03f14749eb61" $ultimatePlan = powercfg -list | Select-String -Pattern "Ultimate Performance"
if($state -eq "Enable") {
if ($State -eq "Enable") { if ($ultimatePlan) {
# Duplicate the Ultimate Performance power plan using its GUID Write-Host "Ultimate Performance plan is already installed."
$duplicateOutput = powercfg /duplicatescheme $ultimateGUID } else {
Write-Host "Installing Ultimate Performance plan..."
$guid = $null powercfg -duplicatescheme e9a42b02-d5df-448d-aa00-03f14749eb61
$nameFromFile = "ChrisTitus - Ultimate Power Plan" Write-Host "> Ultimate Performance plan installed."
$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
}
} }
if (-not $guid) { # Set the Ultimate Performance plan as active
Write-Output "No GUID found in the duplicateOutput. Check the output format." $ultimatePlanGUID = (powercfg -list | Select-String -Pattern "Ultimate Performance").Line.Split()[3]
exit 1 powercfg -setactive $ultimatePlanGUID
Write-Host "Ultimate Performance plan is now active."
} }
elseif($state -eq "Disable") {
# Change the name of the power plan and set its description if ($ultimatePlan) {
$changeNameOutput = powercfg /changename $guid "$nameFromFile" "$description" # Extract the GUID of the Ultimate Performance plan
Write-Output "The power plan name and description have been changed. Output:" $ultimatePlanGUID = $ultimatePlan.Line.Split()[3]
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") {
# Check if the Ultimate Performance plan is installed by GUID
$installedPlan = (powercfg -list | Select-String -Pattern "ChrisTitus - Ultimate Power Plan").Line.Split()[3]
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 = 381b4222-f694-41f0-9685-ff5bb260df2e $balancedPlanGUID = (powercfg -list | Select-String -Pattern "Balanced").Line.Split()[3]
powercfg -setactive $balancedPlanGUID powercfg -setactive $balancedPlanGUID
# Delete the Ultimate Performance plan by GUID # Delete the Ultimate Performance plan
powercfg -delete $ultimatePlanGUID powercfg -delete $ultimatePlanGUID
Write-Host "Ultimate Performance plan has been uninstalled." Write-Host "Ultimate Performance plan has been uninstalled."
@ -70,6 +48,6 @@ Function Invoke-WPFUltimatePerformance {
} }
} }
} catch { } catch {
Write-Error "Error occurred: $_" Write-Warning $psitem.Exception.Message
} }
} }

View File

@ -28,51 +28,38 @@ 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 {
param($PackagesToInstall, $ChocoPreference, $DebugPreference) Invoke-WPFRunspace -ArgumentList $PackagesToInstall -DebugPreference $DebugPreference -ScriptBlock {
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.ArrayList]::new() $packagesWinget = [System.Collections.Generic.List`1[System.Object]]::new()
$packagesChoco = [System.Collections.ArrayList]::new() $packagesChoco = [System.Collections.Generic.List`1[System.Object]]::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 uninstall"
} else {
$null = $packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey uninstall"
}
}
else {
if ($package.winget -eq "na") { if ($package.winget -eq "na") {
$packagesChoco.add($package.choco) $packagesChoco.add($package)
Write-Host "Queueing $($package.choco) for Chocolatey uninstall" Write-Host "Queueing $($package.choco) for Chocolatey Uninstall"
} else { } else {
$null = $packagesWinget.add($($package.winget)) $packagesWinget.add($($package.winget))
Write-Host "Queueing $($package.winget) for Winget uninstall" Write-Host "Queueing $($package.winget) for Winget Uninstall"
}
} }
} }
return $packagesWinget, $packagesChoco 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) {
Install-WinUtilProgramWinget -Action Uninstall -Programs $packagesWinget Invoke-WinUtilWingetProgram -Action Uninstall -Programs $packagesWinget
} }
if($packagesChoco.Count -gt 0) { if($packagesChoco.Count -gt 0) {
Install-WinUtilProgramChoco -Action Uninstall -Programs $packagesChoco Install-WinUtilProgramChoco -ProgramsToInstall $packagesChoco -Manage "Uninstalling"
} }
Write-Host "===========================================" Write-Host "==========================================="

View File

@ -24,12 +24,8 @@ function Invoke-WPFtweaksbutton {
Write-Debug "Number of tweaks to process: $($Tweaks.Count)" Write-Debug "Number of tweaks to process: $($Tweaks.Count)"
# The leading "," in the ParameterList is nessecary because we only provide one argument and powershell cannot be convinced that we want a nested loop with only one argument otherwise Invoke-WPFRunspace -ArgumentList $Tweaks -DebugPreference $DebugPreference -ScriptBlock {
$tweaksHandle = Invoke-WPFRunspace -ParameterList @(,("tweaks",$tweaks)) -DebugPreference $DebugPreference -ScriptBlock { param($Tweaks, $DebugPreference)
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
@ -42,9 +38,8 @@ 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] Invoke-WinUtilTweaks $tweaks[$i]$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i/$Tweaks.Count) })
$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

@ -1,12 +1,5 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block header %}
{{ super() }}
<div style="color: red; text-align: center; padding: 10px; font-size: 20px;">
<strong>Announcement:</strong> We are currently not adding any applications to WinUtil and any apps that will be added through a PR will be declined by the maintainer.
</div>
{% endblock %}
{% block footer %} {% block footer %}
{# Empty block to override the footer #} {# Empty block to override the footer #}
{% endblock %} {% endblock %}

View File

@ -37,12 +37,6 @@ Describe "Config Files" -ForEach @(
$result = New-Object System.Collections.Generic.List[System.Object] $result = New-Object System.Collections.Generic.List[System.Object]
Foreach ($application in $applications) { Foreach ($application in $applications) {
$compare = $global:importedconfigs.$name.$application | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty name $compare = $global:importedconfigs.$name.$application | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty name
if (-not $compare) {
throw "Comparison object for application '$application' is null."
}
if (-not $template) {
throw "Template object for application '$application' is null."
}
if ($(Compare-Object $compare $template) -ne $null) { if ($(Compare-Object $compare $template) -ne $null) {
$result.Add($application) $result.Add($application)
} }

View File

@ -52,84 +52,49 @@ $sync.runspace.Open()
$inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window' $inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window'
if ((Get-WinUtilToggleStatus WPFToggleDarkMode) -eq $True) {
if (Invoke-WinUtilGPU -eq $True) {
$ctttheme = 'Matrix'
} else {
$ctttheme = 'Dark'
}
} else {
$ctttheme = 'Classic'
}
$inputXML = Set-WinUtilUITheme -inputXML $inputXML -themeName $ctttheme
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework') [void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML [xml]$XAML = $inputXML
# Read the XAML file # Read the XAML file
$readerOperationSuccessful = $false # There's more cases of failure then success.
$reader = (New-Object System.Xml.XmlNodeReader $xaml) $reader = (New-Object System.Xml.XmlNodeReader $xaml)
try { try {
$sync["Form"] = [Windows.Markup.XamlReader]::Load( $reader ) $sync["Form"] = [Windows.Markup.XamlReader]::Load( $reader )
$readerOperationSuccessful = $true
} catch [System.Management.Automation.MethodInvocationException] { } catch [System.Management.Automation.MethodInvocationException] {
Write-Host "We ran into a problem with the XAML code. Check the syntax for this control..." -ForegroundColor Red Write-Warning "We ran into a problem with the XAML code. Check the syntax for this control..."
Write-Host $error[0].Exception.Message -ForegroundColor Red Write-Host $error[0].Exception.Message -ForegroundColor Red
If ($error[0].Exception.Message -like "*button*") { If ($error[0].Exception.Message -like "*button*") {
write-Host "Ensure your &lt;button in the `$inputXML does NOT have a Click=ButtonClick property. PS can't handle this`n`n`n`n" -ForegroundColor Red write-warning "Ensure your &lt;button in the `$inputXML does NOT have a Click=ButtonClick property. PS can't handle this`n`n`n`n"
} }
} catch { } catch {
Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed." -ForegroundColor Red Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed."
} }
if (-NOT ($readerOperationSuccessful)) {
Write-Host "Failed to parse xaml content using Windows.Markup.XamlReader's Load Method." -ForegroundColor Red
Write-Host "Quitting winutil..." -ForegroundColor Red
$sync.runspace.Dispose()
$sync.runspace.Close()
[System.GC]::Collect()
exit 1
}
# Setup the Window to follow listen for windows Theme Change events and update the winutil theme
# throttle logic needed, because windows seems to send more than one theme change event per change
$lastThemeChangeTime = [datetime]::MinValue
$debounceInterval = [timespan]::FromSeconds(2)
$sync.Form.Add_Loaded({
$interopHelper = New-Object System.Windows.Interop.WindowInteropHelper $sync.Form
$hwndSource = [System.Windows.Interop.HwndSource]::FromHwnd($interopHelper.Handle)
$hwndSource.AddHook({
param (
[System.IntPtr]$hwnd,
[int]$msg,
[System.IntPtr]$wParam,
[System.IntPtr]$lParam,
[ref]$handled
)
# Check for the Event WM_SETTINGCHANGE (0x1001A) and validate that Button shows the icon for "Auto" => [char]0xF08C
if (($msg -eq 0x001A) -and $sync.ThemeButton.Content -eq [char]0xF08C) {
$currentTime = [datetime]::Now
if ($currentTime - $lastThemeChangeTime -gt $debounceInterval) {
Invoke-WinutilThemeChange -theme "Auto"
$script:lastThemeChangeTime = $currentTime
$handled = $true
}
}
return 0
})
})
Invoke-WinutilThemeChange -init $true
# Load the configuration files # Load the configuration files
#Invoke-WPFUIElements -configVariable $sync.configs.nav -targetGridName "WPFMainGrid" #Invoke-WPFUIElements -configVariable $sync.configs.nav -targetGridName "WPFMainGrid"
Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "appspanel" -columncount 5 Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "appspanel" -columncount 5
Invoke-WPFUIElements -configVariable $sync.configs.tweaks -targetGridName "tweakspanel" -columncount 2 Invoke-WPFUIElements -configVariable $sync.configs.tweaks -targetGridName "tweakspanel" -columncount 2
Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "featurespanel" -columncount 2 Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "featurespanel" -columncount 2
#=========================================================================== #===========================================================================
# Store Form Objects In PowerShell # Store Form Objects In PowerShell
#=========================================================================== #===========================================================================
$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") {
@ -254,34 +219,24 @@ $commonKeyEvents = {
$sync["Form"].Add_PreViewKeyDown($commonKeyEvents) $sync["Form"].Add_PreViewKeyDown($commonKeyEvents)
$sync["Form"].Add_MouseLeftButtonDown({ $sync["Form"].Add_MouseLeftButtonDown({
# Hide Settings and Theme Popup on click anywhere else if ($sync["SettingsPopup"].IsOpen) {
if ($sync.SettingsButton.IsOpen -or $sync["SettingsPopup"].IsOpen = $false
$sync.ThemePopup.IsOpen) {
$sync.SettingsPopup.IsOpen = $false
$sync.ThemePopup.IsOpen = $false
} }
$sync["Form"].DragMove() $sync["Form"].DragMove()
}) })
$sync["Form"].Add_MouseDoubleClick({ $sync["Form"].Add_MouseDoubleClick({
if ($_.OriginalSource -is [System.Windows.Controls.Grid] -or
$_.OriginalSource -is [System.Windows.Controls.StackPanel]) {
if ($sync["Form"].WindowState -eq [Windows.WindowState]::Normal) { if ($sync["Form"].WindowState -eq [Windows.WindowState]::Normal) {
$sync["Form"].WindowState = [Windows.WindowState]::Maximized $sync["Form"].WindowState = [Windows.WindowState]::Maximized;
} } else {
else{ $sync["Form"].WindowState = [Windows.WindowState]::Normal;
$sync["Form"].WindowState = [Windows.WindowState]::Normal
}
} }
}) })
$sync["Form"].Add_Deactivated({ $sync["Form"].Add_Deactivated({
Write-Debug "WinUtil lost focus" Write-Debug "WinUtil lost focus"
# Hide Settings and Theme Popup on Winutil Focus Loss if ($sync["SettingsPopup"].IsOpen) {
if ($sync.SettingsButton.IsOpen -or $sync["SettingsPopup"].IsOpen = $false
$sync.ThemePopup.IsOpen) {
$sync.SettingsPopup.IsOpen = $false
$sync.ThemePopup.IsOpen = $false
} }
}) })
@ -399,35 +354,6 @@ Add-Type @"
}) })
# Add event handlers for the RadioButtons
$sync["ISOdownloader"].add_Checked({
$sync["ISORelease"].Visibility = [System.Windows.Visibility]::Visible
$sync["ISOLanguage"].Visibility = [System.Windows.Visibility]::Visible
})
$sync["ISOmanual"].add_Checked({
$sync["ISORelease"].Visibility = [System.Windows.Visibility]::Collapsed
$sync["ISOLanguage"].Visibility = [System.Windows.Visibility]::Collapsed
})
$sync["ISORelease"].Items.Add("23H2") | Out-Null
$sync["ISORelease"].Items.Add("22H2") | Out-Null
$sync["ISORelease"].Items.Add("21H2") | Out-Null
$sync["ISORelease"].SelectedItem = "23H2"
$sync["ISOLanguage"].Items.Add("System Language ($(Get-FidoLangFromCulture -langName $((Get-Culture).Name)))") | Out-Null
if ($currentCulture -ne "English International") {
$sync["ISOLanguage"].Items.Add("English International") | Out-Null
}
if ($currentCulture -ne "English") {
$sync["ISOLanguage"].Items.Add("English") | Out-Null
}
if ($sync["ISOLanguage"].Items.Count -eq 1) {
$sync["ISOLanguage"].IsEnabled = $false
}
$sync["ISOLanguage"].SelectedIndex = 0
# Load Checkboxes and Labels outside of the Filter function only once on startup for performance reasons # Load Checkboxes and Labels outside of the Filter function only once on startup for performance reasons
$filter = Get-WinUtilVariables -Type CheckBox $filter = Get-WinUtilVariables -Type CheckBox
$CheckBoxes = ($sync.GetEnumerator()).where{ $psitem.Key -in $filter } $CheckBoxes = ($sync.GetEnumerator()).where{ $psitem.Key -in $filter }
@ -450,8 +376,8 @@ $sync["SearchBar"].Add_TextChanged({
$textToSearch = $sync.SearchBar.Text.ToLower() $textToSearch = $sync.SearchBar.Text.ToLower()
foreach ($CheckBox in $CheckBoxes) { foreach ($CheckBox in $CheckBoxes) {
# Skip if the checkbox is null, it doesn't have content or it is the prefer Choco checkbox # Check if the checkbox is null or if it doesn't have content
if ($CheckBox -eq $null -or $CheckBox.Value -eq $null -or $CheckBox.Value.Content -eq $null -or $CheckBox.Name -eq "WPFpreferChocolatey") { if ($CheckBox -eq $null -or $CheckBox.Value -eq $null -or $CheckBox.Value.Content -eq $null) {
continue continue
} }
@ -461,7 +387,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.ToString().ToLower().Contains($textToSearch)) { if ($CheckBox.Value.Content.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
@ -492,78 +418,50 @@ $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\"
[System.IO.Directory]::CreateDirectory($winutildir["path"]) | Out-Null if (-NOT (Test-Path -Path $winutildir["path"])) {
New-Item -Path $winutildir["path"] -ItemType Directory
$winutildir["logo.ico"] = $winutildir["path"] + "cttlogo.ico"
if (Test-Path $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)
$sync["warningrender"] = (Invoke-WinUtilAssets -Type "warning" -Size 512 -Render) # Set the path for the logo and checkmark images
$winutildir["logo.png"] = $winutildir["path"] + "cttlogo.png"
$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"])) {
ConvertTo-Icon -bitmapPath $winutildir["logo.png"] -iconPath $winutildir["logo.ico"]
}
$winutildir["checkmark.png"] = $winutildir["path"] + "checkmark.png"
$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"
$sync["Form"].Add_Activated({ $sync["Form"].Add_Activated({
Set-WinUtilTaskbaritem -overlay "logo" Set-WinUtilTaskbaritem -overlay "logo"
}) })
# Define event handler for ThemeButton click
$sync["ThemeButton"].Add_Click({
if ($sync.ThemePopup.IsOpen) {
$sync.ThemePopup.IsOpen = $false
}
else{
$sync.ThemePopup.IsOpen = $true
}
$sync.SettingsPopup.IsOpen = $false
})
# Define event handlers for menu items
$sync["AutoThemeMenuItem"].Add_Click({
$sync.ThemePopup.IsOpen = $false
Invoke-WinutilThemeChange -theme "Auto"
$_.Handled = $false
})
# Define event handlers for menu items
$sync["DarkThemeMenuItem"].Add_Click({
$sync.ThemePopup.IsOpen = $false
Invoke-WinutilThemeChange -theme "Dark"
$_.Handled = $false
})
# Define event handlers for menu items
$sync["LightThemeMenuItem"].Add_Click({
$sync.ThemePopup.IsOpen = $false
Invoke-WinutilThemeChange -theme "Light"
$_.Handled = $false
})
# Define event handler for button click # Define event handler for button click
$sync["SettingsButton"].Add_Click({ $sync["SettingsButton"].Add_Click({
Write-Debug "SettingsButton clicked" Write-Debug "SettingsButton clicked"
if ($sync.SettingsPopup.IsOpen) { if ($sync["SettingsPopup"].IsOpen) {
$sync.SettingsPopup.IsOpen = $false $sync["SettingsPopup"].IsOpen = $false
} else {
$sync["SettingsPopup"].IsOpen = $true
} }
else{
$sync.SettingsPopup.IsOpen = $true
}
$sync.ThemePopup.IsOpen = $false
$_.Handled = $false $_.Handled = $false
}) })
@ -595,8 +493,12 @@ MicroWin : <a href="https://github.com/KonTy">@KonTy</a>
GitHub : <a href="https://github.com/ChrisTitusTech/winutil">ChrisTitusTech/winutil</a> GitHub : <a href="https://github.com/ChrisTitusTech/winutil">ChrisTitusTech/winutil</a>
Version : <a href="https://github.com/ChrisTitusTech/winutil/releases/tag/$($sync.version)">$($sync.version)</a> Version : <a href="https://github.com/ChrisTitusTech/winutil/releases/tag/$($sync.version)">$($sync.version)</a>
"@ "@
$FontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSize
Show-CustomDialog -Message $authorInfo -LogoSize $LogoSize $HeaderFontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSizeHeader
$IconSize = $sync.configs.themes.$ctttheme.CustomDialogIconSize
$Width = $sync.configs.themes.$ctttheme.CustomDialogWidth
$Height = $sync.configs.themes.$ctttheme.CustomDialogHeight
Show-CustomDialog -Message $authorInfo -Width $Width -Height $Height -FontSize $FontSize -HeaderFontSize $HeaderFontSize -IconSize $IconSize
}) })
$sync["SponsorMenuItem"].Add_Click({ $sync["SponsorMenuItem"].Add_Click({
@ -617,8 +519,12 @@ $sync["SponsorMenuItem"].Add_Click({
$authorInfo += "An error occurred while fetching or processing the sponsors: $_`n" $authorInfo += "An error occurred while fetching or processing the sponsors: $_`n"
} }
Show-CustomDialog -Message $authorInfo -EnableScroll $true $FontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSize
$HeaderFontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSizeHeader
$IconSize = $sync.configs.themes.$ctttheme.CustomDialogIconSize
$Width = $sync.configs.themes.$ctttheme.CustomDialogWidth
$Height = $sync.configs.themes.$ctttheme.CustomDialogHeight
Show-CustomDialog -Message $authorInfo -Width $Width -Height $Height -FontSize $FontSize -HeaderFontSize $HeaderFontSize -IconSize $IconSize -EnableScroll $true
}) })
$sync["Form"].ShowDialog() | out-null $sync["Form"].ShowDialog() | out-null
Stop-Transcript Stop-Transcript

View File

@ -5,7 +5,6 @@
GitHub : https://github.com/ChrisTitusTech GitHub : https://github.com/ChrisTitusTech
Version : #{replaceme} Version : #{replaceme}
#> #>
param ( param (
[switch]$Debug, [switch]$Debug,
[string]$Config, [string]$Config,
@ -28,6 +27,12 @@ if ($Run) {
$PARAM_RUN = $true $PARAM_RUN = $true
} }
if (!(Test-Path -Path $ENV:TEMP)) {
New-Item -ItemType Directory -Force -Path $ENV:TEMP
}
Start-Transcript $ENV:TEMP\Winutil.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
@ -39,38 +44,15 @@ $sync.version = "#{replaceme}"
$sync.configs = @{} $sync.configs = @{}
$sync.ProcessRunning = $false $sync.ProcessRunning = $false
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { # If script isn't running as admin, show error message and quit
Write-Output "Winutil needs to be run as Administrator. Attempting to relaunch." If (([Security.Principal.WindowsIdentity]::GetCurrent()).Owner.Value -ne "S-1-5-32-544") {
$argList = @() Write-Host "===========================================" -Foregroundcolor Red
Write-Host "-- Scripts must be run as Administrator ---" -Foregroundcolor Red
$PSBoundParameters.GetEnumerator() | ForEach-Object { Write-Host "-- Right-Click Start -> Terminal(Admin) ---" -Foregroundcolor Red
$argList += if ($_.Value -is [switch] -and $_.Value) { Write-Host "===========================================" -Foregroundcolor Red
"-$($_.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'"
}
$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 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

@ -39,7 +39,7 @@ function Invoke-Preprocessing {
.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 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'. 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).
.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"
@ -72,45 +72,22 @@ function Invoke-Preprocessing {
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."
} }
$InternalExcludedFiles = [System.Collections.Generic.List[string]]::new($ExcludedFiles.Count) $count = $ExcludedFiles.Count
ForEach ($excludedFile in $ExcludedFiles) { if ((-NOT ($count -eq 0)) -AND (-NOT $SkipExcludedFilesValidation)) {
$InternalExcludedFiles.Add($excludedFile) | Out-Null for ($i = 0; $i -lt $count; $i++) {
} $excludedFile = $ExcludedFiles[$i]
# Validate the ExcludedItems List before continuing on,
# that's if there's a list in the first place, and '-SkipInternalExcludedFilesValidation' was not provided.
if ($ExcludedFiles.Count -gt 0) {
ForEach ($excludedFile in $ExcludedFiles) {
$filePath = "$(($WorkingDir -replace ('\\$', '')) + '\' + ($excludedFile -replace ('\.\\', '')))" $filePath = "$(($WorkingDir -replace ('\\$', '')) + '\' + ($excludedFile -replace ('\.\\', '')))"
$files = Get-ChildItem -Recurse -Path "$filePath" -File -Force if (-NOT (Get-ChildItem -Recurse -Path "$filePath" -File)) {
if ($files.Count -gt 0) { $failedFilesList += "'$filePath', "
ForEach ($file in $files) {
$InternalExcludedFiles.Add("$($file.FullName)") | Out-Null
} }
} else { $failedFilesList += "'$filePath', " }
} }
$failedFilesList = $failedFilesList -replace (',\s*$', '') $failedFilesList = $failedFilesList -replace (',\s*$', '')
if ((-not $failedFilesList -eq "") -and (-not $SkipExcludedFilesValidation)) { if (-NOT $failedFilesList -eq "") {
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" 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"
} }
} }
# Get Files List $files = Get-ChildItem $WorkingDir -Recurse -Exclude $ExcludedFiles -File
[System.Collections.ArrayList]$files = Get-ChildItem -LiteralPath $WorkingDir -Recurse -Exclude $InternalExcludedFiles -File -Force
# Only keep the 'FullName' Property for every entry in the list
for ($i = 0; $i -lt $files.Count; $i++) {
$file = $files[$i]
$files[$i] = $file.FullName
}
# If a file(s) are found in Exclude List,
# Remove the file from files list.
ForEach ($excludedFile in $InternalExcludedFiles) {
$index = $files.IndexOf("$excludedFile")
if ($index -ge 0) { $files.RemoveAt($index) }
}
$numOfFiles = $files.Count $numOfFiles = $files.Count
if ($numOfFiles -eq 0) { if ($numOfFiles -eq 0) {
@ -122,11 +99,26 @@ function Invoke-Preprocessing {
} }
for ($i = 0; $i -lt $numOfFiles; $i++) { for ($i = 0; $i -lt $numOfFiles; $i++) {
$fullFileName = $files[$i] $file = $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 "$fullFileName").TrimEnd() ` (Get-Content "$file").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} {') `
@ -137,8 +129,8 @@ function Invoke-Preprocessing {
-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>\[[^$0-9]+\])\s*(?<str_after_type>\$.*?)', '${parameter_type}${str_after_type}') ` -replace ('(?<parameter_type>\[.*?\])\s*(?<str_after_type>\$.*?(,|\s*\)))', '${parameter_type}${str_after_type}') `
| Set-Content "$fullFileName" | Set-Content "$file"
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

@ -34,20 +34,7 @@ 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

File diff suppressed because it is too large Load Diff