Thanks for your interest in contributing. This guide covers everything you need to get started.
- .NET 9 SDK (download)
- Windows 10/11 (WPF targets
net9.0-windows; scripts only work on Windows) - Windows PowerShell 5.1 (built-in — the app does not use PowerShell 7)
git clone https://github.com/26zl/PleaseTweakWindows.git
cd PleaseTweakWindows
dotnet test PleaseTweakWindows.sln| Command | What it does |
|---|---|
dotnet test |
Run all unit tests |
dotnet run --project src/PleaseTweakWindows |
Run the app in dev mode (UAC prompt appears) |
dotnet build -c Release |
Release build |
Build.bat |
Full build + single-file EXE + distribution ZIP |
/
PleaseTweakWindows.sln
src/
PleaseTweakWindows/ WPF app (net9.0-windows)
App.xaml / App.xaml.cs Entry point, DI container, Serilog
Views/ XAML windows + user controls
ViewModels/ CommunityToolkit.Mvvm
Services/ ScriptExecutor, DialogService, etc.
Models/ Tweak, SubTweak, SubTweakType
Converters/ IValueConverter implementations
Themes/AppTheme.xaml Styles / brushes
app.manifest UAC + DPI declarations
PleaseTweakWindows.Tests/ xUnit + FluentAssertions + Moq
scripts/ PowerShell scripts (embedded in EXE)
CommonFunctions.ps1 Shared utilities
index.txt Resource manifest
file-checksums.json SHA256 hashes for downloads
Gaming optimizations/ Gaming-Optimizations.ps1 + revert
Network optimizations/ Network-Optimizations.ps1 + revert
General Tweaks/ General-Tweaks.ps1 + revert + regs/
Privacy Security/ privacy.ps1 + security.ps1 + reverts
Services management/ Services-Management.ps1 + revert + regs/
- Add the action to the PowerShell script's
ValidateSetandswitchblock - Register a
SubTweakinTweakRegistry.cswith matching action IDs - Update
scripts/index.txtif you added new files - If the action is destructive, add it to
DialogService.DestructiveActions - If it's high-risk, also add it to
DialogService.HighRiskActions - Run
dotnet testto verify
- Lowercase alphanumeric with dashes:
nvidia-settings-on,bloatware-remove - 2-64 characters
- Must match exactly between C# and PowerShell
- Accept
-Action <id>parameter withValidateSet - Use a
switch ($Action)block to dispatch - Must be non-interactive (no
Read-Host, nopause) - Check for
PTW_EMBEDDEDenv var (set by the GUI) to skip prompts - Dot-source
CommonFunctions.ps1for shared utilities - Exit 0 on success, non-zero on error
- Most accept
-Mode <Revert|Repair|RevertAndRepair>(defaultRevertAndRepair) revert-privacy.ps1andrevert-security.ps1also accept-Actionfor individual sub-tweak reverts- Require
#Requires -RunAsAdministrator - Dot-source
CommonFunctions.ps1
- HTTPS only — enforced by
Get-FileFromWebinCommonFunctions.ps1 - Domain whitelist:
microsoft.com,github.com,githubusercontent.com, etc. - Add SHA256 checksums to
file-checksums.jsonfor new downloads
Use functions from CommonFunctions.ps1 instead of defining local copies:
Set-RegDword,Set-RegSz,Set-RegValueSafe,Remove-RegValue,Remove-RegKeySet-RegValueSafeTx,Start-PTWTransaction,Undo-PTWTransaction,Stop-PTWTransaction(transactional registry ops)Get-FileFromWeb(secure download with domain whitelist + SHA256 checksum verification)Write-PTWSuccess,Write-PTWWarning,Write-PTWError,Write-PTWLogGet-ActiveAdapter,Get-GpuClassKeysByVendor,Import-RegistryFile,Wait-ForUser
- MVVM with
CommunityToolkit.Mvvm([ObservableProperty],[RelayCommand]) - Services are registered in
App.xaml.cs; inject via constructor - Use
IProcessRunnerfor process creation (notProcess.Startdirectly) to keep tests isolated - UI updates from background threads must go through
UiDispatcher.PostorApplication.Current.Dispatcher.BeginInvoke - Script path validation rejects
..,;,|,&,>,<
dotnet testTests cover: ScriptExecutor (action/path validation, hash integrity, rejection paths), DialogService (destructive/high-risk classification, warnings), TweakRegistry (category/sub-tweak counts, action ID format, Toggle/Button invariants, path shape), UpdateChecker (JSON parsing, semver comparison).
Tests run on Windows only (WPF target). Access private members via the existing InternalsVisibleTo("PleaseTweakWindows.Tests") attribute in the main csproj.
- Fork the repo and create a branch from
main - Make your changes
- Run
dotnet testand make sure all tests pass - Make sure your PowerShell scripts pass
Invoke-ScriptAnalyzer - Update
scripts/index.txtif you added/removed script files - Open a PR with a clear description of what changed and why
Open an issue on GitHub with:
- What you expected to happen
- What actually happened
- Your Windows version and PowerShell version
- Any relevant log output from the
logs/directory