#Requires -Version 5.1 # Office Auto Installer - WPF with Windows 11 Fluent Design # Single-file, self-contained Office installer with WPF and Fluent theme # Downloads and installs Microsoft Office through official channels # Updated release workflow to include both GUI and Console versions <# .SYNOPSIS Microsoft Office Auto Installer - WPF Fluent Design Edition .DESCRIPTION A beautiful, modern WPF application with Windows 11 Fluent Design theme. All options are pre-filled with recommended defaults for one-click installation. Fully self-contained - no external dependencies required. .NOTES Version: 5.0 - WPF with Fluent Design Theme Author: Office Auto Installer Team Requires: .NET Framework 4.7.2+ or .NET 6+ (for Fluent theme: .NET 9+) #> # ============================================================================ # INITIALIZATION & PREREQUISITES # ============================================================================ # This section handles error handling, dependency checks, and basic setup # before loading the WPF user interface. $ErrorActionPreference = "Continue" # Continue on errors to show user-friendly messages # Load Windows Forms assembly first (needed for error dialogs before WPF is loaded) # This ensures we can display error messages even if WPF fails to initialize Add-Type -AssemblyName System.Windows.Forms -ErrorAction SilentlyContinue # ============================================================================ # .NET FRAMEWORK VERSION CHECK # ============================================================================ # WPF (Windows Presentation Foundation) requires .NET Framework 4.7.2 or later. # Note: WPF does NOT work with .NET Core/.NET 5+. It requires the full .NET Framework. # This check ensures the user has the required runtime before attempting to load WPF. $netFrameworkVersion = $null $netFrameworkInstalled = $false try { # Check registry for .NET Framework 4.x $netFrameworkVersion = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -ErrorAction SilentlyContinue).Release if ($null -ne $netFrameworkVersion) { $netFrameworkInstalled = $true } } catch { # Registry check failed, try alternative method try { $netFrameworkVersion = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client" -ErrorAction SilentlyContinue).Release if ($null -ne $netFrameworkVersion) { $netFrameworkInstalled = $true } } catch { $netFrameworkInstalled = $false } } # If .NET Framework not found, show error if (-not $netFrameworkInstalled) { $errorMsg = ".NET Framework 4.7.2 or later is required for this WPF application.`n`n" + "Please install .NET Framework 4.8 from:`n" + "https://dotnet.microsoft.com/download/dotnet-framework/net48`n`n" + "After installation, restart this application.`n`n" + "Note: This application requires Windows PowerShell (not PowerShell Core)." try { [System.Windows.Forms.MessageBox]::Show($errorMsg, ".NET Framework Required", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) } catch { Write-Host $errorMsg -ForegroundColor Red } exit 1 } # Check if .NET Framework version is 4.7.2 or later (Release >= 461808) if ($netFrameworkVersion -lt 461808) { $errorMsg = ".NET Framework 4.7.2 or later is required.`n`n" + "Your version appears to be older (Release: $netFrameworkVersion).`n`n" + "Please install .NET Framework 4.8 from:`n" + "https://dotnet.microsoft.com/download/dotnet-framework/net48`n`n" + "After installation, restart this application." try { [System.Windows.Forms.MessageBox]::Show($errorMsg, ".NET Framework Version Too Old", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error) } catch { Write-Host $errorMsg -ForegroundColor Red } exit 1 } # Load required assemblies for WPF try { Add-Type -AssemblyName PresentationFramework -ErrorAction Stop Add-Type -AssemblyName PresentationCore -ErrorAction Stop Add-Type -AssemblyName WindowsBase -ErrorAction Stop Add-Type -AssemblyName System.Xaml -ErrorAction Stop } catch { [System.Windows.Forms.MessageBox]::Show( "Failed to load WPF assemblies.`n`nError: $_`n`nPlease ensure .NET Framework 4.7.2 or later is installed.`n`nDownload from: https://dotnet.microsoft.com/download/dotnet-framework/net48", "WPF Assembly Load Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error ) exit 1 } # Try to load Fluent theme if available (.NET 9+) # Note: Fluent theme is only available in .NET 9+, so we'll use custom styling $fluentThemeAvailable = $false # Custom Fluent-like styling will be used instead # ==== EXECUTION POLICY FIX ==== try { $currentPolicy = Get-ExecutionPolicy -Scope CurrentUser if ($currentPolicy -eq 'Restricted' -or $currentPolicy -eq 'AllSigned') { Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force -ErrorAction SilentlyContinue } } catch { } # ==== ADMIN CHECK ==== $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") if (-not $isAdmin) { $result = [System.Windows.Forms.MessageBox]::Show( "This installer requires administrator privileges to install Office.`n`nWould you like to restart with administrator rights?", "Administrator Required", [System.Windows.Forms.MessageBoxButtons]::YesNo, [System.Windows.Forms.MessageBoxIcon]::Question ) if ($result -eq [System.Windows.Forms.DialogResult]::Yes) { $scriptPath = if ($MyInvocation.MyCommand.Path) { $MyInvocation.MyCommand.Path } else { $PSCommandPath } if ($scriptPath) { Start-Process powershell "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`"" -Verb RunAs } else { $bytes = [System.Text.Encoding]::Unicode.GetBytes($MyInvocation.MyCommand.Definition) $encodedCommand = [Convert]::ToBase64String($bytes) Start-Process powershell "-NoProfile -ExecutionPolicy Bypass -EncodedCommand $encodedCommand" -Verb RunAs } exit } else { exit } } # ==== LOGGING ==== $logFile = "$env:TEMP\OfficeInstaller.log" function Log { param([string]$message) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" "$timestamp - $message" | Out-File -FilePath $logFile -Append -Encoding UTF8 } # ============================================================================ # TEMPORARY INSTALLATION FOLDER SETUP # ============================================================================ # Creates a temporary folder in the user's temp directory to store: # - setup.exe (Office Deployment Tool) # - config.xml (Office installation configuration) # This folder is cleaned up after installation completes. $installerFolder = "$env:TEMP\OfficeInstaller" if (-not (Test-Path $installerFolder)) { New-Item -ItemType Directory -Path $installerFolder -Force | Out-Null } # ============================================================================ # WPF XAML USER INTERFACE DEFINITION # ============================================================================ # This embedded XAML string defines the entire WPF window structure. # # Structure Overview: # 1. Window: Main application window with dark theme background # 2. Resources: Color brushes, styles for ComboBox, Button, etc. # 3. Layout: Grid-based layout with header, scrollable content, and footer # 4. Controls: ComboBoxes for selections, CheckBoxes for optional components # 5. Status Panel: Hidden by default, shown during installation # 6. Install Button: Primary action button at the bottom # # Design Philosophy: # - Windows 11 Fluent Design aesthetic with rounded corners # - Dark theme (#202020 background) for modern look # - Custom ComboBox styling to remove default white boxes # - Semi-transparent hover effects on dropdown items # - High-contrast focus indicators for accessibility (WCAG 2.4.7) # # Note: x:Class is intentionally omitted as it's not supported when # loading XAML dynamically in PowerShell. $xaml = @" $(if ($fluentThemeAvailable) { @" "@ })