microsoft/TypeAgent
Publicmirrored fromhttps://github.com/microsoft/TypeAgentAvailable
dotnet/agentLauncher/src/Install.ps1
269lines · modecode
| 1 | # |
| 2 | # TypeAgent Agent Launcher - Installation Script |
| 3 | # This script handles automatic elevation and installs the AgentLauncher MSIX package |
| 4 | # |
| 5 | |
| 6 | param( |
| 7 | [Parameter(DontShow)] |
| 8 | [switch]$ElevatedInstance # Internal parameter marking this as the elevated fork |
| 9 | ) |
| 10 | |
| 11 | $ErrorActionPreference = "Stop" |
| 12 | |
| 13 | #region Utility Functions |
| 14 | |
| 15 | function Test-IsAdministrator { |
| 16 | <# |
| 17 | .SYNOPSIS |
| 18 | Checks if the current session has administrator privileges. |
| 19 | #> |
| 20 | $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent() |
| 21 | $principal = New-Object Security.Principal.WindowsPrincipal($currentUser) |
| 22 | return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) |
| 23 | } |
| 24 | |
| 25 | function Restart-ScriptElevated { |
| 26 | <# |
| 27 | .SYNOPSIS |
| 28 | Restarts the script with administrator privileges. |
| 29 | .DESCRIPTION |
| 30 | Copies the script to TEMP to handle path issues, then launches elevated instance. |
| 31 | #> |
| 32 | |
| 33 | Write-Host "`nThis script requires administrator privileges to install the MSIX package." -ForegroundColor Yellow |
| 34 | Write-Host "You will be prompted to elevate..." -ForegroundColor Yellow |
| 35 | Write-Host "" |
| 36 | |
| 37 | # Create temp directory with timestamp to avoid conflicts |
| 38 | $timestamp = Get-Date -Format "yyyyMMddHHmmss" |
| 39 | $tempScriptDir = Join-Path $env:TEMP "AgentLauncher_Install_$timestamp" |
| 40 | |
| 41 | try { |
| 42 | # Copy script to temp |
| 43 | Write-Host "Preparing elevated script..." -ForegroundColor Cyan |
| 44 | New-Item -ItemType Directory -Path $tempScriptDir -Force | Out-Null |
| 45 | Copy-Item "$PSScriptRoot\Install.ps1" -Destination $tempScriptDir -Force |
| 46 | |
| 47 | $tempScriptPath = Join-Path $tempScriptDir "Install.ps1" |
| 48 | |
| 49 | # Detect which PowerShell version is running |
| 50 | $powershellExecutable = if ($PSVersionTable.PSEdition -eq 'Core') { |
| 51 | "pwsh.exe" |
| 52 | } else { |
| 53 | "powershell.exe" |
| 54 | } |
| 55 | |
| 56 | Write-Host "Launching elevated instance using $powershellExecutable..." -ForegroundColor Cyan |
| 57 | Write-Host "" |
| 58 | |
| 59 | # Start elevated process and wait for completion |
| 60 | $process = Start-Process $powershellExecutable -ArgumentList "-ExecutionPolicy", "Bypass", "-File", "`"$tempScriptPath`"", "-ElevatedInstance" -Verb RunAs -Wait -PassThru |
| 61 | |
| 62 | # Check if user cancelled the UAC prompt |
| 63 | if ($null -eq $process) { |
| 64 | Write-Host "Elevation cancelled by user." -ForegroundColor Yellow |
| 65 | |
| 66 | # Clean up temp folder |
| 67 | if (Test-Path $tempScriptDir) { |
| 68 | Remove-Item $tempScriptDir -Recurse -Force -ErrorAction SilentlyContinue |
| 69 | } |
| 70 | |
| 71 | return 1 |
| 72 | } |
| 73 | |
| 74 | if ($process.ExitCode -ne 0) { |
| 75 | Write-Host "Elevated installation FAILED with exit code: $($process.ExitCode)" -ForegroundColor Red |
| 76 | |
| 77 | # Clean up temp folder on failure |
| 78 | if (Test-Path $tempScriptDir) { |
| 79 | Remove-Item $tempScriptDir -Recurse -Force -ErrorAction SilentlyContinue |
| 80 | } |
| 81 | |
| 82 | return $process.ExitCode |
| 83 | } |
| 84 | |
| 85 | Write-Host "Elevated installation completed successfully." -ForegroundColor Green |
| 86 | |
| 87 | # Clean up temp folder on success |
| 88 | if (Test-Path $tempScriptDir) { |
| 89 | Remove-Item $tempScriptDir -Recurse -Force -ErrorAction SilentlyContinue |
| 90 | } |
| 91 | |
| 92 | return 0 |
| 93 | } |
| 94 | catch { |
| 95 | Write-Host "Failed to restart with elevation. Error: $($_.Exception.Message)" -ForegroundColor Red |
| 96 | Write-Host "Please run PowerShell as Administrator manually and try again." -ForegroundColor Yellow |
| 97 | |
| 98 | # Clean up temp folder on error |
| 99 | if (Test-Path $tempScriptDir) { |
| 100 | Remove-Item $tempScriptDir -Recurse -Force -ErrorAction SilentlyContinue |
| 101 | } |
| 102 | |
| 103 | return 1 |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | #endregion |
| 108 | |
| 109 | #region Main Installation Logic |
| 110 | |
| 111 | function Install-AgentLauncher { |
| 112 | <# |
| 113 | .SYNOPSIS |
| 114 | Performs the actual installation of the AgentLauncher package. |
| 115 | .DESCRIPTION |
| 116 | This function contains all the operations that require elevation: |
| 117 | - Installing the development certificate |
| 118 | - Removing old package |
| 119 | - Installing new package |
| 120 | #> |
| 121 | |
| 122 | # Use PSScriptRoot if available, otherwise try to find it |
| 123 | $scriptDir = $PSScriptRoot |
| 124 | if ([string]::IsNullOrEmpty($scriptDir)) { |
| 125 | $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path |
| 126 | } |
| 127 | |
| 128 | # If we're running from TEMP (elevated instance), navigate back to the actual install location |
| 129 | if ($scriptDir -like "*\Temp\*") { |
| 130 | # Assume the actual location is the standard path |
| 131 | $scriptDir = "D:\repos\TypeAgent\dotnet\agentLauncher\src" |
| 132 | if (-not (Test-Path $scriptDir)) { |
| 133 | Write-Host "ERROR: Could not determine installation directory" -ForegroundColor Red |
| 134 | Write-Host "Please run this script from the agentLauncher\src directory" -ForegroundColor Yellow |
| 135 | return 1 |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | # Paths |
| 140 | $pfxPath = Join-Path $scriptDir "TypeAgent_TemporaryKey.pfx" |
| 141 | $packageDir = Join-Path $scriptDir "bin\x64\Debug\net8.0-windows10.0.26100.0\AppPackages\AgentLauncher_1.0.0.0_x64_Debug_Test" |
| 142 | $msixPath = Join-Path $packageDir "AgentLauncher_1.0.0.0_x64_Debug.msix" |
| 143 | |
| 144 | Write-Host "TypeAgent Agent Launcher - Installation Script" -ForegroundColor Cyan |
| 145 | Write-Host "=============================================" -ForegroundColor Cyan |
| 146 | Write-Host "" |
| 147 | Write-Host "Installation directory: $scriptDir" -ForegroundColor Gray |
| 148 | Write-Host "" |
| 149 | |
| 150 | # Step 1: Check if package exists |
| 151 | if (-not (Test-Path $msixPath)) { |
| 152 | Write-Host "ERROR: Package not found at: $msixPath" -ForegroundColor Red |
| 153 | Write-Host "Please build the project first with: .\Build.ps1" -ForegroundColor Yellow |
| 154 | return 1 |
| 155 | } |
| 156 | |
| 157 | Write-Host "Package found:" -ForegroundColor Green |
| 158 | Write-Host " $msixPath" -ForegroundColor Gray |
| 159 | Write-Host "" |
| 160 | |
| 161 | # Step 2: Install certificate to Trusted Root |
| 162 | Write-Host "Step 1: Installing development certificate..." -ForegroundColor Yellow |
| 163 | try { |
| 164 | $password = ConvertTo-SecureString -String "test123" -Force -AsPlainText |
| 165 | Import-PfxCertificate -FilePath $pfxPath -CertStoreLocation "Cert:\LocalMachine\Root" -Password $password -ErrorAction SilentlyContinue | Out-Null |
| 166 | Write-Host " Certificate installed successfully" -ForegroundColor Green |
| 167 | } catch { |
| 168 | Write-Host " Certificate may already be installed (this is OK)" -ForegroundColor Gray |
| 169 | } |
| 170 | |
| 171 | # Step 3: Remove old package if exists |
| 172 | Write-Host "" |
| 173 | Write-Host "Step 2: Removing existing package (if any)..." -ForegroundColor Yellow |
| 174 | $existingPackage = Get-AppxPackage -Name "TypeAgent.AgentLauncher" -ErrorAction SilentlyContinue |
| 175 | if ($existingPackage) { |
| 176 | Remove-AppxPackage -Package $existingPackage.PackageFullName |
| 177 | Write-Host " Removed existing package: $($existingPackage.Version)" -ForegroundColor Green |
| 178 | } else { |
| 179 | Write-Host " No existing package found" -ForegroundColor Gray |
| 180 | } |
| 181 | |
| 182 | # Step 4: Install new package |
| 183 | Write-Host "" |
| 184 | Write-Host "Step 3: Installing TypeAgent Agent Launcher..." -ForegroundColor Yellow |
| 185 | try { |
| 186 | Add-AppxPackage -Path $msixPath |
| 187 | Write-Host " Package installed successfully" -ForegroundColor Green |
| 188 | } catch { |
| 189 | Write-Host " ERROR: Failed to install package" -ForegroundColor Red |
| 190 | Write-Host " $($_.Exception.Message)" -ForegroundColor Red |
| 191 | return 1 |
| 192 | } |
| 193 | |
| 194 | # Step 5: Verify installation |
| 195 | Write-Host "" |
| 196 | Write-Host "Verifying installation..." -ForegroundColor Yellow |
| 197 | $installed = Get-AppxPackage -Name "TypeAgent.AgentLauncher" |
| 198 | if ($installed) { |
| 199 | Write-Host " Installation verified!" -ForegroundColor Green |
| 200 | Write-Host "" |
| 201 | Write-Host "Package Details:" -ForegroundColor Cyan |
| 202 | Write-Host " Name: $($installed.Name)" -ForegroundColor Gray |
| 203 | Write-Host " Version: $($installed.Version)" -ForegroundColor Gray |
| 204 | Write-Host " Install Location: $($installed.InstallLocation)" -ForegroundColor Gray |
| 205 | Write-Host " Package Family Name: $($installed.PackageFamilyName)" -ForegroundColor Gray |
| 206 | } else { |
| 207 | Write-Host " ERROR: Package not found after installation" -ForegroundColor Red |
| 208 | return 1 |
| 209 | } |
| 210 | |
| 211 | Write-Host "" |
| 212 | Write-Host "Installation complete!" -ForegroundColor Green |
| 213 | Write-Host "" |
| 214 | Write-Host "Next steps:" -ForegroundColor Cyan |
| 215 | Write-Host " 1. Check ODR registration: odr app-agents list" -ForegroundColor Gray |
| 216 | Write-Host " 2. Ensure TypeAgent's agent service is running" -ForegroundColor Gray |
| 217 | Write-Host " 3. Run actions using the universal composer" -ForegroundColor Gray |
| 218 | Write-Host "" |
| 219 | |
| 220 | return 0 |
| 221 | } |
| 222 | |
| 223 | #endregion |
| 224 | |
| 225 | #region Main Entry Point |
| 226 | |
| 227 | function Main { |
| 228 | <# |
| 229 | .SYNOPSIS |
| 230 | Main entry point for the installation script. |
| 231 | .DESCRIPTION |
| 232 | Handles elevation logic: |
| 233 | - If already admin: Install directly |
| 234 | - If not admin: Launch elevated instance and wait |
| 235 | - If elevated instance: Install and exit |
| 236 | #> |
| 237 | |
| 238 | $isAdmin = Test-IsAdministrator |
| 239 | |
| 240 | if ($isAdmin) { |
| 241 | # Already running as admin - proceed with installation |
| 242 | if ($ElevatedInstance) { |
| 243 | Write-Host "Running as Administrator (elevated instance)..." -ForegroundColor Green |
| 244 | } else { |
| 245 | Write-Host "Running as Administrator..." -ForegroundColor Green |
| 246 | } |
| 247 | Write-Host "" |
| 248 | |
| 249 | $exitCode = Install-AgentLauncher |
| 250 | |
| 251 | if ($ElevatedInstance) { |
| 252 | # Pause so user can see results before window closes |
| 253 | Write-Host "" |
| 254 | Write-Host "Press any key to continue..." -ForegroundColor Gray |
| 255 | $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") |
| 256 | } |
| 257 | |
| 258 | exit $exitCode |
| 259 | } else { |
| 260 | # Not admin - need to elevate |
| 261 | $exitCode = Restart-ScriptElevated |
| 262 | exit $exitCode |
| 263 | } |
| 264 | } |
| 265 | |
| 266 | # Execute main function |
| 267 | Main |
| 268 | |
| 269 | #endregion |
| 270 | |