Test 2024 01 03 (#1384)

* Increase performance during loading. (#1348)

* Increase performance during loading.
Add a clear button to the search box.
Add link and description attributes to the applications JSON.
Use the link for linking to the app website.
Use the description as a tooltip for each app.
Add a clickable link to the website for each application (this took a long time; don't kick me if I got some wrong).
Pressing Escape now clears the filter box.
Pressing Alt-P prints your PID.

* Fix for services that are being stopped

* Compile winutil

* Adding new Get-LocalizedYesNo based on choice.exe which is faster and more reliable, thank you @dtm-r for implementing it and testing it on English, German, Dutch, French, Italian, Spansich and Russian. Incredible work by @dtm-r, all cridit and props go to him.
See this thread for details https://github.com/ChrisTitusTech/winutil/issues/1324

* Added error-checking logic for mounting ISOs and also created a wiki page that explains some of the errors.

---------

Co-authored-by: KonTy <KonTy@github.com>

* Compile Winutil

* Custom save targets for MicroWin ISOs (#1346)

* Workaround for Explorer freezes

Some people have reported that setting the Event Log service to Automatic and starting it can (temporarily) fix Explorer freezes.

This change detects whether the next service in the list is "EventLog" and skips it

* Allow user to save MicroWin ISOs anywhere

Adds a SaveFileDialog component to let the user specify the location of the MicroWin ISO and uses it during creation with oscdimg.

(It uses a Process object from System.Diagnostics because I couldn't get it to work with Start-Process)

* Removed temporary workaround

Removed my version of the workaround in favor of the version from @KonTy (merge PR #1348 first)

---------

Co-authored-by: Chris Titus <contact@christitus.com>

* Highly anticipated fix for small screens (#1358)

* Increase performance during loading.
Add a clear button to the search box.
Add link and description attributes to the applications JSON.
Use the link for linking to the app website.
Use the description as a tooltip for each app.
Add a clickable link to the website for each application (this took a long time; don't kick me if I got some wrong).
Pressing Escape now clears the filter box.
Pressing Alt-P prints your PID.

* Fix for services that are being stopped

* Compile winutil

* Adding new Get-LocalizedYesNo based on choice.exe which is faster and more reliable, thank you @dtm-r for implementing it and testing it on English, German, Dutch, French, Italian, Spansich and Russian. Incredible work by @dtm-r, all cridit and props go to him.
See this thread for details https://github.com/ChrisTitusTech/winutil/issues/1324

* Added error-checking logic for mounting ISOs and also created a wiki page that explains some of the errors.

* Highly anticipated fix for small screen computers

---------

Co-authored-by: KonTy <KonTy@github.com>

* Compile Winutil

* Winutil take a long time to create iso file and goes to sleep, this fixes that issue #1343 (#1371)

Co-authored-by: KonTy <KonTy@github.com>

* Compile Winutil

* Create .gitattributes

* Update .gitattributes

* add winget ventoy package (#1374)

* add winget ventoy package

* convert applications.json to utf-8

* update applications.json again

* Compile Winutil

* Update applications.json

fix encoding

* Compile Winutil

* Fix Encoding and Bad Symbols

* Compile Winutil

* feat: Add more software choices (#1379)

* Compile Winutil

* Update configs.Tests.ps1

* Update winutil.Tests.ps1

* Update applications.json

* Compile Winutil

* Update applications.json

* Compile Winutil

* Update applications.json

* Compile Winutil

* fix functions for unit tests

* Compile Winutil

* Update Invoke-MicroWin-Helper.ps1

* Compile Winutil

* fix name WPF Close Button

* Update inputXML.xaml

* Compile Winutil

* my bad that wasnt it

* modify unit test for stop on error

* Compile Winutil

* Update unittests.yaml

* Create test

* Update unittests.yaml

* Update unittests.yaml

* Update unittests.yaml

* Update unittests.yaml

* Update unittests.yaml

* Update unittests.yaml

* Update unittests.yaml

* Update unittests.yaml

* Compile Winutil

* Make restore points optional, enabled by default (#1380)

* Make restore points optional, enabled by default

* Tweaks order fix if restorepoint is checked

* Compile Winutil

* update unit tests

* Compile Winutil

* Update unittests.yaml

* Update unittests.yaml

* Update winutil.Tests.ps1

* tests

* Compile Winutil

* Update unittests.yaml

* Update unittests.yaml

* Update unittests.yaml

* fix unit test

* Update winutil.Tests.ps1

* rewrite all pester test for winutil

* Compile Winutil

* fix handle is invalid error

* final unit test

---------

Co-authored-by: KonTy <9524513+KonTy@users.noreply.github.com>
Co-authored-by: KonTy <KonTy@github.com>
Co-authored-by: ChrisTitusTech <ChrisTitusTech@users.noreply.github.com>
Co-authored-by: CodingWonders <101426328+CodingWonders@users.noreply.github.com>
Co-authored-by: Munkk <152475628+munkk01@users.noreply.github.com>
Co-authored-by: Kiril Vasilev <Kiril.v92@gmail.com>
This commit is contained in:
Chris Titus 2024-01-12 00:34:41 -06:00 committed by GitHub
parent a2b12ae4b0
commit efe37b2f3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 3603 additions and 2819 deletions

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
config/* diff
config/applications.json diff
*.json diff

View File

@ -19,22 +19,22 @@ jobs:
failOnInfos: false
test:
runs-on: windows-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}
- name: pester_tests
id: pester_tests
uses: zyborg/pester-tests-report@v1
with:
include_paths: pester
github_token: ${{ secrets.GITHUB_TOKEN }}
tests_fail_step: true
skip_check_run: true
- name: dump test results
shell: pwsh
run: |
Write-Host 'Total Tests Executed...: ${{ steps.pester_tests.outputs.total_count }}'
Write-Host 'Total Tests PASSED.....: ${{ steps.pester_tests.outputs.passed_count }}'
Write-Host 'Total Tests FAILED.....: ${{ steps.pester_tests.outputs.failed_count }}'
- name: Checkout code
uses: actions/checkout@v2
- name: Install Pester
run: |
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
Install-Module -Name Pester -Force -AllowClobber
shell: pwsh
- name: Run Pester tests
run: |
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
Invoke-Pester -Path 'pester/*.Tests.ps1' -EnableExit
shell: pwsh
env:
TEMP: ${{ runner.temp }}

Binary file not shown.

View File

@ -1,38 +1,12 @@
{
"Classic": {
"ComboBoxBackgroundColor": "#777777",
"LabelboxForegroundColor": "#000000",
"MainForegroundColor": "#000000",
"MainBackgroundColor": "#777777",
"LabelBackgroundColor": "#777777",
"ComboBoxForegroundColor": "#000000",
"ButtonInstallBackgroundColor": "#222222",
"ButtonTweaksBackgroundColor": "#333333",
"ButtonConfigBackgroundColor": "#444444",
"ButtonUpdatesBackgroundColor": "#555555",
"ButtonInstallForegroundColor": "#FFFFFF",
"ButtonTweaksForegroundColor": "#FFFFFF",
"ButtonConfigForegroundColor": "#FFFFFF",
"ButtonUpdatesForegroundColor": "#FFFFFF",
"ButtonBackgroundColor": "#CACACA",
"ButtonBackgroundPressedColor": "#FFFFFF",
"ButtonBackgroundMouseoverColor": "#A55A64",
"ButtonBackgroundSelectedColor": "#BADFFF",
"ButtonForegroundColor": "#000000",
"ButtonBorderThickness": "0",
"ButtonMargin": "0,3,0,3",
"ButtonCornerRadius": "0",
"ToggleButtonHeight": "40",
"BorderColor": "#000000",
"BorderOpacity": "0.2",
"ShadowPulse": "Forever"
},
"Classic": {
"ComboBoxBackgroundColor": "#FFFFFF",
"LabelboxForegroundColor": "#000000",
"MainForegroundColor": "#000000",
"MainBackgroundColor": "#FFFFFF",
"LabelBackgroundColor": "#FAFAFA",
"LinkForegroundColor": "#000000",
"LinkHoverForegroundColor": "#000000",
"GroupBorderBackgroundColor": "#000000",
"ComboBoxForegroundColor": "#000000",
"ButtonInstallBackgroundColor": "#FFFFFF",
@ -63,6 +37,8 @@
"MainForegroundColor": "#9CCC65",
"MainBackgroundColor": "#000000",
"LabelBackgroundColor": "#000000",
"LinkForegroundColor": "#add8e6",
"LinkHoverForegroundColor": "#FFFFFF",
"ComboBoxForegroundColor": "#FFEE58",
"ButtonInstallBackgroundColor": "#222222",
"ButtonTweaksBackgroundColor": "#333333",

View File

@ -2141,6 +2141,43 @@
"
]
},
"WPFEssTweaksRestorePoint": {
"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
Enable-ComputerRestore -Drive \"$env:SystemDrive\"
} catch {
Write-Host \"An error occurred while enabling System Restore: $_\"
}
# Check if the SystemRestorePointCreationFrequency value exists
$exists = Get-ItemProperty -path \"HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SystemRestore\" -Name \"SystemRestorePointCreationFrequency\" -ErrorAction SilentlyContinue
if($null -eq $exists){
write-host 'Changing system to allow multiple restore points per day'
Set-ItemProperty -Path \"HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SystemRestore\" -Name \"SystemRestorePointCreationFrequency\" -Value \"0\" -Type DWord -Force -ErrorAction Stop | Out-Null
}
# Get all the restore points for the current day
$existingRestorePoints = Get-ComputerRestorePoint | Where-Object { $_.CreationTime.Date -eq (Get-Date).Date }
# Check if there is already a restore point created today
if ($existingRestorePoints.Count -eq 0) {
$description = \"System Restore Point created by WinUtil\"
Checkpoint-Computer -Description $description -RestorePointType \"MODIFY_SETTINGS\"
Write-Host -ForegroundColor Green \"System Restore Point Created Successfully\"
}
"
]
},
"WPFEssTweaksOO": {
"InvokeScript": [
"curl.exe -s \"https://raw.githubusercontent.com/ChrisTitusTech/winutil/main/ooshutup10_winutil_settings.cfg\" -o $ENV:temp\\ooshutup10.cfg

View File

@ -1,4 +1,39 @@
function Get-LocalizedYesNo {
<#
.SYNOPSIS
This function runs choice.exe and captures its output to extract yes no in a localized Windows
.DESCRIPTION
The function retrieves the output of the command 'cmd /c "choice <nul 2>nul"' and converts the default output for Yes and No
in the localized format, such as "Yes=<first character>, No=<second character>".
.EXAMPLE
$yesNoArray = Get-LocalizedYesNo
Write-Host "Yes=$($yesNoArray[0]), No=$($yesNoArray[1])"
#>
# Run choice and capture its options as output
# The output shows the options for Yes and No as "[Y,N]?" in the (partitially) localized format.
# eg. English: [Y,N]?
# Dutch: [Y,N]?
# German: [J,N]?
# French: [O,N]?
# Spanish: [S,N]?
# Italian: [S,N]?
# Russian: [Y,N]?
$line = cmd /c "choice <nul 2>nul"
$charactersArray = @()
$regexPattern = '([a-zA-Z])'
$charactersArray = [regex]::Matches($line, $regexPattern) | ForEach-Object { $_.Groups[1].Value }
Write-Debug "According to takeown.exe local Yes is $charactersArray[0]"
# Return the array of characters
return $charactersArray
}
function Get-LocalizedYesNoTakeown {
<#
.SYNOPSIS
This function runs takeown.exe and captures its output to extract yes no in a localized Windows

View File

@ -1,30 +1,30 @@
function Get-WinUtilVariables {
<#
.SYNOPSIS
Gets every form object of the provided type
.OUTPUTS
List containing every object that matches the provided type
#>
param (
[Parameter()]
[ValidateSet("CheckBox", "Button", "ToggleButton")]
[string]$Type
[string[]]$Type
)
$keys = $sync.keys | Where-Object {$psitem -like "WPF*"}
$keys = $sync.keys | Where-Object { $_ -like "WPF*" }
if($type){
if ($Type) {
$output = $keys | ForEach-Object {
Try{
if ($sync["$psitem"].GetType() -like "*$type*"){
Try {
$objType = $sync["$psitem"].GetType().Name
if ($Type -contains $objType) {
Write-Output $psitem
}
}
Catch{<#I am here so errors don't get outputted for a couple variables that don't have the .GetType() attribute#>}
Catch {
<#I am here so errors don't get outputted for a couple variables that don't have the .GetType() attribute#>
}
}
return $output
}

View File

@ -1,3 +1,20 @@
function Invoke-MicroWin-Helper {
<#
.SYNOPSIS
checking unit tests
.PARAMETER Name
no parameters
.EXAMPLE
placeholder
#>
}
function Remove-Features([switch] $dumpFeatures = $false, [switch] $keepDefender = $false) {
<#
@ -430,7 +447,7 @@ function New-FirstRun {
function Stop-UnnecessaryServices
{
$servicesAuto = @"
$servicesToExclude = @(
"AudioSrv",
"AudioEndpointBuilder",
"BFE",
@ -493,12 +510,12 @@ function New-FirstRun {
"vm3dservice",
"webthreatdefusersvc_dc2a4",
"wscsvc"
"@
)
$allServices = Get-Service | Where-Object { $_.StartType -eq "Automatic" -and $servicesAuto -NotContains $_.Name}
foreach($service in $allServices)
$runningServices = Get-Service | Where-Object { $servicesToExclude -notcontains $_.Name }
foreach($service in $runningServices)
{
Stop-Service -Name $service.Name -PassThru
Stop-Service -Name $service.Name -PassThru
Set-Service $service.Name -StartupType Manual
"Stopping service $($service.Name)" | Out-File -FilePath c:\windows\LogFirstRun.txt -Append -NoClobber
}

View File

@ -1,40 +0,0 @@
function Set-WinUtilRestorePoint {
<#
.SYNOPSIS
Creates a Restore Point
#>
# 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
Enable-ComputerRestore -Drive "$env:SystemDrive"
} catch {
Write-Host "An error occurred while enabling System Restore: $_"
}
# Check if the SystemRestorePointCreationFrequency value exists
$exists = Get-ItemProperty -path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore" -name "SystemRestorePointCreationFrequency" -ErrorAction SilentlyContinue
if($null -eq $exists){
write-host 'Changing system to allow multiple restore points per day'
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore" -Name "SystemRestorePointCreationFrequency" -Value "0" -Type DWord -Force -ErrorAction Stop | Out-Null
}
# Get all the restore points for the current day
$existingRestorePoints = Get-ComputerRestorePoint | Where-Object { $_.CreationTime.Date -eq (Get-Date).Date }
# Check if there is already a restore point created today
if ($existingRestorePoints.Count -eq 0) {
$description = "System Restore Point created by WinUtil"
Checkpoint-Computer -Description $description -RestorePointType "MODIFY_SETTINGS"
Write-Host -ForegroundColor Green "System Restore Point Created Successfully"
}
}

View File

@ -55,6 +55,6 @@ function Invoke-WPFButton {
"WPFGetInstalledTweaks" {Invoke-WPFGetInstalled -CheckBox "tweaks"}
"WPFGetIso" {Invoke-WPFGetIso}
"WPFMicrowin" {Invoke-WPFMicrowin}
"WPFCloseButton" {Invoke-CloseButton}
"WPFCloseButton" {Invoke-WPFCloseButton}
}
}

View File

@ -1,4 +1,4 @@
function Invoke-CloseButton {
function Invoke-WPFCloseButton {
<#

View File

@ -80,11 +80,19 @@ function Invoke-WPFGetIso {
return
}
Write-Host "Mounting Iso. Please wait."
$mountedISO = Mount-DiskImage -PassThru "$filePath"
Write-Host "Done mounting Iso $mountedISO"
$driveLetter = (Get-Volume -DiskImage $mountedISO).DriveLetter
Write-Host "Iso mounted to '$driveLetter'"
try {
Write-Host "Mounting Iso. Please wait."
$mountedISO = Mount-DiskImage -PassThru "$filePath"
Write-Host "Done mounting Iso $mountedISO"
$driveLetter = (Get-Volume -DiskImage $mountedISO).DriveLetter
Write-Host "Iso mounted to '$driveLetter'"
} catch {
# @ChrisTitusTech please copy this wiki and change the link below to your copy of the wiki
Write-Error "Failed to mount the image. Error: $($_.Exception.Message)"
Write-Error "This is NOT winutil's problem, your ISO might be corrupt, or there is a problem on the system"
Write-Error "Please refer to this wiki for more details https://github.com/KonTy/winutil/wiki/Error-in-Winutil-MicroWin-during-ISO-mounting"
return
}
# storing off values in hidden fields for further steps
# there is probably a better way of doing this, I don't have time to figure this out
$sync.MicrowinIsoDrive.Text = $driveLetter

View File

@ -10,7 +10,40 @@ function Invoke-WPFMicrowin {
return
}
# Define the constants for Windows API
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class PowerManagement {
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
[FlagsAttribute]
public enum EXECUTION_STATE : uint {
ES_SYSTEM_REQUIRED = 0x00000001,
ES_DISPLAY_REQUIRED = 0x00000002,
ES_CONTINUOUS = 0x80000000,
}
}
"@
# Prevent the machine from sleeping
[PowerManagement]::SetThreadExecutionState([PowerManagement]::EXECUTION_STATE::ES_CONTINUOUS -bor [PowerManagement]::EXECUTION_STATE::ES_SYSTEM_REQUIRED -bor [PowerManagement]::EXECUTION_STATE::ES_DISPLAY_REQUIRED)
# Ask the user where to save the file
$SaveDialog = New-Object System.Windows.Forms.SaveFileDialog
$SaveDialog.InitialDirectory = [Environment]::GetFolderPath('Desktop')
$SaveDialog.Filter = "ISO images (*.iso)|*.iso"
$SaveDialog.ShowDialog() | Out-Null
if ($SaveDialog.FileName -eq "") {
Write-Host "No file name for the target image was specified"
return
}
Write-Host "Target ISO location: $($SaveDialog.FileName)"
$index = $sync.MicrowinWindowsFlavors.SelectedValue.Split(":")[0].Trim()
Write-Host "Index chosen: '$index' from $($sync.MicrowinWindowsFlavors.SelectedValue)"
@ -107,14 +140,6 @@ function Invoke-WPFMicrowin {
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*ParentalControls*" -Directory
Write-Host "Removal complete!"
# *************************** Automation black ***************************
# this doesn't work for some reason, this script is not being run at the end of the install
# if someone knows how to fix this, feel free to modify
New-Item -ItemType Directory -Force -Path $scratchDir\Windows\Setup\Scripts\
"wmic cpu get Name > C:\windows\cpu.txt" | Out-File -FilePath "$($scratchDir)\Windows\Setup\Scripts\SetupComplete.cmd" -NoClobber -Append
"wmic bios get serialnumber > C:\windows\SerialNumber.txt" | Out-File -FilePath "$($scratchDir)\Windows\Setup\Scripts\SetupComplete.cmd" -NoClobber -Append
"devmgmt.msc /s" | Out-File -FilePath "$($scratchDir)\Windows\Setup\Scripts\SetupComplete.cmd" -NoClobber -Append
Write-Host "Create unattend.xml"
New-Unattend
Write-Host "Done Create unattend.xml"
@ -255,7 +280,7 @@ function Invoke-WPFMicrowin {
if (-not (Test-Path -Path "$mountDir\sources\install.wim"))
{
Write-Error "Somethig went wrong and '$mountDir\sources\install.wim' doesn't exist. Please report this bug to the devs"
Write-Error "Something went wrong and '$mountDir\sources\install.wim' doesn't exist. Please report this bug to the devs"
return
}
Write-Host "Windows image completed. Continuing with boot.wim."
@ -323,13 +348,23 @@ function Invoke-WPFMicrowin {
Write-Host "[INFO] Using oscdimg.exe from: $oscdimgPath"
#& oscdimg.exe -m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir $env:temp\microwin.iso
Start-Process -FilePath $oscdimgPath -ArgumentList "-m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir $env:temp\microwin.iso" -NoNewWindow -Wait
#Start-Process -FilePath $oscdimgPath -ArgumentList "-m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir $env:temp\microwin.iso" -NoNewWindow -Wait
#Start-Process -FilePath $oscdimgPath -ArgumentList '-m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir `"$($SaveDialog.FileName)`"' -NoNewWindow -Wait
$oscdimgProc = New-Object System.Diagnostics.Process
$oscdimgProc.StartInfo.FileName = $oscdimgPath
$oscdimgProc.StartInfo.Arguments = "-m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir `"$($SaveDialog.FileName)`""
$oscdimgProc.StartInfo.CreateNoWindow = $True
$oscdimgProc.StartInfo.WindowStyle = "Hidden"
$oscdimgProc.StartInfo.UseShellExecute = $False
$oscdimgProc.Start()
$oscdimgProc.WaitForExit()
if ($copyToUSB)
{
Write-Host "Copying microwin.iso to the USB drive"
Copy-ToUSB("$env:temp\microwin.iso")
Write-Host "Done Copying microwin.iso to USB drive!"
Write-Host "Copying target ISO to the USB drive"
#Copy-ToUSB("$env:temp\microwin.iso")
Copy-ToUSB("$($SaveDialog.FileName)")
if ($?) { Write-Host "Done Copying target ISO to USB drive!" } else { Write-Host "ISO copy failed." }
}
Write-Host " _____ "
@ -344,18 +379,20 @@ function Invoke-WPFMicrowin {
Write-Host "`n`nPerforming Cleanup..."
Remove-Item -Recurse -Force "$($scratchDir)"
Remove-Item -Recurse -Force "$($mountDir)"
$msg = "Done. ISO image is located here: $env:temp\microwin.iso"
#$msg = "Done. ISO image is located here: $env:temp\microwin.iso"
$msg = "Done. ISO image is located here: $($SaveDialog.FileName)"
Write-Host $msg
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
} else {
Write-Host "ISO creation failed. The "$($mountDir)" directory has not been removed."
}
$sync.MicrowinOptionsPanel.Visibility = 'Collapsed'
$sync.MicrowinFinalIsoLocation.Text = "$env:temp\microwin.iso"
#$sync.MicrowinFinalIsoLocation.Text = "$env:temp\microwin.iso"
$sync.MicrowinFinalIsoLocation.Text = "$($SaveDialog.FileName)"
# Allow the machine to sleep again (optional)
[PowerManagement]::SetThreadExecutionState(0)
$sync.ProcessRunning = $false
}
}

View File

@ -27,10 +27,16 @@ function Invoke-WPFtweaksbutton {
$sync.ProcessRunning = $true
Set-WinUtilRestorePoint
# Executes first if selected
if ("WPFEssTweaksRestorePoint" -in $Tweaks) {
Invoke-WinUtilTweaks "WPFEssTweaksRestorePoint"
}
Foreach ($tweak in $tweaks){
Invoke-WinUtilTweaks $tweak
# Execute other selected tweaks
foreach ($tweak in $tweaks) {
if ($tweak -ne "WPFEssTweaksRestorePoint") {
Invoke-WinUtilTweaks $tweak
}
}
$sync.ProcessRunning = $false

0
logs/test Normal file
View File

View File

@ -14,7 +14,12 @@ Describe "Config Files" -ForEach @(
name = "applications"
config = $('{
"winget": "value",
"choco": "value"
"choco": "value",
"category": "value",
"panel": "value",
"content": "value",
"description": "value",
"link": "value"
}' | ConvertFrom-Json)
},
@{

View File

@ -2,13 +2,35 @@
# Tests - Functions
#===========================================================================
# Get all .ps1 files in the functions folder
$ps1Files = Get-ChildItem -Path ./functions -Filter *.ps1
# Loop through each file
foreach ($file in $ps1Files) {
# Define the test name
$testName = "Syntax check for $($file.Name)"
# Define the test script
$testScript = {
# Import the script
. $file.FullName
# Check if any errors occurred
$scriptError = $error[0]
$scriptError | Should -Be $null
}
# Add the test to the Pester test suite
Describe $testName $testScript
}
Describe "Functions"{
Get-ChildItem .\functions -Recurse -File | ForEach-Object {
context "$($psitem.BaseName)" {
BeforeEach -Scriptblock {
. $fullname
. $psitem.FullName
}
It "Imports with no errors" -TestCases @{

View File

@ -1,27 +0,0 @@
# Load Variables needed for testing
./Compile.ps1
$script = Get-Content .\winutil.ps1
# Remove the part of the script that shows the form, leaving only the variable and function declarations
$script[0..($script.count - 21)] | Out-File .\pester.ps1
BeforeAll {
# Execute the truncated script, bringing the variabes into the current scope
. .\pester.ps1
}
Describe "GUI" {
Context "XML" {
It "Imports with no errors" {
$inputXML | should -Not -BeNullOrEmpty
}
}
Context "Form" {
It "Imports with no errors" {
$sync.Form | should -Not -BeNullOrEmpty
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 876 KiB

View File

@ -66,6 +66,8 @@ foreach ($appName in $sync.configs.applications.PSObject.Properties.Name) {
Choco = $appInfo.choco
Winget = $appInfo.winget
Panel = $appInfo.panel
Link = $appInfo.link
Description = $appInfo.description
}
if (-not $organizedData.ContainsKey($appInfo.panel)) {
@ -87,8 +89,14 @@ foreach ($panel in $organizedData.Keys) {
$sortedApps = $organizedData[$panel][$category].Keys | Sort-Object
foreach ($appName in $sortedApps) {
$appInfo = $organizedData[$panel][$category][$appName]
$blockXml += "<CheckBox Name=""$appName"" Content=""$($appInfo.Content)""/>`n"
if ($null -eq $appInfo.Link)
{
$blockXml += "<CheckBox Name=""$appName"" Content=""$($appInfo.Content)"" ToolTip=""$($appInfo.Description)""/>`n"
}
else
{
$blockXml += "<StackPanel Orientation=""Horizontal""><CheckBox Name=""$appName"" Content=""$($appInfo.Content)"" ToolTip=""$($appInfo.Description)"" Margin=""0,0,2,0""/><TextBlock Name=""$($appName)Link"" Style=""{StaticResource HoverTextBlockStyle}"" Text=""(?)"" ToolTip=""$($appInfo.Link)"" /></StackPanel>`n"
}
}
}
@ -131,32 +139,8 @@ $xaml.SelectNodes("//*[@Name]") | ForEach-Object {$sync["$("$($psitem.Name)")"]
$sync.keys | ForEach-Object {
if($sync.$psitem){
if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "Button"){
$sync["$psitem"].Add_Click({
[System.Object]$Sender = $args[0]
Invoke-WPFButton $Sender.name
})
}
}
}
$sync.keys | ForEach-Object {
if($sync.$psitem){
if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "ToggleButton"){
$sync["$psitem"].Add_Click({
[System.Object]$Sender = $args[0]
Invoke-WPFButton $Sender.name
})
}
}
}
$sync.keys | ForEach-Object {
if($sync.$psitem){
if(
$($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "CheckBox" `
-and $sync["$psitem"].Name -like "WPFToggle*"
){
if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "CheckBox" `
-and $sync["$psitem"].Name -like "WPFToggle*"){
$sync["$psitem"].IsChecked = Get-WinUtilToggleStatus $sync["$psitem"].Name
$sync["$psitem"].Add_Click({
@ -164,6 +148,31 @@ $sync.keys | ForEach-Object {
Invoke-WPFToggle $Sender.name
})
}
if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "ToggleButton"){
$sync["$psitem"].Add_Click({
[System.Object]$Sender = $args[0]
Invoke-WPFButton $Sender.name
})
}
if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "Button"){
$sync["$psitem"].Add_Click({
[System.Object]$Sender = $args[0]
Invoke-WPFButton $Sender.name
})
}
if ($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "TextBlock") {
if ($sync["$psitem"].Name.EndsWith("Link")) {
$sync["$psitem"].Add_MouseUp({
[System.Object]$Sender = $args[0]
Start-Process $Sender.ToolTip -ErrorAction Stop
Write-Host "Let's go: $($Sender.ToolTip)"
})
}
}
}
}
@ -197,21 +206,25 @@ $sync["Form"].Add_Closing({
[System.GC]::Collect()
})
# Attach the event handler to the Click event
$sync.CheckboxFilterClear.Add_Click({
$sync.CheckboxFilter.Text = ""
$sync.CheckboxFilterClear.Visibility = "Collapsed"
})
# add some shortcuts for people that don't like clicking
$commonKeyEvents = {
if ($sync.ProcessRunning -eq $true) {
return
}
# Escape removes focus from the searchbox that way all shortcuts will start workinf again
if ($_.Key -eq "Escape") {
#if ($sync.CheckboxFilter.IsFocused)
{
$sync.CheckboxFilter.SelectAll()
$sync.CheckboxFilter.Text = ""
$sync.CheckboxFilter.Focus()
return
}
if ($_.Key -eq "Escape")
{
$sync.CheckboxFilter.SelectAll()
$sync.CheckboxFilter.Text = ""
$sync.CheckboxFilterClear.Visibility = "Collapsed"
return
}
# don't ask, I know what I'm doing, just go...
@ -219,31 +232,7 @@ $commonKeyEvents = {
{
$this.Close()
}
# $ret = [System.Windows.Forms.MessageBox]::Show("Are you sure you want to Exit?", "Winutil", [System.Windows.Forms.MessageBoxButtons]::YesNo,
# [System.Windows.Forms.MessageBoxIcon]::Question, [System.Windows.Forms.MessageBoxDefaultButton]::Button2)
# switch ($ret) {
# "Yes" {
# $this.Close()
# }
# "No" {
# return
# }
# }
if ($_.KeyboardDevice.Modifiers -eq "Alt") {
# this is an example how to handle shortcuts per tab
# Alt-I on the MicroWin tab (4) would press GetIso Button
# NOTE: All per tab shortcuts have to be handled *before* regular tab keys
# if ($_.SystemKey -eq "I") {
# $TabNav = Get-WinUtilVariables | Where-Object {$psitem -like "WPFTabNav"}
# if ($sync.$TabNav.Items[4].IsSelected -eq $true) {
# Invoke-WPFButton "WPFGetIso"
# break
# }
# }
if ($_.SystemKey -eq "I") {
Invoke-WPFButton "WPFTab1BT"
}
@ -259,6 +248,9 @@ $commonKeyEvents = {
if ($_.SystemKey -eq "M") {
Invoke-WPFButton "WPFTab5BT"
}
if ($_.SystemKey -eq "P") {
Write-Host "Your Windows Product Key: $((Get-WmiObject -query 'select * from SoftwareLicensingService').OA3xOriginalProductKey)"
}
}
# shortcut for the filter box
if ($_.Key -eq "F" -and $_.KeyboardDevice.Modifiers -eq "Ctrl") {
@ -269,6 +261,7 @@ $commonKeyEvents = {
$sync.CheckboxFilter.Focus()
}
}
$sync["Form"].Add_PreViewKeyDown($commonKeyEvents)
# adding some left mouse window move on drag capability
@ -287,28 +280,18 @@ $sync["Form"].Add_MouseDoubleClick({
}
})
$sync["Form"].Add_ContentRendered({
# setting window icon to make it look more professional
$sync["Form"].Add_Loaded({
$downloadUrl = "https://christitus.com/images/logo-full.png"
$destinationPath = Join-Path $env:TEMP "cttlogo.png"
# Check if the file already exists
if (-not (Test-Path $destinationPath)) {
# File does not exist, download it
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($downloadUrl, $destinationPath)
Write-Host "File downloaded to: $destinationPath"
} else {
Write-Output "File already exists at: $destinationPath"
foreach ($proc in (Get-Process | Where-Object { $_.MainWindowTitle -and $_.MainWindowTitle -like "*tit*" })) {
if ($proc.Id -ne [System.IntPtr]::Zero) {
Write-Debug "MainWindowHandle: $($proc.Id) $($proc.MainWindowTitle) $($proc.MainWindowHandle)"
$windowHandle = $proc.MainWindowHandle
}
}
$sync["Form"].Icon = $destinationPath
Try {
[Void][Window]
} Catch {
try {
[void][Window]
} catch {
Add-Type @"
using System;
using System.Runtime.InteropServices;
@ -320,8 +303,7 @@ $sync["Form"].Add_Loaded({
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowWindow(IntPtr handle, int state);
public static extern int GetSystemMetrics(int nIndex);
}
public struct RECT {
public int Left; // x position of upper-left corner
@ -331,47 +313,84 @@ $sync["Form"].Add_Loaded({
}
"@
}
$processId = [System.Diagnostics.Process]::GetCurrentProcess().Id
$windowHandle = (Get-Process -Id $processId).MainWindowHandle
$rect = New-Object RECT
[Void][Window]::GetWindowRect($windowHandle,[ref]$rect)
# only snap upper edge don't move left to right, in case people have multimon setup
$x = $rect.Left
$y = 0
[void][Window]::GetWindowRect($windowHandle, [ref]$rect)
$width = $rect.Right - $rect.Left
$height = $rect.Bottom - $rect.Top
# Move the window to that position...
[Void][Window]::MoveWindow($windowHandle, $x, $y, $width, $height, $True)
Write-Debug "UpperLeft:$($rect.Left),$($rect.Top) LowerBottom:$($rect.Right),$($rect.Bottom). Width:$($width) Height:$($height)"
# Load the Windows Forms assembly
Add-Type -AssemblyName System.Windows.Forms
$primaryScreen = [System.Windows.Forms.Screen]::PrimaryScreen
# Check if the primary screen is found
if ($primaryScreen) {
# Extract screen width and height for the primary monitor
$screenWidth = $primaryScreen.Bounds.Width
$screenHeight = $primaryScreen.Bounds.Height
# Print the screen size
Write-Debug "Primary Monitor Width: $screenWidth pixels"
Write-Debug "Primary Monitor Height: $screenHeight pixels"
# Compare with the primary monitor size
if ($width -gt $screenWidth -or $height -gt $screenHeight) {
Write-Debug "The specified width and/or height is greater than the primary monitor size."
[void][Window]::MoveWindow($windowHandle, 0, 0, $screenWidth, $screenHeight, $True)
} else {
Write-Debug "The specified width and height are within the primary monitor size limits."
}
} else {
Write-Debug "Unable to retrieve information about the primary monitor."
}
Invoke-WPFTab "WPFTab1BT"
$sync["Form"].Focus()
})
$sync["CheckboxFilter"].Add_TextChanged({
#Write-host $sync.CheckboxFilter.Text
$filter = Get-WinUtilVariables -Type Checkbox
$CheckBoxes = $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter}
$textToSearch = $sync.CheckboxFilter.Text
Foreach ($CheckBox in $CheckBoxes) {
#Write-Host "$($sync.CheckboxFilter.Text)"
if ($sync.CheckboxFilter.Text -ne "") {
$sync.CheckboxFilterClear.Visibility = "Visible"
}
else {
$sync.CheckboxFilterClear.Visibility = "Collapsed"
}
$filter = Get-WinUtilVariables -Type CheckBox
$CheckBoxes = $sync.GetEnumerator() | Where-Object { $psitem.Key -in $filter }
foreach ($CheckBox in $CheckBoxes) {
# 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
}
if ($CheckBox.Value.Content.ToLower().Contains($textToSearch)) {
$CheckBox.Value.Visibility = "Visible"
}
else {
$textToSearch = $sync.CheckboxFilter.Text
$checkBoxName = $CheckBox.Key
$textBlockName = $checkBoxName + "Link"
# Retrieve the corresponding text block based on the generated name
$textBlock = $sync[$textBlockName]
if ($CheckBox.Value.Content.ToLower().Contains($textToSearch)) {
$CheckBox.Value.Visibility = "Visible"
# Set the corresponding text block visibility
if ($textBlock -ne $null) {
$textBlock.Visibility = "Visible"
}
}
else {
$CheckBox.Value.Visibility = "Collapsed"
}
}
# Set the corresponding text block visibility
if ($textBlock -ne $null) {
$textBlock.Visibility = "Collapsed"
}
}
}
})
# show current windowsd Product ID
#Write-Host "Your Windows Product Key: $((Get-WmiObject -query 'select * from SoftwareLicensingService').OA3xOriginalProductKey)"
$sync["Form"].ShowDialog() | out-null
Stop-Transcript

View File

@ -6,6 +6,10 @@
Version : #{replaceme}
#>
if (!(Test-Path -Path $ENV:TEMP)) {
New-Item -ItemType Directory -Force -Path $ENV:TEMP
}
Start-Transcript $ENV:TEMP\Winutil.log -Append
# Load DLLs

File diff suppressed because it is too large Load Diff

View File

@ -8,11 +8,20 @@
Background="{MainBackgroundColor}"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
Title="Chris Titus Tech's Windows Utility" Height="800" Width="1200">
Title="Chris Titus Tech's Windows Utility" Height="800" Width="1280">
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" CornerRadius="10"/>
</WindowChrome.WindowChrome>
<Window.Resources>
<Storyboard x:Key="FireworksAnimation">
<!-- Firework Burst -->
<DoubleAnimation Storyboard.TargetName="FireworkBurst" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.5"/>
<DoubleAnimation Storyboard.TargetName="FireworkBurst" Storyboard.TargetProperty="ScaleX" From="0" To="1" Duration="0:0:0.5"/>
<DoubleAnimation Storyboard.TargetName="FireworkBurst" Storyboard.TargetProperty="ScaleY" From="0" To="1" Duration="0:0:0.5"/>
<ColorAnimation Storyboard.TargetName="FireworkBurst" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" To="Red" Duration="0:0:0.5"/>
</Storyboard>
<!--Scrollbar Thumbs-->
<Style x:Key="ScrollThumbs" TargetType="{x:Type Thumb}">
<Setter Property="Template">
@ -33,6 +42,18 @@
</Setter>
</Style>
<Style TargetType="TextBlock" x:Key="HoverTextBlockStyle">
<Setter Property="Foreground" Value="{LinkForegroundColor}" />
<Setter Property="TextDecorations" Value="Underline" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{LinkHoverForegroundColor}" />
<Setter Property="TextDecorations" Value="Underline" />
<Setter Property="Cursor" Value="Hand" />
</Trigger>
</Style.Triggers>
</Style>
<!--ScrollBars-->
<Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
<Setter Property="Stylus.IsFlicksEnabled" Value="false" />
@ -146,7 +167,6 @@
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Margin" Value="{ButtonMargin}"/>
<Setter Property="Content" Value=""/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
@ -203,7 +223,6 @@
<Setter Property="Foreground" Value="{ButtonForegroundColor}"/>
<Setter Property="Background" Value="{ButtonBackgroundColor}"/>
<Setter Property="Height" Value="{ToggleButtonHeight}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
@ -232,11 +251,33 @@
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ClearButtonStyle" TargetType="Button">
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Content" Value="X"/>
<Setter Property="Height" Value="14"/>
<Setter Property="Width" Value="14"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{MainForegroundColor}"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Cursor" Value="Hand"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="10"/>
</Trigger>
</Style.Triggers>
</Style>
<!-- Checkbox template -->
<Style TargetType="CheckBox">
<Setter Property="Foreground" Value="{MainForegroundColor}"/>
<Setter Property="Background" Value="{MainBackgroundColor}"/>
<Setter Property="Template">
<Setter Property="FontSize" Value="14" />
<Setter Property="TextElement.FontFamily" Value="Arial, sans-serif"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<Grid Background="{TemplateBinding Background}">
@ -269,9 +310,9 @@
<Setter TargetName="CheckMark" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<!--Setter TargetName="Border" Property="Background" Value="{ButtonBackgroundPressedColor}"/-->
<Setter Property="Foreground" Value="{ButtonBackgroundPressedColor}"/>
</Trigger>
<!--Setter TargetName="Border" Property="Background" Value="{ButtonBackgroundPressedColor}"/-->
<Setter Property="Foreground" Value="{ButtonBackgroundPressedColor}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
@ -562,17 +603,18 @@
<Grid>
<TextBox Width="200"
FontSize="14"
VerticalAlignment="Center" HorizontalAlignment="Left"
Height="25" Margin="10,0,0,0" BorderThickness="1" Padding="22,2,2,2"
Name="CheckboxFilter"
Foreground="{MainForegroundColor}" Background="{MainBackgroundColor}"
ToolTip="Press Ctrl-F and type app name to filter application list below. Press Esc to reset the filter"
>
ToolTip="Press Ctrl-F and type app name to filter application list below. Press Esc to reset the filter">
</TextBox>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" FontFamily="Segoe MDL2 Assets"
FontSize="14" Margin="16,0,0,0">&#xE721;</TextBlock>
<Button Name="CheckboxFilterClear" Style="{StaticResource ClearButtonStyle}" Margin="184,0,0,0" Visibility="Collapsed"/>
</Grid>
<TextBlock Text="Version: CTTVersion" VerticalAlignment="Center" HorizontalAlignment="Center"
Margin="10,0,0,0"/>
<TextBlock Text="Version: CTTVersion" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0"/>
<Button Content="&#xD7;" BorderThickness="0"
BorderBrush="Transparent"
Background="{MainBackgroundColor}"
@ -591,14 +633,13 @@
<RowDefinition Height="0.95*"/>
</Grid.RowDefinitions>
<StackPanel Background="{MainBackgroundColor}" Orientation="Horizontal" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="0" Grid.ColumnSpan="3" Margin="5">
<Label Content="Winget:" FontSize="15" VerticalAlignment="Center"/>
<Button Name="WPFinstall" Content=" Install Selection " Margin="1" />
<Button Name="WPFInstallUpgrade" Content=" Upgrade All " Margin="1"/>
<Button Name="WPFuninstall" Content=" Uninstall Selection " Margin="1"/>
<Button Name="WPFGetInstalled" Content=" Get Installed " Margin="1"/>
<Button Name="WPFclearWinget" Content=" Clear Selection " Margin="1"/>
<Button Name="WPFinstall" Content=" Install Selected" Margin="2" />
<Button Name="WPFInstallUpgrade" Content=" Upgrade All" Margin="2"/>
<Button Name="WPFuninstall" Content=" Uninstall Selection" Margin="2"/>
<Button Name="WPFGetInstalled" Content=" Get Installed" Margin="2"/>
<Button Name="WPFclearWinget" Content=" Clear Selection" Margin="2"/>
<Label Content="Configuration File:" FontSize="15" VerticalAlignment="Center"/>
<Label Content="Configuration:" FontSize="15" VerticalAlignment="Center"/>
<Button Name="WPFimportWinget" Content=" Import " Margin="1"/>
<Button Name="WPFexportWinget" Content=" Export " Margin="1"/>
</StackPanel>
@ -680,6 +721,7 @@
<Border Grid.Row="1" Grid.Column="0">
<StackPanel Background="{MainBackgroundColor}" SnapsToDevicePixels="True">
<Label FontSize="16" Content="Essential Tweaks"/>
<CheckBox Name="WPFEssTweaksRestorePoint" Content="Create Restore Point" Margin="5,0" ToolTip="Creates a restore point at runtime in case a revert is needed from WinUtil modifications" IsChecked="True"/>
<CheckBox Name="WPFEssTweaksOO" Content="Run OO Shutup" Margin="5,0" ToolTip="Runs OO Shutup from https://www.oo-software.com/en/shutup10"/>
<CheckBox Name="WPFEssTweaksTele" Content="Disable Telemetry" Margin="5,0" ToolTip="Disables Microsoft Telemetry. Note: This will lock many Edge Browser settings. Microsoft spies heavily on you when using the Edge browser."/>
<CheckBox Name="WPFEssTweaksWifi" Content="Disable Wifi-Sense" Margin="5,0" ToolTip="Wifi Sense is a spying service that phones home all nearby scanned wifi networks and your current geo location."/>
@ -850,7 +892,7 @@
<Grid Width="Auto" Height="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
@ -964,7 +1006,7 @@
- Choose which features you want to keep <LineBreak/>
- Click the "Start Process" button <LineBreak/>
The process of creating the Windows image may take some time, please check the console and wait for it to say "Done" <LineBreak/>
- Once complete, the microwin.iso will be in the %temp% directory <LineBreak/>
- Once complete, the target ISO file will be in the directory you have specified <LineBreak/>
- Copy this image to your Ventoy USB Stick, boot to this image, gg
<LineBreak/>
If you are injecting drivers ensure you put all your inf, sys, and dll files for each driver into a separate directory