Compare commits

..

1 Commits

Author SHA1 Message Date
655324b927 Revert "Modify Compile.ps1 Handling of Xaml to Improve Maintainability (#2701)"
This reverts commit 00668755c9.
2024-09-11 10:06:25 -05:00
38 changed files with 975 additions and 1487 deletions

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.

3
.github/mkdocs.yml vendored
View File

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

View File

@ -19,6 +19,10 @@ template: |
$CHANGES
## Contributors
$CONTRIBUTORS
change-title-escapes: '\<*_&"'''
autolabeler:
- label: 'documentation'

View File

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

@ -73,8 +73,8 @@ Get-ChildItem "functions" -Recurse -File | ForEach-Object {
}
Update-Progress "Adding: Config *.json" 40
Get-ChildItem "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("'","''")
$jsonAsObject = $json | convertfrom-json
# Add 'WPFInstall' as a prefix to every entry-name in 'applications.json' file
if ($psitem.Name -eq "applications.json") {
@ -85,26 +85,19 @@ Get-ChildItem "config" | Where-Object {$psitem.extension -eq ".json"} | ForEach-
}
}
# Line 90 requires no whitespace inside the here-strings, to keep formatting of the JSON in the final script.
$json = @"
$($jsonAsObject | ConvertTo-Json -Depth 3)
"@
# The replace at the end is required, as without it the output of 'converto-json' will be somewhat weird for Multiline Strings
# 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
$json = ($jsonAsObject | convertto-json -Depth 3).replace('\r\n',"`r`n")
$sync.configs.$($psitem.BaseName) = $json | ConvertFrom-Json
$script_content.Add($(Write-Output "`$sync.configs.$($psitem.BaseName) = @'`n$json`n'@ `| ConvertFrom-Json" ))
$sync.configs.$($psitem.BaseName) = $json | 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" -Raw
$xaml = (Get-Content "xaml\inputXML.xaml").replace("'","''")
Update-Progress "Adding: Xaml " 90
# Add the XAML content to $script_content using a here-string
$script_content.Add(@"
`$inputXML = @'
$xaml
'@
"@)
$script_content.Add($(Write-output "`$inputXML = '$xaml'"))
$script_content.Add($(Get-Content "scripts\main.ps1"))

File diff suppressed because one or more lines are too long

View File

@ -445,7 +445,7 @@
"category": "Utilities",
"content": "Dual Monitor Tools",
"link": "https://dualmonitortool.sourceforge.net/",
"description": "Dual Monitor Tools (DMT) is a FOSS app that allows you to customize the handling of multiple monitors. Useful for fullscreen games and apps that handle a second monitor poorly and can improve your workflow."
"description": "Dual Monitor Tools (DMT) is a FOSS app that customize handling multiple monitors and even lock the mouse on specific monitor. Useful for full screen games and apps that does not handle well a second monitor or helps the workflow."
},
"duplicati": {
"category": "Utilities",
@ -2855,6 +2855,14 @@
"link": "https://www.kicad.org/",
"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": {
"category": "Utilities",
"choco": "na",

View File

@ -46,23 +46,5 @@
"Secondary": "94.140.15.16",
"Primary6": "2a10:50c0::bad1: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

@ -313,13 +313,5 @@
"Order": "a083_",
"Type": "Button",
"ButtonWidth": "300"
},
"WPFWinUtilSSHServer": {
"Content": "Enable OpenSSH Server",
"category": "Remote Access",
"panel": "2",
"Order": "a084_",
"Type": "Button",
"ButtonWidth": "300"
},
}
}

View File

@ -1,44 +1,36 @@
{
"shared":{
"_default": {
"CustomDialogFontSize": "12",
"CustomDialogFontSizeHeader": "14",
"CustomDialogIconSize": "25",
"CustomDialogWidth": "400",
"CustomDialogHeight": "200",
"FontSize": "12",
"FontFamily": "Arial",
"FontSizeHeading": "16",
"HeaderFontFamily": "Consolas, Monaco",
"CheckBoxBulletDecoratorSize": "14",
"CheckBoxMargin": "15,0,0,2",
"TabContentMargin": "5",
"TabButtonFontSize": "14",
"TabButtonWidth": "110",
"TabButtonHeight": "26",
"TabButtonWidth": "100",
"TabButtonHeight": "25",
"TabRowHeightInPixels": "50",
"IconFontSize": "14",
"IconButtonSize": "35",
"SettingsIconFontSize": "18",
"CloseIconFontSize": "18",
"MicroWinLogoSize": "10",
"MicrowinCheckBoxMargin": "-10,5,0,0",
"GroupBorderBackgroundColor": "#232629",
"ButtonFontSize": "12",
"ButtonFontFamily": "Arial",
"ButtonWidth": "200",
"ButtonHeight": "25",
"ConfigTabButtonFontSize": "16",
"SearchBarWidth": "200",
"SearchBarHeight": "26",
"SearchBarTextBoxFontSize": "12",
"SearchBarClearButtonFontSize": "14",
"CheckboxMouseOverColor": "#999999",
"ButtonBorderThickness": "1",
"ButtonMargin": "1",
"ButtonCornerRadius": "2"
},
"Light": {
"ComboBoxForegroundColor": "#232629",
"ProgressBarForegroundColor": "#2e77ff",
"ProgressBarBackgroundColor": "Transparent",
"ProgressBarTextColor": "#232629",
"ComboBoxBackgroundColor": "#F7F7F7",
"LabelboxForegroundColor": "#232629",
"MainForegroundColor": "#232629",
@ -46,13 +38,20 @@
"LabelBackgroundColor": "#F7F7F7",
"LinkForegroundColor": "#232629",
"LinkHoverForegroundColor": "#232629",
"ScrollBarBackgroundColor": "#4A4D52",
"ScrollBarHoverColor": "#5A5D62",
"ScrollBarDraggingColor": "#6A6D72",
"GroupBorderBackgroundColor": "#232629",
"ComboBoxForegroundColor": "#232629",
"ButtonFontSize": "12",
"ButtonFontFamily": "Arial",
"ButtonWidth": "200",
"ButtonHeight": "25",
"ConfigTabButtonFontSize": "16",
"SearchBarWidth": "200",
"SearchBarHeight": "25",
"SearchBarTextBoxFontSize": "12",
"SearchBarClearButtonFontSize": "14",
"ProgressBarForegroundColor": "#2e77ff",
"ProgressBarBackgroundColor": "Transparent",
"ProgressBarTextColor": "#232629",
"ButtonInstallBackgroundColor": "#F7F7F7",
"ButtonTweaksBackgroundColor": "#F7F7F7",
"ButtonConfigBackgroundColor": "#F7F7F7",
@ -63,31 +62,60 @@
"ButtonUpdatesForegroundColor": "#232629",
"ButtonBackgroundColor": "#F5F5F5",
"ButtonBackgroundPressedColor": "#1A1A1A",
"CheckboxMouseOverColor": "#999999",
"ButtonBackgroundMouseoverColor": "#C2C2C2",
"ButtonBackgroundSelectedColor": "#F0F0F0",
"ButtonForegroundColor": "#232629",
"ToggleButtonOnColor": "#2e77ff",
"ToggleButtonOffColor": "#707070",
"BorderColor": "#232629",
"BorderOpacity": "0.2"
"ButtonBorderThickness": "1",
"ButtonMargin": "1",
"ButtonCornerRadius": "2",
"BorderColor": "#232629",
"BorderOpacity": "0.2",
"ShadowPulse": "Forever"
},
"Dark": {
"ComboBoxForegroundColor": "#F7F7F7",
"ComboBoxBackgroundColor": "#1E3747",
"LabelboxForegroundColor": "#0567ff",
"Classic": {
"ComboBoxBackgroundColor": "#F7F7F7",
"LabelboxForegroundColor": "#232629",
"MainForegroundColor": "#232629",
"MainBackgroundColor": "#F7F7F7",
"LabelBackgroundColor": "#F7F7F7",
"LinkForegroundColor": "#232629",
"LinkHoverForegroundColor": "#232629",
"GroupBorderBackgroundColor": "#232629",
"ComboBoxForegroundColor": "#232629",
"ButtonInstallBackgroundColor": "#F7F7F7",
"ButtonTweaksBackgroundColor": "#F7F7F7",
"ButtonConfigBackgroundColor": "#F7F7F7",
"ButtonUpdatesBackgroundColor": "#F7F7F7",
"ButtonInstallForegroundColor": "#232629",
"ButtonTweaksForegroundColor": "#232629",
"ButtonConfigForegroundColor": "#232629",
"ButtonUpdatesForegroundColor": "#232629",
"ButtonBackgroundColor": "#F5F5F5",
"ButtonBackgroundPressedColor": "#1A1A1A",
"CheckboxMouseOverColor": "#999999",
"ButtonBackgroundMouseoverColor": "#C2C2C2",
"ButtonBackgroundSelectedColor": "#F0F0F0",
"ButtonForegroundColor": "#232629",
"ToggleButtonOnColor": "#2e77ff"
},
"Matrix": {
"ComboBoxBackgroundColor": "#232629",
"LabelboxForegroundColor": "#81a1c1",
"MainForegroundColor": "#F7F7F7",
"MainBackgroundColor": "#232629",
"LabelBackgroundColor": "#232629",
"LinkForegroundColor": "#add8e6",
"LinkHoverForegroundColor": "#F7F7F7",
"ScrollBarBackgroundColor": "#2E3135",
"ScrollBarHoverColor": "#3B4252",
"ScrollBarDraggingColor": "#5E81AC",
"ComboBoxForegroundColor": "#81a1c1",
"ProgressBarForegroundColor": "#222222",
"ProgressBarBackgroundColor": "Transparent",
"ProgressBarTextColor": "#cccccc",
"ButtonInstallBackgroundColor": "#222222",
"ButtonTweaksBackgroundColor": "#333333",
"ButtonConfigBackgroundColor": "#444444",
@ -102,8 +130,40 @@
"ButtonBackgroundSelectedColor": "#5E81AC",
"ButtonForegroundColor": "#F7F7F7",
"ToggleButtonOnColor": "#2e77ff",
"ToggleButtonOffColor": "#707070",
"BorderColor": "#2F373D",
"BorderOpacity": "0.2"
"BorderColor": "#0060CC",
"BorderOpacity": "0.2",
"ShadowPulse": "0:0:3"
},
"Dark": {
"ComboBoxBackgroundColor": "#232629",
"LabelboxForegroundColor": "#81a1c1",
"MainForegroundColor": "#F7F7F7",
"MainBackgroundColor": "#232629",
"LabelBackgroundColor": "#232629",
"LinkForegroundColor": "#add8e6",
"LinkHoverForegroundColor": "#F7F7F7",
"ComboBoxForegroundColor": "#81a1c1",
"ProgressBarForegroundColor": "#222222",
"ProgressBarBackgroundColor": "Transparent",
"ProgressBarTextColor": "#cccccc",
"ButtonInstallBackgroundColor": "#222222",
"ButtonTweaksBackgroundColor": "#333333",
"ButtonConfigBackgroundColor": "#444444",
"ButtonUpdatesBackgroundColor": "#555555",
"ButtonInstallForegroundColor": "#F7F7F7",
"ButtonTweaksForegroundColor": "#F7F7F7",
"ButtonConfigForegroundColor": "#F7F7F7",
"ButtonUpdatesForegroundColor": "#F7F7F7",
"ButtonBackgroundColor": "#1E3747",
"ButtonBackgroundPressedColor": "#00CFFF",
"ButtonBackgroundMouseoverColor": "#5E81AC",
"ButtonBackgroundSelectedColor": "#5E81AC",
"ButtonForegroundColor": "#F7F7F7",
"ToggleButtonOnColor": "#2e77ff",
"BorderColor": "#0b1215"
}
}

View File

@ -1600,6 +1600,13 @@
"Value": "0",
"OriginalValue": "1"
},
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "EdgeEnhanceImagesEnabled",
"Type": "DWord",
"Value": "0",
"OriginalValue": "1"
},
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "PersonalizationReportingEnabled",
@ -1649,6 +1656,13 @@
"Value": "0",
"OriginalValue": "1"
},
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "EdgeFollowEnabled",
"Type": "DWord",
"Value": "0",
"OriginalValue": "1"
},
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "EdgeShoppingAssistantEnabled",
@ -1712,6 +1726,13 @@
"Value": "0",
"OriginalValue": "1"
},
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "ConfigureDoNotTrack",
"Type": "DWord",
"Value": "1",
"OriginalValue": "0"
},
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "WalletDonationEnabled",
@ -2409,6 +2430,12 @@
"Order": "a001_",
"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
try {
# Try getting restore points to check if System Restore is enabled
@ -2740,48 +2767,6 @@
],
"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": {
"Content": "Disable Notification Tray/Calendar",
"Description": "Disables all Notifications INCLUDING Calendar",
@ -3414,7 +3399,7 @@
"panel": "1",
"Order": "a040_",
"Type": "Combobox",
"ComboItems": "Default DHCP Google Cloudflare Cloudflare_Malware Cloudflare_Malware_Adult Open_DNS Quad9 AdGuard_Ads_Trackers AdGuard_Ads_Trackers_Malware_Adult dns0.eu_Open dns0.eu_ZERO dns0.eu_KIDS",
"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"
},
"WPFAddUltPerf": {

View File

@ -1,117 +1,3 @@
# How to Contribute?
--8<-- ".github/CONTRIBUTING.md"
## 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#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.
<!-- The content is sourced from "CONTRIBUTING.md," located in the root directory of the project. -->

View File

@ -34,9 +34,8 @@
* 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)
![Install Image](assets/Install-Tab-Dark.png#only-dark)
![Install Image](assets/Install-Tab-Light.png#only-light)
!!! tip
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 +43,8 @@
## Tweaks
---
![Tweaks Image](assets/Tweaks-Tab-Dark.png#only-dark#gh-dark-mode-only)
![Tweaks Image](assets/Tweaks-Tab-Light.png#only-light#gh-light-mode-only)
![Tweaks Image](assets/Tweaks-Tab-Dark.png#only-dark)
![Tweaks Image](assets/Tweaks-Tab-Light.png#only-light)
### Run Tweaks
* **Open Tweaks Tab**: Navigate to the 'Tweaks' tab in the application.
@ -142,10 +141,6 @@ Open old-school Windows panels directly from WinUtil. Following Panels are avail
* System Properties
* User Accounts
### Remote Access
Enables OpenSSH server on your windows machine.
## Updates
---
@ -180,8 +175,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](assets/Microwin-Dark.png#only-dark#gh-dark-mode-only)
![Microwin](assets/Microwin-Light.png#only-light#gh-light-mode-only)
![Microwin](assets/Microwin-Dark.png#only-dark)
![Microwin](assets/Microwin-Light.png#only-light)
#### Basic usage
@ -239,12 +234,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
* 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-Light.png#only-light#gh-light-mode-only)
![GetInstalled](assets/Get-Installed-Dark.png#only-dark)
![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.
![SettingsExport](assets/Settings-Export-Dark.png#only-dark#gh-dark-mode-only)
![SettingsExport](assets/Settings-Export-Light.png#only-light#gh-light-mode-only)
![SettingsExport](assets/Settings-Export-Dark.png#only-dark)
![SettingsExport](assets/Settings-Export-Light.png#only-light)
* Copy this file to a USB or somewhere you can use it after Windows installation.

View File

@ -19,10 +19,10 @@ function Copy-Files {
try {
$files = Get-ChildItem -Path $path -Recurse:$recurse
Write-Host "Copy $($files.Count) file(s) from $path to $destination"
Write-Host "Copy $($files.Count)(s) from $path to $destination"
foreach ($file in $files) {
$status = "Copying file {0} of {1}: {2}" -f $counter, $files.Count, $file.Name
$status = "Copy files {0} on {1}: {2}" -f $counter, $files.Count, $file.Name
Write-Progress -Activity "Copy Windows files" -Status $status -PercentComplete ($counter++/$files.count*100)
$restpath = $file.FullName -Replace $path, ''
@ -37,11 +37,7 @@ function Copy-Files {
}
Write-Progress -Activity "Copy Windows files" -Status "Ready" -Completed
} catch {
Write-Host "Unable to Copy all the files due to an unhandled exception" -ForegroundColor Yellow
Write-Host "Error information: $($_.Exception.Message)`n" -ForegroundColor Yellow
Write-Host "Additional information:" -ForegroundColor Yellow
Write-Host $PSItem.Exception.StackTrace
# Write possible suggestions
Write-Host "`nIf you are using an antivirus, try configuring exclusions"
Write-Warning "Unable to Copy all the files due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
}

View File

@ -16,72 +16,136 @@ Function Get-WinUtilToggleStatus {
if($ToggleSwitch -eq "WPFToggleDarkMode") {
$app = (Get-ItemProperty -path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize').AppsUseLightTheme
$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") {
$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") {
$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") {
$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") {
$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") {
$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") {
$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") {
$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") {
$MouseSpeed = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseSpeed
$MouseThreshold1 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold1
$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") {
$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") {
$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") {
$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") {
$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") {
$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") {
$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") {
$DetailedBSoD1 = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisplayParameters
$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") {
return
}
# Install logic taken from https://chocolatey.org/install#individual
Write-Host "Seems Chocolatey is not installed, installing now."
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Start-Process -FilePath "powershell" -ArgumentList "Set-ExecutionPolicy Bypass -Scope Process -Force; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) -ErrorAction Stop" -Wait -NoNewWindow
Start-Process -FilePath "powershell" -ArgumentList "choco feature enable -n allowGlobalConfirmation" -Wait -NoNewWindow
} catch {
Write-Host "===========================================" -Foregroundcolor Red

View File

@ -21,11 +21,6 @@ Function Invoke-WinUtilDarkMode {
$Path = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize"
Set-ItemProperty -Path $Path -Name AppsUseLightTheme -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] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} 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

@ -25,67 +25,6 @@ function Test-CompatibleImage() {
}
}
class ErroredPackage {
[string]$PackageName
[string]$ErrorMessage
ErroredPackage() { $this.Init(@{} )}
# Constructor for packages that have errored out
ErroredPackage([string]$pkgName, [string]$reason) {
$this.PackageName = $pkgName
$this.ErrorMessage = $reason
}
}
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() {
<#
.SYNOPSIS
@ -108,9 +47,6 @@ function Remove-Features() {
$_.FeatureName -NotLike "*NetFx*" -AND
$_.FeatureName -NotLike "*Media*" -AND
$_.FeatureName -NotLike "*NFS*" -AND
$_.FeatureName -NotLike "*SearchEngine*" -AND
$_.FeatureName -NotLike "*RemoteDesktop*" -AND
$_.FeatureName -NotLike "*Recall*" -AND
$_.State -ne "Disabled"
}
@ -158,7 +94,6 @@ function Remove-Packages {
$_ -NotLike "*ParentalControls*" -AND
$_ -NotLike "*Win32WebViewHost*" -AND
$_ -NotLike "*InputApp*" -AND
$_ -NotLike "*DirectPlay*" -AND
$_ -NotLike "*AccountsControl*" -AND
$_ -NotLike "*AsyncTextService*" -AND
$_ -NotLike "*CapturePicker*" -AND
@ -170,54 +105,27 @@ function Remove-Packages {
$_ -NotLike "*WMIC*" -AND
$_ -NotLike "*UI.XaML*" -AND
$_ -NotLike "*Ethernet*" -AND
$_ -NotLike "*Wifi*" -AND
$_ -NotLike "*FodMetadata*" -AND
$_ -NotLike "*Foundation*" -AND
$_ -NotLike "*LanguageFeatures*" -AND
$_ -NotLike "*VBSCRIPT*" -AND
$_ -NotLike "*License*"
$_ -NotLike "*Wifi*"
}
$failedCount = 0
$erroredPackages = [System.Collections.Generic.List[ErroredPackage]]::new()
foreach ($pkg in $pkglist) {
try {
$status = "Removing $pkg"
Write-Progress -Activity "Removing Packages" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
Write-Progress -Activity "Removing Apps" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
Remove-WindowsPackage -Path "$scratchDir" -PackageName $pkg -NoRestart -ErrorAction SilentlyContinue
} catch {
# This can happen if the package that is being removed is a permanent one
$erroredPackages.Add([ErroredPackage]::new($pkg, $_.Exception.Message))
# This can happen if the package that is being removed is a permanent one, like FodMetadata
Write-Host "Could not remove OS package $($pkg)"
$failedCount += 1
continue
}
}
Write-Progress -Activity "Removing Packages" -Status "Ready" -Completed
Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed
if ($failedCount -gt 0)
{
Write-Host "$failedCount package(s) could not be removed. Your image will still work fine, however. Below is information on what packages failed to be removed and why."
if ($erroredPackages.Count -gt 0)
{
$erroredPackages = $erroredPackages | Sort-Object -Property ErrorMessage
$previousErroredPackage = $erroredPackages[0]
$counter = 0
Write-Host ""
Write-Host "- $($previousErroredPackage.ErrorMessage)"
foreach ($erroredPackage in $erroredPackages) {
if ($erroredPackage.ErrorMessage -ne $previousErroredPackage.ErrorMessage) {
Write-Host ""
$counter = 0
Write-Host "- $($erroredPackage.ErrorMessage)"
}
$counter += 1
Write-Host " $counter) $($erroredPackage.PackageName)"
$previousErroredPackage = $erroredPackage
}
Write-Host ""
}
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 {
Write-Host "Unable to get information about the packages. MicroWin processing will continue, but packages will not be processed"
@ -241,8 +149,13 @@ function Remove-ProvisionedPackages() {
$appxProvisionedPackages = Get-AppxProvisionedPackage -Path "$($scratchDir)" | Where-Object {
$_.PackageName -NotLike "*AppInstaller*" -AND
$_.PackageName -NotLike "*Store*" -and
$_.PackageName -NotLike "*dism*" -and
$_.PackageName -NotLike "*Foundation*" -and
$_.PackageName -NotLike "*FodMetadata*" -and
$_.PackageName -NotLike "*LanguageFeatures*" -and
$_.PackageName -NotLike "*Notepad*" -and
$_.PackageName -NotLike "*Printing*" -and
$_.PackageName -NotLike "*Foundation*" -and
$_.PackageName -NotLike "*YourPhone*" -and
$_.PackageName -NotLike "*Xbox*" -and
$_.PackageName -NotLike "*WindowsTerminal*" -and
@ -252,8 +165,7 @@ function Remove-ProvisionedPackages() {
$_.PackageName -NotLike "*Paint*" -and
$_.PackageName -NotLike "*Gaming*" -and
$_.PackageName -NotLike "*Extension*" -and
$_.PackageName -NotLike "*SecHealthUI*" -and
$_.PackageName -NotLike "*ScreenSketch*"
$_.PackageName -NotLike "*SecHealthUI*"
}
$counter = 0
@ -660,70 +572,70 @@ function New-CheckInstall {
# using here string to embedd firstrun
$checkInstall = @'
@echo off
if exist "%HOMEDRIVE%\windows\cpu.txt" (
echo %HOMEDRIVE%\windows\cpu.txt exists
if exist "C:\windows\cpu.txt" (
echo C:\windows\cpu.txt exists
) else (
echo %HOMEDRIVE%\windows\cpu.txt does not exist
echo C:\windows\cpu.txt does not exist
)
if exist "%HOMEDRIVE%\windows\SerialNumber.txt" (
echo %HOMEDRIVE%\windows\SerialNumber.txt exists
if exist "C:\windows\SerialNumber.txt" (
echo C:\windows\SerialNumber.txt exists
) else (
echo %HOMEDRIVE%\windows\SerialNumber.txt does not exist
echo C:\windows\SerialNumber.txt does not exist
)
if exist "%HOMEDRIVE%\unattend.xml" (
echo %HOMEDRIVE%\unattend.xml exists
if exist "C:\unattend.xml" (
echo C:\unattend.xml exists
) else (
echo %HOMEDRIVE%\unattend.xml does not exist
echo C:\unattend.xml does not exist
)
if exist "%HOMEDRIVE%\Windows\Setup\Scripts\SetupComplete.cmd" (
echo %HOMEDRIVE%\Windows\Setup\Scripts\SetupComplete.cmd exists
if exist "C:\Windows\Setup\Scripts\SetupComplete.cmd" (
echo C:\Windows\Setup\Scripts\SetupComplete.cmd exists
) else (
echo %HOMEDRIVE%\Windows\Setup\Scripts\SetupComplete.cmd does not exist
echo C:\Windows\Setup\Scripts\SetupComplete.cmd does not exist
)
if exist "%HOMEDRIVE%\Windows\Panther\unattend.xml" (
echo %HOMEDRIVE%\Windows\Panther\unattend.xml exists
if exist "C:\Windows\Panther\unattend.xml" (
echo C:\Windows\Panther\unattend.xml exists
) else (
echo %HOMEDRIVE%\Windows\Panther\unattend.xml does not exist
echo C:\Windows\Panther\unattend.xml does not exist
)
if exist "%HOMEDRIVE%\Windows\System32\Sysprep\unattend.xml" (
echo %HOMEDRIVE%\Windows\System32\Sysprep\unattend.xml exists
if exist "C:\Windows\System32\Sysprep\unattend.xml" (
echo C:\Windows\System32\Sysprep\unattend.xml exists
) else (
echo %HOMEDRIVE%\Windows\System32\Sysprep\unattend.xml does not exist
echo C:\Windows\System32\Sysprep\unattend.xml does not exist
)
if exist "%HOMEDRIVE%\Windows\FirstStartup.ps1" (
echo %HOMEDRIVE%\Windows\FirstStartup.ps1 exists
if exist "C:\Windows\FirstStartup.ps1" (
echo C:\Windows\FirstStartup.ps1 exists
) else (
echo %HOMEDRIVE%\Windows\FirstStartup.ps1 does not exist
echo C:\Windows\FirstStartup.ps1 does not exist
)
if exist "%HOMEDRIVE%\Windows\winutil.ps1" (
echo %HOMEDRIVE%\Windows\winutil.ps1 exists
if exist "C:\Windows\winutil.ps1" (
echo C:\Windows\winutil.ps1 exists
) else (
echo %HOMEDRIVE%\Windows\winutil.ps1 does not exist
echo C:\Windows\winutil.ps1 does not exist
)
if exist "%HOMEDRIVE%\Windows\LogSpecialize.txt" (
echo %HOMEDRIVE%\Windows\LogSpecialize.txt exists
if exist "C:\Windows\LogSpecialize.txt" (
echo C:\Windows\LogSpecialize.txt exists
) else (
echo %HOMEDRIVE%\Windows\LogSpecialize.txt does not exist
echo C:\Windows\LogSpecialize.txt does not exist
)
if exist "%HOMEDRIVE%\Windows\LogAuditUser.txt" (
echo %HOMEDRIVE%\Windows\LogAuditUser.txt exists
if exist "C:\Windows\LogAuditUser.txt" (
echo C:\Windows\LogAuditUser.txt exists
) else (
echo %HOMEDRIVE%\Windows\LogAuditUser.txt does not exist
echo C:\Windows\LogAuditUser.txt does not exist
)
if exist "%HOMEDRIVE%\Windows\LogOobeSystem.txt" (
echo %HOMEDRIVE%\Windows\LogOobeSystem.txt exists
if exist "C:\Windows\LogOobeSystem.txt" (
echo C:\Windows\LogOobeSystem.txt exists
) else (
echo %HOMEDRIVE%\Windows\LogOobeSystem.txt does not exist
echo C:\Windows\LogOobeSystem.txt does not exist
)
if exist "%HOMEDRIVE%\windows\csup.txt" (
echo %HOMEDRIVE%\windows\csup.txt exists
if exist "c:\windows\csup.txt" (
echo c:\windows\csup.txt exists
) else (
echo %HOMEDRIVE%\windows\csup.txt does not exist
echo c:\windows\csup.txt does not exist
)
if exist "%HOMEDRIVE%\windows\LogFirstRun.txt" (
echo %HOMEDRIVE%\windows\LogFirstRun.txt exists
if exist "c:\windows\LogFirstRun.txt" (
echo c:\windows\LogFirstRun.txt exists
) else (
echo %HOMEDRIVE%\windows\LogFirstRun.txt does not exist
echo c:\windows\LogFirstRun.txt does not exist
)
'@
$checkInstall | Out-File -FilePath "$env:temp\checkinstall.cmd" -Force -Encoding Ascii
@ -761,7 +673,7 @@ function New-FirstRun {
}
}
"FirstStartup has worked" | Out-File -FilePath "$env:HOMEDRIVE\windows\LogFirstRun.txt" -Append -NoClobber
"FirstStartup has worked" | Out-File -FilePath c:\windows\LogFirstRun.txt -Append -NoClobber
$taskbarPath = "$env:AppData\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar"
# Delete all files on the Taskbar
@ -781,7 +693,7 @@ function New-FirstRun {
}
}
Remove-Item -Path "$env:USERPROFILE\Desktop\*.lnk"
Remove-Item -Path "$env:HOMEDRIVE\Users\Default\Desktop\*.lnk"
Remove-Item -Path "C:\Users\Default\Desktop\*.lnk"
# ************************************************
# Create WinUtil shortcut on the desktop
@ -797,8 +709,8 @@ function New-FirstRun {
# Create a shortcut object
$shortcut = $shell.CreateShortcut($shortcutPath)
if (Test-Path -Path "$env:HOMEDRIVE\Windows\cttlogo.png") {
$shortcut.IconLocation = "$env:HOMEDRIVE\Windows\cttlogo.png"
if (Test-Path -Path "c:\Windows\cttlogo.png") {
$shortcut.IconLocation = "c:\Windows\cttlogo.png"
}
# Set properties of the shortcut
@ -818,17 +730,8 @@ function New-FirstRun {
# Done create WinUtil shortcut on the desktop
# ************************************************
try
{
if ((Get-WindowsOptionalFeature -Online | Where-Object { $_.FeatureName -like "Recall" }).Count -gt 0)
{
Disable-WindowsOptionalFeature -Online -FeatureName "Recall" -Remove
}
}
catch
{
Start-Process explorer
}
'@
$firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force
}

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

@ -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"
if ($Value -ne "<RemoveEntry>") {
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] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] {

View File

@ -0,0 +1,83 @@
function Set-WinUtilUITheme {
<#
.SYNOPSIS
Sets the theme of the XAML file
.PARAMETER inputXML
A string representing the XAML object to modify
.PARAMETER customThemeName
The name of the custom theme to set the XAML to. Defaults to 'matrix'
.PARAMETER defaultThemeName
The name of the default theme to use when setting the XAML. Defaults to '_default'
.EXAMPLE
$returnVal = Set-WinUtilUITheme -inputXAML $inputXAML
if ($returnVal[0] -eq "") {
Write-Host "Failed to process inputXML"
} else {
$inputXML = $returnVal[0]
}
# to know which theme this function has used, access the second item in returned value.
Write-Host "Theme used in processing: $($returnVal[1])"
#>
param (
[Parameter(Mandatory, position=0)]
[string]$inputXML,
[Parameter(position=1)]
[string]$customThemeName = 'matrix',
[Parameter(position=2)]
[string]$defaultThemeName = '_default'
)
try {
# Note:
# Reason behind not caching the '$sync.configs.themes` object into a variable,
# because this code can modify the themes object.. meaning it's better to access it
# using the more verbose way, rather than introduce possible bugs into the code, just for the sake of readability.
#
if (-NOT $sync.configs.themes) {
throw [GenericException]::new("[Set-WinUtilTheme] Did not find 'config.themes' inside `$sync variable.")
}
if (-NOT $sync.configs.themes.$defaultThemeName) {
throw [GenericException]::new("[Set-WinUtilTheme] Did not find '$defaultThemeName' theme in the themes config file.")
}
$themeToUse = $customThemeName
if ($sync.configs.themes.$themeToUse) {
# Loop through every default theme option, and modify the custom theme in $sync variable,
# so that it has full options available for other functions to use.
foreach ($option in $sync.configs.themes.$defaultThemeName.PSObject.Properties) {
$optionName = $option.Name
$optionValue = $option.Value
if (-NOT $sync.configs.themes.$themeToUse.$optionName) {
$sync.configs.themes.$themeToUse | Add-Member -MemberType NoteProperty -Name $optionName -Value $optionValue
}
}
} else {
Write-Debug "[Set-WinUtilTheme] Theme '$customThemeName' was not found, using '$defaultThemeName' instead."
$themeToUse = $defaultThemeName
}
foreach ($property in $sync.configs.themes.$themeToUse.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)
}
}
catch {
Write-Host "[Set-WinUtilTheme] Unable to apply theme" -ForegroundColor Red
Write-Host "$($psitem.Exception.Message)" -ForegroundColor Red
$inputXML = "" # Make inputXML equal an empty string, indicating something went wrong to the function caller.
}
return @($inputXML, $themeToUse);
}

View File

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

View File

@ -19,6 +19,7 @@ function Invoke-WPFButton {
}
Switch -Wildcard ($Button) {
"WPFTab?BT" {Invoke-WPFTab $Button}
"WPFInstall" {Invoke-WPFInstall}
"WPFUninstall" {Invoke-WPFUnInstall}
@ -58,6 +59,5 @@ function Invoke-WPFButton {
"WPFCloseButton" {Invoke-WPFCloseButton}
"MicrowinScratchDirBT" {Invoke-ScratchDialog}
"WPFWinUtilPSProfile" {Invoke-WinUtilpsProfile}
"WPFWinUtilSSHServer" {Invoke-WinUtilSSHServer}
}
}

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
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.initialDirectory = $initialDirectory
@ -76,66 +74,6 @@ function Invoke-WPFGetIso {
$sync.BusyMessage.Visibility="Hidden"
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)"
if (-not (Test-Path -Path "$filePath" -PathType Leaf)) {

View File

@ -19,59 +19,45 @@ function Invoke-WPFImpex {
$Config = $null
)
function ConfigDialog {
if (!$Config) {
switch ($type) {
"export" { $FileBrowser = New-Object System.Windows.Forms.SaveFileDialog }
"import" { $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog }
if ($type -eq "export") {
$FileBrowser = New-Object System.Windows.Forms.SaveFileDialog
}
if ($type -eq "import") {
$FileBrowser = New-Object System.Windows.Forms.OpenFileDialog
}
if (-not $Config) {
$FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop')
$FileBrowser.Filter = "JSON Files (*.json)|*.json"
$FileBrowser.ShowDialog() | Out-Null
if($FileBrowser.FileName -eq "") {
return $null
return
} else {
return $FileBrowser.FileName
}
} else {
return $Config
$Config = $FileBrowser.FileName
}
}
switch ($type) {
"export" {
try {
$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
if ($type -eq "export") {
$jsonFile = Get-WinUtilCheckBoxes -unCheck $false
$jsonFile | ConvertTo-Json | Out-File $FileBrowser.FileName -Force
$runscript = "iex ""& { `$(irm christitus.com/win) } -Config '$($FileBrowser.FileName)'"""
$runscript | Set-Clipboard
}
} catch {
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 {
if ($type -eq "import") {
$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 })
}
$flattenedJson = [string]$flattenedJson
Invoke-WPFPresets -preset $flattenedJson -imported $true
}
} catch {
Write-Error "An error occurred while importing: $_"
}
}
}
}

View File

@ -20,7 +20,7 @@ function Invoke-WPFInstall {
return
}
$ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked)
$installHandle = Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
Invoke-WPFRunspace -ArgumentList $PackagesToInstall,$ChocoPreference -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $ChocoPreference, $DebugPreference)
if ($PackagesToInstall.count -eq 1) {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })

View File

@ -51,6 +51,10 @@ public class PowerManagement {
$index = $sync.MicrowinWindowsFlavors.SelectedValue.Split(":")[0].Trim()
Write-Host "Index chosen: '$index' from $($sync.MicrowinWindowsFlavors.SelectedValue)"
$keepPackages = $sync.WPFMicrowinKeepProvisionedPackages.IsChecked
$keepProvisionedPackages = $sync.WPFMicrowinKeepAppxPackages.IsChecked
$keepDefender = $sync.WPFMicrowinKeepDefender.IsChecked
$keepEdge = $sync.WPFMicrowinKeepEdge.IsChecked
$copyToUSB = $sync.WPFMicrowinCopyToUsb.IsChecked
$injectDrivers = $sync.MicrowinInjectDrivers.IsChecked
$importDrivers = $sync.MicrowinImportDrivers.IsChecked
@ -87,14 +91,6 @@ public class PowerManagement {
return
}
# Detect whether the image to process contains Windows 10 and show warning
if ((Test-CompatibleImage $imgVersion $([System.Version]::new(10,0,21996,1))) -eq $false) {
$msg = "Windows 10 has been detected in the image you want to process. While you can continue, Windows 10 is not a recommended target for MicroWin, and you may not get the full experience."
$dlg_msg = $msg
Write-Host $msg
[System.Windows.MessageBox]::Show($dlg_msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Exclamation)
}
$mountDirExists = Test-Path $mountDir
$scratchDirExists = Test-Path $scratchDir
if (-not $mountDirExists -or -not $scratchDirExists) {
@ -242,9 +238,6 @@ public class PowerManagement {
# Write-Host Error code $LASTEXITCODE
Write-Host "Done disabling Teams"
Write-Host "Fix Windows Volume Mixer Issue"
reg add "HKLM\zNTUSER\Software\Microsoft\Internet Explorer\LowRegistry\Audio\PolicyConfig\PropertyStore" /f
Write-Host "Bypassing system requirements (system image)"
reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV1" /t REG_DWORD /d 0 /f
reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV2" /t REG_DWORD /d 0 /f
@ -296,19 +289,6 @@ public class PowerManagement {
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v "AppsUseLightTheme" /t REG_DWORD /d 0 /f
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v "SystemUsesLightTheme" /t REG_DWORD /d 0 /f
if ((Test-CompatibleImage $imgVersion $([System.Version]::new(10,0,21996,1))) -eq $false) {
# We're dealing with Windows 10. Configure sane desktop settings. NOTE: even though stuff to disable News and Interests is there,
# it doesn't seem to work, and I don't want to waste more time dealing with an operating system that will lose support in a year (2025)
# I invite anyone to work on improving stuff for News and Interests, but that won't be me!
Write-Host "Disabling Search Highlights..."
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Feeds\DSB" /v "ShowDynamicContent" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\SearchSettings" /v "IsDynamicSearchBoxEnabled" /t REG_DWORD /d 0 /f
reg add "HKLM\zSOFTWARE\Policies\Microsoft\Dsh" /v "AllowNewsAndInterests" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "TraySearchBoxVisible" /t REG_DWORD /d 1 /f
}
} catch {
Write-Error "An unexpected error occurred: $_"
} finally {

View File

@ -17,7 +17,7 @@ function Invoke-WPFPresets {
param (
[Parameter(position=0)]
[Array]$preset = "",
[string]$preset = "",
[Parameter(position=1)]
[bool]$imported = $false,
@ -51,7 +51,7 @@ function Invoke-WPFPresets {
}
# 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
$sync.$checkboxName.IsChecked = $true
Write-Debug "$checkboxName is checked"

View File

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

View File

@ -27,7 +27,7 @@ function Invoke-WPFUIElements {
$window = $sync["Form"]
$theme = $sync.Form.Resources
$theme = $sync.configs.themes.$ctttheme
$borderstyle = $window.FindResource("BorderStyle")
$HoverTextBlockStyle = $window.FindResource("HoverTextBlockStyle")
$ColorfulToggleSwitchStyle = $window.FindResource("ColorfulToggleSwitchStyle")
@ -186,7 +186,7 @@ function Invoke-WPFUIElements {
$label.ToolTip = $entryInfo.Description
$label.HorizontalAlignment = "Left"
$label.FontSize = $theme.FontSize
$label.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
$label.Foreground = $theme.MainForegroundColor
$dockPanel.Children.Add($label) | Out-Null
$stackPanel.Children.Add($dockPanel) | Out-Null
@ -207,14 +207,14 @@ function Invoke-WPFUIElements {
$toggleButton.HorizontalAlignment = "Left"
$toggleButton.Height = $theme.TabButtonHeight
$toggleButton.Width = $theme.TabButtonWidth
$toggleButton.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "ButtonInstallBackgroundColor")
$toggleButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
$toggleButton.Background = $theme.ButtonInstallBackgroundColor
$toggleButton.Foreground = [Windows.Media.Brushes]::White
$toggleButton.FontWeight = [Windows.FontWeights]::Bold
$textBlock = New-Object Windows.Controls.TextBlock
$textBlock.FontSize = $theme.TabButtonFontSize
$textBlock.Background = [Windows.Media.Brushes]::Transparent
$textBlock.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "ButtonInstallForegroundColor")
$textBlock.Foreground = $theme.ButtonInstallForegroundColor
$underline = New-Object Windows.Documents.Underline
$underline.Inlines.Add($entryInfo.name -replace "(.).*", "`$1")
@ -292,7 +292,7 @@ function Invoke-WPFUIElements {
$checkBox.FontSize = $theme.FontSize
$checkBox.ToolTip = $entryInfo.Description
$checkBox.Margin = $theme.CheckBoxMargin
if ($entryInfo.Checked -eq $true) {
if ($entryInfo.Checked) {
$checkBox.IsChecked = $entryInfo.Checked
}
$horizontalStackPanel.Children.Add($checkBox) | Out-Null

View File

@ -50,14 +50,14 @@ Function Invoke-WPFUltimatePerformance {
} 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]
$installedPlan = powercfg -list | Select-String -Pattern $ultimateGUID
if ($installedPlan) {
# Extract the GUID of the installed Ultimate Performance plan
$ultimatePlanGUID = $installedPlan.Line.Split()[3]
# Set a different power plan as active before deleting the Ultimate Performance plan
$balancedPlanGUID = 381b4222-f694-41f0-9685-ff5bb260df2e
$balancedPlanGUID = (powercfg -list | Select-String -Pattern "Balanced").Line.Split()[3]
powercfg -setactive $balancedPlanGUID
# Delete the Ultimate Performance plan by GUID

View File

@ -30,7 +30,7 @@ function Invoke-WPFUnInstall {
if($confirm -eq "No") {return}
$ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked)
Invoke-WPFRunspace -ArgumentList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
Invoke-WPFRunspace -ArgumentList $PackagesToInstall, $ChocoPreference -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $ChocoPreference, $DebugPreference)
if ($PackagesToInstall.count -eq 1) {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })

View File

@ -24,12 +24,8 @@ function Invoke-WPFtweaksbutton {
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
$tweaksHandle = Invoke-WPFRunspace -ParameterList @(,("tweaks",$tweaks)) -DebugPreference $DebugPreference -ScriptBlock {
param(
$tweaks,
$DebugPreference
)
Invoke-WPFRunspace -ArgumentList $Tweaks -DebugPreference $DebugPreference -ScriptBlock {
param($Tweaks, $DebugPreference)
Write-Debug "Inside Number of tweaks to process: $($Tweaks.Count)"
$sync.ProcessRunning = $true
@ -42,9 +38,8 @@ function Invoke-WPFtweaksbutton {
# Execute other selected tweaks
for ($i = 0; $i -lt $Tweaks.Count; $i++) {
Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($i / $tweaks.Count * 100)
Invoke-WinUtilTweaks $tweaks[$i]
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i/$Tweaks.Count) })
Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($i / $Tweaks.Count * 100)
Invoke-WinUtilTweaks $tweaks[$i]$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i/$Tweaks.Count) })
}
Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100
$sync.ProcessRunning = $false

View File

@ -52,6 +52,29 @@ $sync.runspace.Open()
$inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window'
$defaulttheme = '_default'
if ((Get-WinUtilToggleStatus WPFToggleDarkMode) -eq $True) {
if (Invoke-WinUtilGPU -eq $True) {
$ctttheme = 'Matrix'
} else {
$ctttheme = 'Dark'
}
} else {
$ctttheme = 'Classic'
}
$returnVal = Set-WinUtilUITheme -inputXML $inputXML -customThemeName $ctttheme -defaultThemeName $defaulttheme
if ($returnVal[0] -eq "") {
Write-Host "Failed to statically apply theming to xaml content using Set-WinUtilTheme, please check previous Error/Warning messages." -ForegroundColor Red
Write-Host "Quitting winutil..." -ForegroundColor Red
$sync.runspace.Dispose()
$sync.runspace.Close()
[System.GC]::Collect()
exit 1
}
$inputXML = $returnVal[0]
$ctttheme = $returnVal[1]
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML
@ -81,35 +104,6 @@ if (-NOT ($readerOperationSuccessful)) {
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
#Invoke-WPFUIElements -configVariable $sync.configs.nav -targetGridName "WPFMainGrid"
Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "appspanel" -columncount 5
@ -254,34 +248,24 @@ $commonKeyEvents = {
$sync["Form"].Add_PreViewKeyDown($commonKeyEvents)
$sync["Form"].Add_MouseLeftButtonDown({
# Hide Settings and Theme Popup on click anywhere else
if ($sync.SettingsButton.IsOpen -or
$sync.ThemePopup.IsOpen) {
$sync.SettingsPopup.IsOpen = $false
$sync.ThemePopup.IsOpen = $false
if ($sync["SettingsPopup"].IsOpen) {
$sync["SettingsPopup"].IsOpen = $false
}
$sync["Form"].DragMove()
})
$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) {
$sync["Form"].WindowState = [Windows.WindowState]::Maximized
}
else{
$sync["Form"].WindowState = [Windows.WindowState]::Normal
}
$sync["Form"].WindowState = [Windows.WindowState]::Maximized;
} else {
$sync["Form"].WindowState = [Windows.WindowState]::Normal;
}
})
$sync["Form"].Add_Deactivated({
Write-Debug "WinUtil lost focus"
# Hide Settings and Theme Popup on Winutil Focus Loss
if ($sync.SettingsButton.IsOpen -or
$sync.ThemePopup.IsOpen) {
$sync.SettingsPopup.IsOpen = $false
$sync.ThemePopup.IsOpen = $false
if ($sync["SettingsPopup"].IsOpen) {
$sync["SettingsPopup"].IsOpen = $false
}
})
@ -399,33 +383,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("24H2") | Out-Null
$sync["ISORelease"].SelectedItem = "24H2"
$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
$filter = Get-WinUtilVariables -Type CheckBox
$CheckBoxes = ($sync.GetEnumerator()).where{ $psitem.Key -in $filter }
@ -448,8 +405,8 @@ $sync["SearchBar"].Add_TextChanged({
$textToSearch = $sync.SearchBar.Text.ToLower()
foreach ($CheckBox in $CheckBoxes) {
# Skip if the checkbox is null, it doesn't have content or it is the prefer Choco checkbox
if ($CheckBox -eq $null -or $CheckBox.Value -eq $null -or $CheckBox.Value.Content -eq $null -or $CheckBox.Name -eq "WPFpreferChocolatey") {
# 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) {
continue
}
@ -521,47 +478,15 @@ Set-WinUtilTaskbaritem -overlay "logo"
$sync["Form"].Add_Activated({
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
$sync["SettingsButton"].Add_Click({
Write-Debug "SettingsButton clicked"
if ($sync.SettingsPopup.IsOpen) {
$sync.SettingsPopup.IsOpen = $false
if ($sync["SettingsPopup"].IsOpen) {
$sync["SettingsPopup"].IsOpen = $false
} else {
$sync["SettingsPopup"].IsOpen = $true
}
else{
$sync.SettingsPopup.IsOpen = $true
}
$sync.ThemePopup.IsOpen = $false
$_.Handled = $false
})
@ -593,8 +518,12 @@ MicroWin : <a href="https://github.com/KonTy">@KonTy</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>
"@
Show-CustomDialog -Message $authorInfo -LogoSize $LogoSize
$FontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSize
$HeaderFontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSizeHeader
$LogoSize = $sync.configs.themes.$ctttheme.CustomDialogLogoSize
$Width = $sync.configs.themes.$ctttheme.CustomDialogWidth
$Height = $sync.configs.themes.$ctttheme.CustomDialogHeight
Show-CustomDialog -Message $authorInfo -Width $Width -Height $Height -FontSize $FontSize -HeaderFontSize $HeaderFontSize -LogoSize $LogoSize
})
$sync["SponsorMenuItem"].Add_Click({
@ -615,8 +544,12 @@ $sync["SponsorMenuItem"].Add_Click({
$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
$LogoSize = $sync.configs.themes.$ctttheme.CustomDialogLogoSize
$Width = $sync.configs.themes.$ctttheme.CustomDialogWidth
$Height = $sync.configs.themes.$ctttheme.CustomDialogHeight
Show-CustomDialog -Message $authorInfo -Width $Width -Height $Height -FontSize $FontSize -HeaderFontSize $HeaderFontSize -LogoSize $LogoSize -EnableScroll $true
})
$sync["Form"].ShowDialog() | out-null
Stop-Transcript

View File

@ -72,45 +72,80 @@ 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."
}
$InternalExcludedFiles = [System.Collections.Generic.List[string]]::new($ExcludedFiles.Count)
ForEach ($excludedFile in $ExcludedFiles) {
$InternalExcludedFiles.Add($excludedFile) | Out-Null
$count = $ExcludedFiles.Count
# Make sure there's a * at the end of folders in ExcludedFiles list
for ($i = 0; $i -lt $count; $i++) {
$excludedFile = $ExcludedFiles[$i]
$isFolder = ($excludedFile) -match '\\$'
if ($isFolder) { $ExcludedFiles[$i] = $excludedFile + '*' }
}
# Validate the 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) {
# Validate the ExcludedFiles List before continuing on,
# that's if there's a list in the first place, and '-SkipExcludedFilesValidation' was not provided.
if (-not $SkipExcludedFilesValidation) {
for ($i = 0; $i -lt $count; $i++) {
$excludedFile = $ExcludedFiles[$i]
$filePath = "$(($WorkingDir -replace ('\\$', '')) + '\' + ($excludedFile -replace ('\.\\', '')))"
$files = Get-ChildItem -Recurse -Path "$filePath" -File -Force
if ($files.Count -gt 0) {
ForEach ($file in $files) {
$InternalExcludedFiles.Add("$($file.FullName)") | Out-Null
# Handle paths with wildcards in a different implementation
$matches = ($filePath) -match '^.*?\*'
if ($matches) {
if (-NOT (Get-ChildItem -Recurse -Path "$filePath" -File -Force)) {
$failedFilesList += "'$filePath', "
}
} else {
if (-NOT (Test-Path -Path "$filePath")) {
$failedFilesList += "'$filePath', "
}
}
} else { $failedFilesList += "'$filePath', " }
}
$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"
}
}
# Get Files List
[System.Collections.ArrayList]$files = Get-ChildItem -LiteralPath $WorkingDir -Recurse -Exclude $InternalExcludedFiles -File -Force
[System.Collections.ArrayList]$files = Get-ChildItem $WorkingDir -Recurse -Exclude $ExcludedFiles -File -Force
$numOfFiles = $files.Count
# Only keep the 'FullName' Property for every entry in the list
for ($i = 0; $i -lt $files.Count; $i++) {
for ($i = 0; $i -lt $numOfFiles; $i++) {
$file = $files[$i]
$files[$i] = $file.FullName
}
# If a file(s) are found in Exclude List,
# Remove the file from files list.
ForEach ($excludedFile in $InternalExcludedFiles) {
$index = $files.IndexOf("$excludedFile")
for ($j = 0; $j -lt $excludedFiles.Count; $j++) {
# Prepare some variables
$excluded = $excludedFiles[$j]
$pathToFind = ($excluded) -replace ('^\.\\', '')
$pathToFind = $WorkingDir + '\' + $pathToFind
$index = -1 # reset index on every iteration
# Handle paths with wildcards in a different implementation
$matches = ($pathToFind) -match '^.*?\*'
if ($matches) {
$filesToCheck = Get-ChildItem -Recurse -Path "$pathToFind" -File -Force
if ($filesToCheck) {
for ($k = 0; $k -lt $filesToCheck.Count; $k++) {
$fileToCheck = $filesToCheck[$k]
$index = $files.IndexOf("$fileToCheck")
if ($index -ge 0) { $files.RemoveAt($index) }
}
}
} else {
$index = $files.IndexOf("$pathToFind")
if ($index -ge 0) { $files.RemoveAt($index) }
}
}
# Make sure 'numOfFiles' is synced with the actual Number of Files found in '$files'
# This's done because previous may or may not edit the files list, so we should update it
$numOfFiles = $files.Count
if ($numOfFiles -eq 0) {

File diff suppressed because it is too large Load Diff