diff --git a/README.md b/README.md index bfde2f4..93bf2a3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,32 @@ -# Mole for Windows +
+

Mole

+

Deep clean and optimize your Windows.

+
-Windows support for [Mole](https://github.com/tw93/Mole) - A system maintenance toolkit. +

+ Stars + Version + License + Commits + Twitter + Telegram +

+ +

+ Mole - 95.50GB freed +

+ +## Features + +- **All-in-one toolkit**: CCleaner, IObit Uninstaller, WinDirStat, and Task Manager combined into a single PowerShell toolkit +- **Deep cleaning**: Scans and removes temp files, caches, and browser leftovers to reclaim gigabytes of space +- **Smart uninstaller**: Thoroughly removes apps along with AppData, preferences, and hidden remnants +- **Disk insights**: Visualizes usage, manages large files, and refreshes system services +- **Live monitoring**: Real-time stats for CPU, memory, disk, and network to diagnose performance issues + +## Platform Support + +Mole is designed for Windows 10/11. This is the native Windows version ported from the [macOS original](https://github.com/tw93/Mole/tree/main). For macOS users, please visit the [main branch](https://github.com/tw93/Mole) for the native macOS version. ## Requirements @@ -8,7 +34,7 @@ Windows support for [Mole](https://github.com/tw93/Mole) - A system maintenance - PowerShell 5.1 or later (pre-installed on Windows 10/11) - Go 1.24+ (for building TUI tools) -## Installation +## Quick Start ### Quick Install (One-Liner) @@ -37,6 +63,192 @@ git checkout windows # Optional: Create Start Menu shortcut .\install.ps1 -AddToPath -CreateShortcut +``` + +Run: + +```powershell +mole # Interactive menu +mole clean # Deep cleanup +mole uninstall # Remove apps + leftovers +mole optimize # Refresh caches & services +mole analyze # Visual disk explorer +mole status # Live system health dashboard +mole purge # Clean project build artifacts + +mole -ShowHelp # Show help +mole -Version # Show installed version + +mole clean -DryRun # Preview the cleanup plan +mole clean -Whitelist # Manage protected caches +mole clean -DryRun -Debug # Detailed preview with risk levels + +mole optimize -DryRun # Preview optimization actions +mole optimize -Debug # Run with detailed operation logs +mole purge -Paths # Configure project scan directories +``` + +## Tips + +- **Safety**: Built with strict protections. Preview changes with `mole clean -DryRun`. +- **Be Careful**: Although safe by design, file deletion is permanent. Please review operations carefully. +- **Debug Mode**: Use `-Debug` for detailed logs (e.g., `mole clean -Debug`). Combine with `-DryRun` for comprehensive preview including risk levels and file details. +- **Navigation**: Supports arrow keys for TUI navigation. +- **Configuration**: Use `mole clean -Whitelist` to manage protected paths, `mole purge -Paths` to configure scan directories. + +## Features in Detail + +### Deep System Cleanup + +```powershell +mole clean +``` + +``` +Scanning cache directories... + + ✓ User temp files 12.3GB + ✓ Browser cache (Chrome, Edge, Firefox) 8.5GB + ✓ Developer tools (Node.js, npm, Python) 15.2GB + ✓ Windows logs and temp files 4.1GB + ✓ App-specific cache (Spotify, Slack, VS Code) 6.8GB + ✓ Recycle Bin 9.2GB + +==================================================================== +Space freed: 56.1GB | Free space now: 180.3GB +==================================================================== +``` + +### Smart App Uninstaller + +```powershell +mole uninstall +``` + +``` +Select Apps to Remove +═══════════════════════════ +▶ ☑ Adobe Photoshop 2024 (4.2GB) | Old + ☐ IntelliJ IDEA (2.8GB) | Recent + ☐ Premiere Pro (3.4GB) | Recent + +Uninstalling: Adobe Photoshop 2024 + + ✓ Removed application + ✓ Cleaned 52 related files across 8 locations + - AppData, Caches, Preferences + - Logs, Registry entries + - Extensions, Plugins + +==================================================================== +Space freed: 4.8GB +==================================================================== +``` + +### System Optimization + +```powershell +mole optimize +``` + +``` +System: 12/32 GB RAM | 280/460 GB Disk (61%) | Uptime 6d + + ✓ Clear Windows Update cache + ✓ Reset DNS cache + ✓ Clean event logs and diagnostic reports + ✓ Refresh Windows Search index + ✓ Clear thumbnail cache + ✓ Optimize startup programs + +==================================================================== +System optimization completed +==================================================================== +``` + +### Disk Space Analyzer + +```powershell +mole analyze +``` + +``` +Analyze Disk C:\Users\YourName\Documents | Total: 156.8GB + + ▶ 1. ███████████████████ 48.2% | 📁 Downloads 75.4GB >6mo + 2. ██████████░░░░░░░░░ 22.1% | 📁 Videos 34.6GB + 3. ████░░░░░░░░░░░░░░░ 14.3% | 📁 Pictures 22.4GB + 4. ███░░░░░░░░░░░░░░░░ 10.8% | 📁 Documents 16.9GB + 5. ██░░░░░░░░░░░░░░░░░ 5.2% | 📄 backup_2023.zip 8.2GB + + ↑↓←→ Navigate | O Open | F Show | Del Delete | L Large files | Q Quit +``` + +### Live System Status + +Real-time dashboard with system health score, hardware info, and performance metrics. + +```powershell +mole status +``` + +``` +Mole Status Health ● 92 Desktop PC · Intel i7 · 32GB · Windows 11 + +⚙ CPU ▦ Memory +Total ████████████░░░░░░░ 45.2% Used ███████████░░░░░░░ 58.4% +Load 0.82 / 1.05 / 1.23 (8 cores) Total 18.7 / 32.0 GB +Core 1 ███████████████░░░░ 78.3% Free ████████░░░░░░░░░░ 41.6% +Core 2 ████████████░░░░░░░ 62.1% Avail 13.3 GB + +▤ Disk ⚡ Power +Used █████████████░░░░░░ 67.2% Status AC Power +Free 156.3 GB Temp 58°C +Read ▮▯▯▯▯ 2.1 MB/s +Write ▮▮▮▯▯ 18.3 MB/s + +⇅ Network ▶ Processes +Down ▮▮▯▯▯ 3.2 MB/s Code ▮▮▮▮▯ 42.1% +Up ▮▯▯▯▯ 0.8 MB/s Chrome ▮▮▮▯▯ 28.3% +``` + +Health score based on CPU, memory, disk, temperature, and I/O load. Color-coded by range. + +### Project Artifact Purge + +Clean old build artifacts (`node_modules`, `target`, `build`, `dist`, etc.) from your projects to free up disk space. + +```powershell +mole purge +``` + +``` +Select Categories to Clean - 18.5GB (8 selected) + +➤ ● my-react-app 3.2GB | node_modules + ● old-project 2.8GB | node_modules + ● rust-app 4.1GB | target + ● next-blog 1.9GB | node_modules + ○ current-work 856MB | node_modules | Recent + ● django-api 2.3GB | venv + ● vue-dashboard 1.7GB | node_modules + ● backend-service 2.5GB | node_modules +``` + +Use with caution: This will permanently delete selected artifacts. Review carefully before confirming. Recent projects — less than 7 days old — are marked and unselected by default. + +Custom scan paths can be configured with `mole purge -Paths`. + +## Installation Options + +### Manual Installation + +```powershell +# Install to custom location +.\install.ps1 -InstallDir C:\Tools\Mole -AddToPath + +# Create Start Menu shortcut +.\install.ps1 -AddToPath -CreateShortcut # Optional: Custom install location .\install.ps1 -InstallDir C:\Tools\Mole -AddToPath @@ -48,63 +260,31 @@ git checkout windows .\install.ps1 -Uninstall ``` -## Usage +## Configuration -```powershell -# Interactive menu -mole +Mole stores its configuration in: -# Show help -mole -ShowHelp - -# Show version -mole -Version - -# Commands -mole clean # Deep system cleanup -mole clean -DryRun # Preview cleanup without deleting -mole uninstall # Interactive app uninstaller -mole optimize # System optimization -mole purge # Clean developer artifacts -mole analyze # Disk space analyzer -mole status # System health monitor -``` - -## Commands - -| Command | Description | -|---------|-------------| -| `clean` | Deep cleanup of temp files, caches, and logs | -| `uninstall` | Interactive application uninstaller | -| `optimize` | System optimization and health checks | -| `purge` | Clean project build artifacts (node_modules, etc.) | -| `analyze` | Interactive disk space analyzer (TUI) | -| `status` | Real-time system health monitor (TUI) | - -## Environment Variables - -| Variable | Description | -|----------|-------------| -| `MOLE_DRY_RUN=1` | Preview changes without making them | -| `MOLE_DEBUG=1` | Enable debug output | -| `MO_ANALYZE_PATH` | Starting path for analyze tool | +- Config: `~\.config\mole\` +- Cache: `~\.cache\mole\` +- Whitelist: `~\.config\mole\whitelist.txt` +- Purge paths: `~\.config\mole\purge_paths.txt` ## Directory Structure ``` -windows/ +mole/ (windows branch) ├── mole.ps1 # Main CLI entry point ├── install.ps1 # Windows installer ├── Makefile # Build automation for Go tools ├── go.mod # Go module definition ├── go.sum # Go dependencies ├── bin/ -│ ├── clean.ps1 # Deep cleanup orchestrator -│ ├── uninstall.ps1 # Interactive app uninstaller -│ ├── optimize.ps1 # System optimization -│ ├── purge.ps1 # Project artifact cleanup -│ ├── analyze.ps1 # Disk analyzer wrapper -│ └── status.ps1 # Status monitor wrapper +301: │ ├── clean.ps1 # Deep cleanup orchestrator +302: │ ├── uninstall.ps1 # Interactive app uninstaller +303: │ ├── optimize.ps1 # System optimization +304: │ ├── purge.ps1 # Project artifact cleanup +305: │ ├── analyze.ps1 # Disk analyzer wrapper +306: │ └── status.ps1 # Status monitor wrapper ├── cmd/ │ ├── analyze/ # Disk analyzer (Go TUI) │ │ └── main.go @@ -130,7 +310,7 @@ windows/ The analyze and status commands require Go to be installed: ```powershell -cd windows +# From the repository root # Build both tools make build @@ -142,16 +322,13 @@ go build -o bin/status.exe ./cmd/status/ # The wrapper scripts will auto-build if Go is available ``` -## Configuration +## Support -Mole stores its configuration in: +- If Mole saved you disk space, consider starring the repo or [sharing it](https://twitter.com/intent/tweet?url=https://github.com/tw93/Mole/tree/windows&text=Mole%20-%20Deep%20clean%20and%20optimize%20your%20Windows%20PC.) with friends. +- Have ideas or fixes? Check our [Contributing Guide](https://github.com/tw93/Mole/blob/windows/CONTRIBUTING.md), then open an issue or PR to help shape Mole's future. +- Love Mole? [Buy Tw93 an ice-cold Coke](https://miaoyan.app/cats.html?name=Mole) to keep the project alive and kicking! 🥤 -- Config: `~\.config\mole\` -- Cache: `~\.cache\mole\` -- Whitelist: `~\.config\mole\whitelist.txt` -- Purge paths: `~\.config\mole\purge_paths.txt` - -## Development Phases +## Community Love ### Phase 1: Core Infrastructure ✅ @@ -180,6 +357,12 @@ Mole stores its configuration in: - [ ] GitHub Actions workflows - [ ] `scripts/build.ps1` - Build automation +Mole wouldn't be possible without these amazing contributors. They've built countless features that make Mole what it is today. Go follow them! ❤️ + +[![Contributors](https://contrib.rocks/image?repo=tw93/Mole)](https://github.com/tw93/Mole/graphs/contributors) + +Join thousands of users worldwide who trust Mole to keep their systems clean and optimized. + ## License -Same license as the main Mole project. +MIT License — feel free to enjoy and participate in open source. diff --git a/bin/clean.ps1 b/bin/clean.ps1 index ce66194..6220a5b 100644 --- a/bin/clean.ps1 +++ b/bin/clean.ps1 @@ -6,6 +6,7 @@ param( [switch]$DryRun, [switch]$System, + [switch]$GameMedia, [switch]$DebugMode, [switch]$Whitelist, [switch]$ShowHelp @@ -51,14 +52,16 @@ function Show-CleanHelp { Write-Host "$esc[33mOptions:$esc[0m" Write-Host " -DryRun Preview changes without deleting (recommended first run)" Write-Host " -System Include system-level cleanup (requires admin)" + Write-Host " -GameMedia Clean old game replays, screenshots, recordings (>90d)" Write-Host " -Whitelist Manage protected paths" Write-Host " -DebugMode Enable debug logging" Write-Host " -ShowHelp Show this help message" Write-Host "" Write-Host "$esc[33mExamples:$esc[0m" - Write-Host " mole clean -DryRun # Preview what would be cleaned" - Write-Host " mole clean # Run standard cleanup" - Write-Host " mole clean -System # Include system cleanup (as admin)" + Write-Host " mole clean -DryRun # Preview what would be cleaned" + Write-Host " mole clean # Run standard cleanup" + Write-Host " mole clean -GameMedia # Include old game media cleanup" + Write-Host " mole clean -System # Include system cleanup (as admin)" Write-Host "" } @@ -161,7 +164,8 @@ function Show-CleanupSummary { function Start-Cleanup { param( [bool]$IsDryRun, - [bool]$IncludeSystem + [bool]$IncludeSystem, + [bool]$IncludeGameMedia ) $esc = [char]27 @@ -230,14 +234,22 @@ function Start-Cleanup { # Browser caches Clear-BrowserCaches + # GPU shader caches (NVIDIA, AMD, Intel, DirectX) + Clear-GPUShaderCaches + # Application caches Clear-AppCaches # Developer tools Invoke-DevToolsCleanup - # Applications cleanup - Invoke-AppCleanup + # Applications cleanup (with optional game media) + if ($IncludeGameMedia) { + Invoke-AppCleanup -IncludeGameMedia -GameMediaDaysOld 90 + } + else { + Invoke-AppCleanup + } # System cleanup (if requested and admin) if ($IncludeSystem -and (Test-IsAdmin)) { @@ -288,7 +300,7 @@ function Main { # Run cleanup try { - Start-Cleanup -IsDryRun $DryRun -IncludeSystem $System + Start-Cleanup -IsDryRun $DryRun -IncludeSystem $System -IncludeGameMedia $GameMedia } finally { # Cleanup temp files diff --git a/bin/optimize.ps1 b/bin/optimize.ps1 index 5973ee9..7c52361 100644 --- a/bin/optimize.ps1 +++ b/bin/optimize.ps1 @@ -1,12 +1,18 @@ # Mole - Optimize Command -# System optimization and health checks for Windows +# System optimization, health checks, and repairs for Windows #Requires -Version 5.1 [CmdletBinding()] param( [switch]$DryRun, [switch]$DebugMode, - [switch]$ShowHelp + [switch]$ShowHelp, + # Repair options + [switch]$Repair, + [switch]$Font, + [switch]$Icon, + [switch]$Search, + [switch]$Store ) Set-StrictMode -Version Latest @@ -27,6 +33,7 @@ $libDir = Join-Path (Split-Path -Parent $scriptDir) "lib" # ============================================================================ $script:OptimizationsApplied = 0 +$script:RepairsApplied = 0 $script:IssuesFound = 0 $script:IssuesFixed = 0 @@ -37,22 +44,36 @@ $script:IssuesFixed = 0 function Show-OptimizeHelp { $esc = [char]27 Write-Host "" - Write-Host "$esc[1;35mMole Optimize$esc[0m - System optimization and health checks" + Write-Host "$esc[1;35mMole Optimize$esc[0m - System optimization, health checks, and repairs" Write-Host "" Write-Host "$esc[33mUsage:$esc[0m mole optimize [options]" Write-Host "" Write-Host "$esc[33mOptions:$esc[0m" - Write-Host " -DryRun Preview optimizations without applying" + Write-Host " -DryRun Preview changes without applying" Write-Host " -DebugMode Enable debug logging" Write-Host " -ShowHelp Show this help message" Write-Host "" - Write-Host "$esc[33mOptimizations:$esc[0m" + Write-Host "$esc[33mRepair Options:$esc[0m" + Write-Host " -Repair Run all repairs (Font, Icon, Search, Store)" + Write-Host " -Font Rebuild font cache (fixes font display issues)" + Write-Host " -Icon Rebuild icon cache (fixes missing/corrupt icons)" + Write-Host " -Search Reset Windows Search index (fixes search issues)" + Write-Host " -Store Reset Windows Store cache (fixes Store issues)" + Write-Host "" + Write-Host "$esc[33mExamples:$esc[0m" + Write-Host " mole optimize # Run standard optimizations" + Write-Host " mole optimize -Repair # Run optimizations + all repairs" + Write-Host " mole optimize -Icon -Font # Run optimizations + specific repairs" + Write-Host " mole optimize -DryRun # Preview what would happen" + Write-Host "" + Write-Host "$esc[33mOptimizations (always run):$esc[0m" Write-Host " - Disk defragmentation/TRIM (SSD optimization)" - Write-Host " - Windows Search index optimization" + Write-Host " - Windows Search index check" Write-Host " - DNS cache flush" Write-Host " - Network optimization" Write-Host " - Startup program analysis" - Write-Host " - System file verification" + Write-Host " - Disk health check" + Write-Host " - Windows Update status" Write-Host "" } @@ -440,6 +461,234 @@ function Test-WindowsUpdate { } } +# ============================================================================ +# Repair Functions +# ============================================================================ + +function Repair-FontCache { + <# + .SYNOPSIS + Rebuild Windows font cache + .DESCRIPTION + Stops the font cache service, clears the cache files, and restarts. + Fixes issues with fonts not displaying correctly or missing fonts. + #> + + $esc = [char]27 + + Write-Host "" + Write-Host "$esc[34m$($script:Icons.Arrow) Font Cache Rebuild$esc[0m" + + if (-not (Test-IsAdmin)) { + Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Requires administrator privileges" + return + } + + # Font cache locations + $fontCachePaths = @( + "$env:LOCALAPPDATA\Microsoft\Windows\Fonts" + "$env:WINDIR\ServiceProfiles\LocalService\AppData\Local\FontCache" + "$env:WINDIR\System32\FNTCACHE.DAT" + ) + + if ($script:DryRun) { + Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would stop Windows Font Cache Service" + Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would delete font cache files" + Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would restart Windows Font Cache Service" + $script:RepairsApplied++ + return + } + + try { + # Stop font cache service + Write-Host " $esc[90mStopping Font Cache Service...$esc[0m" + Stop-Service -Name "FontCache" -Force -ErrorAction SilentlyContinue + Stop-Service -Name "FontCache3.0.0.0" -Force -ErrorAction SilentlyContinue + + # Wait a moment for service to stop + Start-Sleep -Seconds 2 + + # Delete font cache files + foreach ($path in $fontCachePaths) { + if (Test-Path $path) { + if (Test-Path $path -PathType Container) { + Get-ChildItem -Path $path -Recurse -Force -ErrorAction SilentlyContinue | + Remove-Item -Force -Recurse -ErrorAction SilentlyContinue + } + else { + Remove-Item -Path $path -Force -ErrorAction SilentlyContinue + } + } + } + + # Restart font cache service + Write-Host " $esc[90mRestarting Font Cache Service...$esc[0m" + Start-Service -Name "FontCache" -ErrorAction SilentlyContinue + Start-Service -Name "FontCache3.0.0.0" -ErrorAction SilentlyContinue + + Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Font cache rebuilt successfully" + Write-Host " $esc[90mNote: Some apps may need restart to see changes$esc[0m" + $script:RepairsApplied++ + } + catch { + Write-Host " $esc[31m$($script:Icons.Error)$esc[0m Could not rebuild font cache: $_" + Start-Service -Name "FontCache" -ErrorAction SilentlyContinue + } +} + +function Repair-IconCache { + <# + .SYNOPSIS + Rebuild Windows icon cache + .DESCRIPTION + Clears the icon cache database files, forcing Windows to rebuild them. + Fixes issues with missing, corrupted, or outdated icons. + #> + + $esc = [char]27 + + Write-Host "" + Write-Host "$esc[34m$($script:Icons.Arrow) Icon Cache Rebuild$esc[0m" + + $iconCachePath = "$env:LOCALAPPDATA\Microsoft\Windows\Explorer" + + if ($script:DryRun) { + Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would stop Explorer" + Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would delete icon cache files (iconcache_*.db)" + Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would restart Explorer" + $script:RepairsApplied++ + return + } + + try { + Write-Host " $esc[90mStopping Explorer...$esc[0m" + Stop-Process -Name "explorer" -Force -ErrorAction SilentlyContinue + Start-Sleep -Seconds 2 + + # Delete icon cache files + $iconCacheFiles = Get-ChildItem -Path $iconCachePath -Filter "iconcache_*.db" -Force -ErrorAction SilentlyContinue + $thumbCacheFiles = Get-ChildItem -Path $iconCachePath -Filter "thumbcache_*.db" -Force -ErrorAction SilentlyContinue + + $deletedCount = 0 + foreach ($file in $iconCacheFiles) { + Remove-Item -Path $file.FullName -Force -ErrorAction SilentlyContinue + $deletedCount++ + } + + foreach ($file in $thumbCacheFiles) { + Remove-Item -Path $file.FullName -Force -ErrorAction SilentlyContinue + $deletedCount++ + } + + $systemIconCache = "$env:LOCALAPPDATA\IconCache.db" + if (Test-Path $systemIconCache) { + Remove-Item -Path $systemIconCache -Force -ErrorAction SilentlyContinue + $deletedCount++ + } + + Write-Host " $esc[90mRestarting Explorer...$esc[0m" + Start-Process "explorer.exe" + + Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Icon cache rebuilt ($deletedCount files cleared)" + Write-Host " $esc[90mNote: Icons will rebuild gradually as you browse$esc[0m" + $script:RepairsApplied++ + } + catch { + Write-Host " $esc[31m$($script:Icons.Error)$esc[0m Could not rebuild icon cache: $_" + Start-Process "explorer.exe" -ErrorAction SilentlyContinue + } +} + +function Repair-SearchIndex { + <# + .SYNOPSIS + Reset Windows Search index + .DESCRIPTION + Stops the Windows Search service, deletes the search index, and restarts. + Fixes issues with search not finding files or returning incorrect results. + #> + + $esc = [char]27 + + Write-Host "" + Write-Host "$esc[34m$($script:Icons.Arrow) Windows Search Index Reset$esc[0m" + + if (-not (Test-IsAdmin)) { + Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Requires administrator privileges" + return + } + + $searchIndexPath = "$env:ProgramData\Microsoft\Search\Data\Applications\Windows" + + if ($script:DryRun) { + Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would stop Windows Search service" + Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would delete search index database" + Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would restart Windows Search service" + $script:RepairsApplied++ + return + } + + try { + Write-Host " $esc[90mStopping Windows Search service...$esc[0m" + Stop-Service -Name "WSearch" -Force -ErrorAction Stop + Start-Sleep -Seconds 3 + + if (Test-Path $searchIndexPath) { + Write-Host " $esc[90mDeleting search index...$esc[0m" + Remove-Item -Path "$searchIndexPath\*" -Recurse -Force -ErrorAction SilentlyContinue + } + + Write-Host " $esc[90mRestarting Windows Search service...$esc[0m" + Start-Service -Name "WSearch" -ErrorAction Stop + + Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Search index reset successfully" + Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m Indexing will rebuild in the background (may take hours)" + $script:RepairsApplied++ + } + catch { + Write-Host " $esc[31m$($script:Icons.Error)$esc[0m Could not reset search index: $_" + Start-Service -Name "WSearch" -ErrorAction SilentlyContinue + } +} + +function Repair-StoreCache { + <# + .SYNOPSIS + Reset Windows Store cache + .DESCRIPTION + Runs wsreset.exe to clear the Windows Store cache. + Fixes issues with Store apps not installing, updating, or launching. + #> + + $esc = [char]27 + + Write-Host "" + Write-Host "$esc[34m$($script:Icons.Arrow) Windows Store Cache Reset$esc[0m" + + if ($script:DryRun) { + Write-Host " $esc[33m$($script:Icons.DryRun)$esc[0m Would run wsreset.exe" + $script:RepairsApplied++ + return + } + + try { + Write-Host " $esc[90mResetting Windows Store cache...$esc[0m" + $wsreset = Start-Process -FilePath "wsreset.exe" -PassThru -WindowStyle Hidden + $wsreset.WaitForExit(30000) + + if ($wsreset.ExitCode -eq 0) { + Write-Host " $esc[32m$($script:Icons.Success)$esc[0m Windows Store cache reset successfully" + } + else { + Write-Host " $esc[33m$($script:Icons.Warning)$esc[0m wsreset completed with code $($wsreset.ExitCode)" + } + $script:RepairsApplied++ + } + catch { + Write-Host " $esc[31m$($script:Icons.Error)$esc[0m Could not reset Store cache: $_" + } +} + # ============================================================================ # Summary # ============================================================================ @@ -459,12 +708,20 @@ function Show-OptimizeSummary { Write-Host "" if ($script:DryRun) { - Write-Host " Would apply $esc[33m$($script:OptimizationsApplied)$esc[0m optimizations" + $total = $script:OptimizationsApplied + $script:RepairsApplied + Write-Host " Would apply $esc[33m$total$esc[0m changes" + if ($script:RepairsApplied -gt 0) { + Write-Host " ($($script:OptimizationsApplied) optimizations, $($script:RepairsApplied) repairs)" + } Write-Host " Run without -DryRun to apply changes" } else { Write-Host " Optimizations applied: $esc[32m$($script:OptimizationsApplied)$esc[0m" + if ($script:RepairsApplied -gt 0) { + Write-Host " Repairs applied: $esc[32m$($script:RepairsApplied)$esc[0m" + } + if ($script:IssuesFixed -gt 0) { Write-Host " Issues fixed: $esc[32m$($script:IssuesFixed)$esc[0m" } @@ -500,6 +757,9 @@ function Main { # Set dry-run mode $script:DryRun = $DryRun + # Check if any repairs were requested + $runRepairs = $Repair -or $Font -or $Icon -or $Search -or $Store + # Clear screen Clear-Host @@ -528,8 +788,30 @@ function Main { Test-DiskHealth Test-WindowsUpdate - # System file check is slow, ask first - if (-not $script:DryRun -and (Test-IsAdmin)) { + # Run repairs if requested + if ($runRepairs) { + Write-Host "" + Write-Host "$esc[1;35m$($script:Icons.Arrow) Repairs$esc[0m" + + if ($Repair -or $Font) { + Repair-FontCache + } + + if ($Repair -or $Icon) { + Repair-IconCache + } + + if ($Repair -or $Search) { + Repair-SearchIndex + } + + if ($Repair -or $Store) { + Repair-StoreCache + } + } + + # System file check is slow, ask first (only if not doing repairs) + if (-not $runRepairs -and -not $script:DryRun -and (Test-IsAdmin)) { Write-Host "" $runSfc = Read-Host "Run System File Checker? This may take several minutes (y/N)" if ($runSfc -eq 'y' -or $runSfc -eq 'Y') { diff --git a/lib/clean/apps.ps1 b/lib/clean/apps.ps1 index 36ed9c7..eb36e1e 100644 --- a/lib/clean/apps.ps1 +++ b/lib/clean/apps.ps1 @@ -402,6 +402,269 @@ function Clear-GamingPlatformCaches { } } +# ============================================================================ +# Game Media Cleanup (Replays, Screenshots, Recordings) +# ============================================================================ + +function Clear-GameMediaFiles { + <# + .SYNOPSIS + Clean old game replays, screenshots, and recordings + .DESCRIPTION + Removes old media files from various gaming sources: + - NVIDIA ShadowPlay/Highlights + - AMD ReLive + - Xbox Game Bar captures + - Steam screenshots + - OBS recordings + - Windows Game DVR + - GeForce Experience + + By default, only removes files older than 90 days. + User media in standard Pictures/Videos folders is NOT touched + unless it's in a game-specific subfolder. + .PARAMETER DaysOld + Minimum age of files to remove (default: 90 days) + #> + param( + [int]$DaysOld = 90 + ) + + Start-Section "Game media (>${DaysOld}d old)" + + $cutoffDate = (Get-Date).AddDays(-$DaysOld) + $mediaExtensions = @('*.mp4', '*.mkv', '*.avi', '*.mov', '*.wmv', '*.webm', '*.png', '*.jpg', '*.jpeg', '*.bmp', '*.gif') + + # ------------------------------------------------------------------------- + # NVIDIA ShadowPlay / GeForce Experience + # ------------------------------------------------------------------------- + $nvidiaPaths = @( + "$env:USERPROFILE\Videos\NVIDIA" # Default ShadowPlay location + "$env:USERPROFILE\Videos\ShadowPlay" # Alternative name + "$env:USERPROFILE\Videos\GeForce Experience" # GeForce Experience recordings + ) + + foreach ($basePath in $nvidiaPaths) { + if (Test-Path $basePath) { + foreach ($ext in $mediaExtensions) { + $oldFiles = Get-ChildItem -Path $basePath -Filter $ext -File -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate } + if ($oldFiles) { + $paths = $oldFiles | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "NVIDIA recordings (>${DaysOld}d)" + } + } + } + } + + # NVIDIA Highlights (game-specific clips) + $highlightsPath = "$env:USERPROFILE\Videos\NVIDIA\Highlights" + if (Test-Path $highlightsPath) { + $oldHighlights = Get-ChildItem -Path $highlightsPath -File -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate -and $_.Extension -match '\.(mp4|mkv|avi|mov)$' } + if ($oldHighlights) { + $paths = $oldHighlights | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "NVIDIA Highlights (>${DaysOld}d)" + } + } + + # ------------------------------------------------------------------------- + # AMD ReLive / Radeon Software + # ------------------------------------------------------------------------- + $amdPaths = @( + "$env:USERPROFILE\Videos\Radeon ReLive" + "$env:USERPROFILE\Videos\AMD" + "$env:USERPROFILE\Videos\Radeon" + ) + + foreach ($basePath in $amdPaths) { + if (Test-Path $basePath) { + foreach ($ext in $mediaExtensions) { + $oldFiles = Get-ChildItem -Path $basePath -Filter $ext -File -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate } + if ($oldFiles) { + $paths = $oldFiles | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "AMD ReLive recordings (>${DaysOld}d)" + } + } + } + } + + # ------------------------------------------------------------------------- + # Xbox Game Bar / Windows Game DVR + # ------------------------------------------------------------------------- + $xboxCapturesPath = "$env:USERPROFILE\Videos\Captures" + if (Test-Path $xboxCapturesPath) { + foreach ($ext in $mediaExtensions) { + $oldFiles = Get-ChildItem -Path $xboxCapturesPath -Filter $ext -File -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate } + if ($oldFiles) { + $paths = $oldFiles | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "Xbox Game Bar captures (>${DaysOld}d)" + } + } + } + + # ------------------------------------------------------------------------- + # Windows Snipping Tool / Snip & Sketch Screenshots + # ------------------------------------------------------------------------- + $windowsScreenshotsPath = "$env:USERPROFILE\Pictures\Screenshots" + if (Test-Path $windowsScreenshotsPath) { + foreach ($ext in @('*.png', '*.jpg', '*.jpeg', '*.gif', '*.bmp')) { + $oldFiles = Get-ChildItem -Path $windowsScreenshotsPath -Filter $ext -File -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate } + if ($oldFiles) { + $paths = $oldFiles | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "Windows screenshots (>${DaysOld}d)" + } + } + } + + # ------------------------------------------------------------------------- + # Windows Screen Recordings (Snipping Tool / Win+Alt+R) + # ------------------------------------------------------------------------- + $windowsRecordingsPath = "$env:USERPROFILE\Videos\Screen Recordings" + if (Test-Path $windowsRecordingsPath) { + foreach ($ext in @('*.mp4', '*.mkv', '*.avi', '*.mov', '*.wmv')) { + $oldFiles = Get-ChildItem -Path $windowsRecordingsPath -Filter $ext -File -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate } + if ($oldFiles) { + $paths = $oldFiles | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "Windows screen recordings (>${DaysOld}d)" + } + } + } + + # ------------------------------------------------------------------------- + # Steam Screenshots + # ------------------------------------------------------------------------- + # Steam stores screenshots in userdata\\760\remote\\screenshots + $steamUserDataPath = "${env:ProgramFiles(x86)}\Steam\userdata" + if (Test-Path $steamUserDataPath) { + $screenshotFolders = Get-ChildItem -Path $steamUserDataPath -Directory -ErrorAction SilentlyContinue | + ForEach-Object { Join-Path $_.FullName "760\remote" } | + Where-Object { Test-Path $_ } + + foreach ($folder in $screenshotFolders) { + $oldScreenshots = Get-ChildItem -Path $folder -Filter "*.jpg" -File -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate } + if ($oldScreenshots) { + $paths = $oldScreenshots | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "Steam screenshots (>${DaysOld}d)" + } + } + } + + # Also check common Steam screenshot export location + $steamScreenshotsPath = "$env:USERPROFILE\Pictures\Steam Screenshots" + if (Test-Path $steamScreenshotsPath) { + $oldFiles = Get-ChildItem -Path $steamScreenshotsPath -Filter "*.jpg" -File -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate } + if ($oldFiles) { + $paths = $oldFiles | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "Steam exported screenshots (>${DaysOld}d)" + } + } + + # ------------------------------------------------------------------------- + # OBS Studio Recordings + # ------------------------------------------------------------------------- + $obsRecordingsPath = "$env:USERPROFILE\Videos\OBS" + if (Test-Path $obsRecordingsPath) { + foreach ($ext in @('*.mp4', '*.mkv', '*.flv', '*.mov', '*.ts')) { + $oldFiles = Get-ChildItem -Path $obsRecordingsPath -Filter $ext -File -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate } + if ($oldFiles) { + $paths = $oldFiles | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "OBS recordings (>${DaysOld}d)" + } + } + } + + # ------------------------------------------------------------------------- + # Windows Game DVR (legacy location) + # ------------------------------------------------------------------------- + $gameDvrPath = "$env:LOCALAPPDATA\Packages\Microsoft.XboxGamingOverlay_*\LocalState\GameDVR" + $gameDvrPaths = Resolve-Path $gameDvrPath -ErrorAction SilentlyContinue + foreach ($path in $gameDvrPaths) { + if (Test-Path $path.Path) { + $oldFiles = Get-ChildItem -Path $path.Path -File -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate -and $_.Extension -match '\.(mp4|png)$' } + if ($oldFiles) { + $paths = $oldFiles | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "Game DVR recordings (>${DaysOld}d)" + } + } + } + + # ------------------------------------------------------------------------- + # Medal.tv Clips + # ------------------------------------------------------------------------- + $medalPath = "$env:USERPROFILE\Videos\Medal" + if (Test-Path $medalPath) { + foreach ($ext in $mediaExtensions) { + $oldFiles = Get-ChildItem -Path $medalPath -Filter $ext -File -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate } + if ($oldFiles) { + $paths = $oldFiles | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "Medal.tv clips (>${DaysOld}d)" + } + } + } + + # ------------------------------------------------------------------------- + # Overwolf / Outplayed Recordings + # ------------------------------------------------------------------------- + $overwolfPaths = @( + "$env:USERPROFILE\Videos\Overwolf" + "$env:USERPROFILE\Videos\Outplayed" + ) + foreach ($basePath in $overwolfPaths) { + if (Test-Path $basePath) { + foreach ($ext in $mediaExtensions) { + $oldFiles = Get-ChildItem -Path $basePath -Filter $ext -File -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate } + if ($oldFiles) { + $paths = $oldFiles | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "Overwolf/Outplayed recordings (>${DaysOld}d)" + } + } + } + } + + # ------------------------------------------------------------------------- + # Game-specific replay folders (common locations) + # ------------------------------------------------------------------------- + $gameReplayPaths = @( + # Fortnite replays + "$env:LOCALAPPDATA\FortniteGame\Saved\Demos" + # League of Legends replays + "$env:USERPROFILE\Documents\League of Legends\Replays" + # Valorant + "$env:LOCALAPPDATA\VALORANT\Saved\Logs" + # Rocket League replays + "$env:USERPROFILE\Documents\My Games\Rocket League\TAGame\Demos" + # Call of Duty + "$env:USERPROFILE\Documents\Call of Duty\players\theatre" + # Apex Legends + "$env:USERPROFILE\Saved Games\Respawn\Apex\assets\temp" + ) + + foreach ($path in $gameReplayPaths) { + if (Test-Path $path) { + $oldFiles = Get-ChildItem -Path $path -File -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.LastWriteTime -lt $cutoffDate } + if ($oldFiles) { + $gameName = (Split-Path (Split-Path $path -Parent) -Leaf) + $paths = $oldFiles | ForEach-Object { $_.FullName } + Remove-SafeItems -Paths $paths -Description "$gameName replays (>${DaysOld}d)" + } + } + } + + Stop-Section +} + # ============================================================================ # Main Application Cleanup Function # ============================================================================ @@ -411,7 +674,11 @@ function Invoke-AppCleanup { .SYNOPSIS Run all application-specific cleanup tasks #> - param([switch]$IncludeOrphaned) + param( + [switch]$IncludeOrphaned, + [switch]$IncludeGameMedia, + [int]$GameMediaDaysOld = 90 + ) Start-Section "Applications" @@ -430,6 +697,11 @@ function Invoke-AppCleanup { Stop-Section + # Game media (replays, screenshots, recordings) + if ($IncludeGameMedia) { + Clear-GameMediaFiles -DaysOld $GameMediaDaysOld + } + # Orphaned app data (separate section) if ($IncludeOrphaned) { Clear-OrphanedAppData -DaysOld 60 diff --git a/lib/clean/caches.ps1 b/lib/clean/caches.ps1 index bba2550..e48832f 100644 --- a/lib/clean/caches.ps1 +++ b/lib/clean/caches.ps1 @@ -337,6 +337,79 @@ function Clear-DotNetCaches { # Assembly cache (don't touch - managed by CLR) } +# ============================================================================ +# GPU Shader Caches +# ============================================================================ + +function Clear-GPUShaderCaches { + <# + .SYNOPSIS + Clean GPU shader caches (NVIDIA, AMD, Intel, DirectX) + .DESCRIPTION + GPU drivers cache compiled shaders to improve game/app load times. + These caches can grow very large (10GB+) and are safe to delete. + They will be rebuilt automatically when needed. + #> + + Start-Section "GPU shader caches" + + # NVIDIA shader caches + $nvidiaCachePaths = @( + "$env:LOCALAPPDATA\NVIDIA\DXCache" + "$env:LOCALAPPDATA\NVIDIA\GLCache" + "$env:LOCALAPPDATA\NVIDIA Corporation\NV_Cache" + "$env:TEMP\NVIDIA Corporation\NV_Cache" + ) + foreach ($path in $nvidiaCachePaths) { + if (Test-Path $path) { + Clear-DirectoryContents -Path $path -Description "NVIDIA shader cache" + } + } + + # AMD shader caches + $amdCachePaths = @( + "$env:LOCALAPPDATA\AMD\DXCache" + "$env:LOCALAPPDATA\AMD\GLCache" + "$env:LOCALAPPDATA\AMD\VkCache" + ) + foreach ($path in $amdCachePaths) { + if (Test-Path $path) { + Clear-DirectoryContents -Path $path -Description "AMD shader cache" + } + } + + # Intel shader caches + $intelCachePaths = @( + "$env:LOCALAPPDATA\Intel\ShaderCache" + "$env:APPDATA\Intel\ShaderCache" + ) + foreach ($path in $intelCachePaths) { + if (Test-Path $path) { + Clear-DirectoryContents -Path $path -Description "Intel shader cache" + } + } + + # DirectX shader cache (system-wide) + $dxCachePath = "$env:LOCALAPPDATA\D3DSCache" + if (Test-Path $dxCachePath) { + Clear-DirectoryContents -Path $dxCachePath -Description "DirectX shader cache" + } + + # DirectX pipeline cache + $dxPipelinePath = "$env:LOCALAPPDATA\Microsoft\DirectX Shader Cache" + if (Test-Path $dxPipelinePath) { + Clear-DirectoryContents -Path $dxPipelinePath -Description "DirectX pipeline cache" + } + + # Vulkan pipeline cache (common location) + $vulkanCachePath = "$env:LOCALAPPDATA\VulkanCache" + if (Test-Path $vulkanCachePath) { + Clear-DirectoryContents -Path $vulkanCachePath -Description "Vulkan pipeline cache" + } + + Stop-Section +} + # ============================================================================ # Main Cache Cleanup Function # ============================================================================ @@ -349,7 +422,8 @@ function Invoke-CacheCleanup { param( [switch]$IncludeWindowsUpdate, [switch]$IncludeBrowsers, - [switch]$IncludeApps + [switch]$IncludeApps, + [switch]$IncludeGPU ) Start-Section "System caches" @@ -368,6 +442,11 @@ function Invoke-CacheCleanup { Stop-Section + # GPU shader caches + if ($IncludeGPU) { + Clear-GPUShaderCaches + } + # Browser caches if ($IncludeBrowsers) { Clear-BrowserCaches diff --git a/mole.ps1 b/mole.ps1 index f5c5eab..e82f4af 100644 --- a/mole.ps1 +++ b/mole.ps1 @@ -61,7 +61,7 @@ function Show-MainHelp { Write-Host " ${cyan}uninstall${nc} Smart application uninstaller" Write-Host " ${cyan}analyze${nc} Visual disk space analyzer" Write-Host " ${cyan}status${nc} Real-time system monitor" - Write-Host " ${cyan}optimize${nc} System optimization tasks" + Write-Host " ${cyan}optimize${nc} System optimization and repairs" Write-Host " ${cyan}purge${nc} Clean project build artifacts" Write-Host "" Write-Host " ${green}OPTIONS:${nc}" @@ -71,14 +71,16 @@ function Show-MainHelp { Write-Host "" Write-Host " ${green}EXAMPLES:${nc}" Write-Host "" - Write-Host " ${gray}mole${nc} ${gray}# Interactive menu${nc}" - Write-Host " ${gray}mole clean${nc} ${gray}# Deep cleanup${nc}" - Write-Host " ${gray}mole clean -DryRun${nc} ${gray}# Preview cleanup${nc}" - Write-Host " ${gray}mole uninstall${nc} ${gray}# Uninstall apps${nc}" - Write-Host " ${gray}mole analyze${nc} ${gray}# Disk analyzer${nc}" - Write-Host " ${gray}mole status${nc} ${gray}# System monitor${nc}" - Write-Host " ${gray}mole optimize${nc} ${gray}# Optimize system${nc}" - Write-Host " ${gray}mole purge${nc} ${gray}# Clean dev artifacts${nc}" + Write-Host " ${gray}mole${nc} ${gray}# Interactive menu${nc}" + Write-Host " ${gray}mole clean${nc} ${gray}# Deep cleanup${nc}" + Write-Host " ${gray}mole clean -DryRun${nc} ${gray}# Preview cleanup${nc}" + Write-Host " ${gray}mole uninstall${nc} ${gray}# Uninstall apps${nc}" + Write-Host " ${gray}mole analyze${nc} ${gray}# Disk analyzer${nc}" + Write-Host " ${gray}mole status${nc} ${gray}# System monitor${nc}" + Write-Host " ${gray}mole optimize${nc} ${gray}# Optimize system${nc}" + Write-Host " ${gray}mole optimize -Repair${nc} ${gray}# Optimize + all repairs${nc}" + Write-Host " ${gray}mole optimize -Icon${nc} ${gray}# Optimize + rebuild icons${nc}" + Write-Host " ${gray}mole purge${nc} ${gray}# Clean dev artifacts${nc}" Write-Host "" Write-Host " ${green}ENVIRONMENT:${nc}" Write-Host "" @@ -121,7 +123,7 @@ function Show-MainMenu { } @{ Name = "Optimize" - Description = "System optimization" + Description = "Optimization & repairs" Command = "optimize" Icon = $script:Icons.Arrow }