The Bootstrap page is a core feature of TidyWindow that enables users to detect, install, repair, and uninstall package managers (winget, Chocolatey, and Scoop) on their Windows system. It provides a unified interface for managing the foundational tools required for package orchestration and automation workflows.
The Bootstrap page serves as the initial setup and verification hub for package managers. It ensures that users have the necessary tools installed and properly configured before proceeding with package installation and management tasks.
The Bootstrap feature is built using the MVVM (Model-View-ViewModel) pattern with the following components:
┌─────────────────────────────────────────────────────────────┐
│ BootstrapPage.xaml │
│ (View - UI Layer) │
└───────────────────────┬─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ BootstrapViewModel.cs │
│ (ViewModel - Business Logic) │
└───────┬───────────────────────────────┬─────────────────────┘
│ │
▼ ▼
┌───────────────────┐ ┌──────────────────────────┐
│ PackageManager │ │ PackageManager │
│ Detector │ │ Installer │
│ (Detection) │ │ (Install/Repair/Remove) │
└─────────┬─────────┘ └──────────┬───────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────┐
│ PowerShell Scripts (Automation Layer) │
│ • bootstrap-package-managers.ps1 │
│ • install-package-manager.ps1 │
│ • remove-package-manager.ps1 │
└─────────────────────────────────────────────────────────┘
- Location:
src/TidyWindow.App/ViewModels/BootstrapViewModel.cs - Responsibilities:
- Manages UI state (busy indicators, manager collection)
- Coordinates detection, installation, and uninstallation operations
- Handles error reporting and activity logging
- Updates manager status after operations
- Location:
src/TidyWindow.Core/PackageManagers/PackageManagerDetector.cs - Responsibilities:
- Executes PowerShell detection script
- Parses JSON results from detection
- Merges detection results with fallback detection logic
- Provides detection results as
PackageManagerInfoobjects
- Location:
src/TidyWindow.Core/PackageManagers/PackageManagerInstaller.cs - Responsibilities:
- Executes installation/repair scripts
- Executes uninstallation scripts
- Normalizes manager names (handles aliases)
- Returns
PowerShellInvocationResultwith operation outcomes
- Location:
src/TidyWindow.App/ViewModels/PackageManagerEntryViewModel.cs - Responsibilities:
- Represents individual package manager in UI
- Tracks installation status and operation history
- Provides computed properties for UI binding (action labels, visibility)
- Formats and displays status messages
The Bootstrap page uses a two-column layout:
Left Column:
- Detection Controls Card: Checkboxes for including Scoop/Chocolatey and "Run detection" button
- Manager Inventory Card: ListView displaying detected package managers with their status
Right Column:
- PowerShell Runtime Card: Information about PowerShell 7+ requirement
- Quick Guidance Card: Usage instructions
- Status Tips Card: Visual indicators for manager states
Each package manager entry displays:
- Name: Display name (e.g., "Windows Package Manager client", "Chocolatey CLI")
- Status Badge:
- 🟢 Green "Installed" for detected managers
- 🟡 Yellow "Missing" for undetected managers
- Status Message: Detailed information about detection results
- Action Buttons:
- "Install" or "Repair" button (green) for missing or installed managers
- "Uninstall" button (red) for installed managers
- Operation Feedback: Last operation message and success/failure indicators
Three overlay loaders provide visual feedback during operations:
BootstrapInstallLoader: Shown during install/repair operationsBootstrapUninstallLoader: Shown during uninstall operationsBootstrapUpdateLoader: Shown during detection operations
-
User Configuration
- User selects which optional managers to include (Scoop, Chocolatey)
- winget is always included as it's Windows-managed
-
Detection Execution
BootstrapViewModel.DetectAsync()is invokedPackageManagerDetector.DetectAsync()executes the PowerShell script- Script path:
automation/scripts/bootstrap-package-managers.ps1 - Parameters passed:
IncludeScoop,IncludeChocolatey
-
Script Processing
- PowerShell script checks for managers in common locations
- Checks PATH environment variable
- Verifies executable existence
- Returns JSON array with detection results
-
Result Parsing
- C# code parses JSON output
- Merges with fallback detection logic (for edge cases)
- Creates
PackageManagerInfoobjects
-
UI Update
UpdateManagers()synchronizes detected managers with UI collection- Existing entries are updated, new ones added, removed ones deleted
- Status messages and badges reflect current state
-
User Action
- User clicks "Install" or "Repair" button for a manager
BootstrapViewModel.InstallAsync()is invoked with manager entry
-
Validation
- Checks if manager allows install/repair (winget is Windows-managed)
- Verifies manager is not currently busy
-
Operation Execution
- Sets busy state and shows loader overlay
PackageManagerInstaller.InstallOrRepairAsync()executes script- Script path:
automation/scripts/install-package-manager.ps1 - Parameter:
Manager(normalized name)
-
Script Behavior
- Scoop: Downloads and executes official bootstrap script from
get.scoop.sh - Chocolatey: Downloads and executes official install script from
community.chocolatey.org - winget: Returns informational message (cannot be installed via automation)
- Handles elevation requests for Chocolatey (requires admin)
- Scoop: Downloads and executes official bootstrap script from
-
Result Processing
- Parses output and error streams
- Updates manager entry with operation result
- Logs to activity log service
- Shows success/failure message
-
Auto-Refresh
- After successful install, automatically runs detection again
- Updates UI with new installation status
-
User Action
- User clicks "Uninstall" button for an installed manager
BootstrapViewModel.UninstallAsync()is invoked
-
Validation
- Verifies manager is installed
- Checks if manager allows uninstall
-
Operation Execution
- Sets busy state and shows uninstall loader
PackageManagerInstaller.UninstallAsync()executes script- Script path:
automation/scripts/remove-package-manager.ps1
-
Script Behavior
- Scoop: Runs Scoop's uninstall script or removes directories manually
- Chocolatey: Uses
choco uninstall chocolateycommand - winget: Removes App Installer package via
Remove-AppxPackage - Handles elevation for Chocolatey and winget (admin required)
-
Result Processing
- Updates manager entry status
- Logs operation result
- Auto-refreshes detection if successful
Purpose: Detects installed package managers on the system.
Parameters:
IncludeScoop(switch): Include Scoop in detectionIncludeChocolatey(switch): Include Chocolatey in detection
Output: JSON array with detection results:
[
{
"Name": "winget",
"DisplayName": "Windows Package Manager client",
"Found": true,
"Notes": "Windows Package Manager client",
"CommandPath": "C:\\...\\winget.exe",
"InstalledVersion": "1.5.0"
}
]Detection Logic:
- winget: Checks
%LOCALAPPDATA%\Microsoft\WindowsApps\winget.exeand PATH - Chocolatey: Checks
%ChocolateyInstall%\bin\choco.exeand common install paths - Scoop: Checks
%SCOOP%\shims\scoop.exeand user profile locations
Purpose: Installs or repairs a package manager.
Parameters:
Manager(string, required): Manager name (winget, choco, scoop)Elevated(switch): Indicates elevated executionResultPath(string): Optional path for result JSON file
Manager-Specific Behavior:
Scoop:
- If installed: Runs
scoop updateto repair - If missing: Downloads bootstrap script from
https://get.scoop.sh - Sets execution policy to
RemoteSignedif needed - Executes bootstrap script (with
-RunAsAdminif elevated)
Chocolatey:
- If installed: Runs
choco upgrade chocolatey -yto repair - If missing: Downloads install script from
https://community.chocolatey.org/install.ps1 - Requires administrator privileges (requests elevation if needed)
- Sets execution policy to
Bypassfor installation
winget:
- Returns informational message (cannot be installed via automation)
- Directs users to Microsoft Store
Purpose: Uninstalls a package manager.
Parameters: Same as install script
Manager-Specific Behavior:
Scoop:
- Runs Scoop's uninstall script if available
- Otherwise uses
scoop uninstall scoop - Removes Scoop directories from common locations
- Cleans up environment variables
Chocolatey:
- Runs
choco uninstall chocolatey -y --remove-dependencies - Removes
%ChocolateyInstall%directory - Requires administrator privileges
winget:
- Removes App Installer package via
Remove-AppxPackage - Removes provisioned packages (if admin)
- Note: Windows may reinstall during servicing updates
- Script Execution Failure: Throws
InvalidOperationExceptionwith error details - Invalid JSON: Throws
InvalidOperationExceptionwith parsing error - File Not Found: Throws
FileNotFoundExceptionif script path cannot be resolved
- Administrator Denial: Detects UAC denial messages and provides user-friendly feedback
- Network Errors: Scripts handle download failures gracefully
- Execution Policy: Scripts attempt to set appropriate execution policy
- Operation Failures: Errors are captured in
PowerShellInvocationResult.Errors
- Activity Log: All operations are logged with details
- Status Messages: Main status bar shows current operation status
- Manager Entry: Each manager displays last operation message and success/failure indicator
- Error Messages: User-friendly messages for common scenarios (admin required, network issues)
IsBusy: Indicates any operation is in progressIsInstalling: Install/repair operation activeIsUninstalling: Uninstall operation activeIsUpdating: Detection operation activeIncludeScoop: Checkbox state for Scoop inclusionIncludeChocolatey: Checkbox state for Chocolatey inclusionManagers: Observable collection ofPackageManagerEntryViewModelobjects
IsInstalled: Current installation statusIsBusy: Manager-specific operation in progressLastOperationMessage: Result message from last operationLastOperationSucceeded: Boolean? indicating success/failure/null
All operations log to ActivityLogService with:
- Category: "Bootstrap"
- Message: Operation description
- Details: Context information (manager name, parameters, output, errors)
Operations register with IAutomationWorkTracker:
- Work type:
AutomationWorkType.Install - Description: Operation-specific description
- Token: GUID for tracking operation lifecycle
Status messages are relayed to MainViewModel.SetStatusMessage() for display in the main application status bar.
- PowerShell 7+: Ensure PowerShell 7 or newer is installed before using Bootstrap
- Administrator Rights: Be prepared to accept UAC prompts for Chocolatey operations
- Detection First: Always run detection before attempting install/repair
- Review Status: Check status messages and activity log for operation details
- Error Handling: Always check
PowerShellInvocationResult.IsSuccessbefore processing results - State Management: Update UI state in
finallyblocks to ensure cleanup - Logging: Include context details in activity log entries
- User Feedback: Provide clear, actionable error messages
- Auto-Refresh: Refresh detection after successful install/uninstall operations
- Scripts are executed via
PowerShellInvokerwhich handles:- PowerShell 7+ preference (falls back to Windows PowerShell)
- Execution policy management
- Output/error stream capture
- Exit code tracking
Script paths are resolved relative to AppContext.BaseDirectory with fallback to parent directories, ensuring scripts are found in both development and deployment scenarios.
The system handles various name formats:
- "choco" ↔ "chocolatey" ↔ "Chocolatey CLI"
- "scoop" ↔ "Scoop package manager"
- "winget" ↔ "Windows Package Manager client"
winget is treated specially:
- Cannot be installed via automation
- Cannot be uninstalled via automation (though removal script exists)
- UI shows informational message directing users to Windows Settings/Store
- Missing winget? Install or repair the Microsoft App Installer package. The quickest path is opening
ms-windows-store://pdp/?productid=9NBLGGH4NNS1(Store listing) and pressing Get. Offline or disconnected hosts can download the latestMicrosoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundleplus its dependency packages from https://aka.ms/getwinget and install them withAdd-AppxPackage -Path .\<package>.msixbundlefrom an elevated PowerShell prompt.
Potential improvements:
- Support for additional package managers
- Batch operations (install multiple managers)
- Health checks and diagnostics
- Automatic repair suggestions
- Installation history tracking