Public/Install-CpmfUipsPackCommandLineTool.ps1
|
function Install-CpmfUipsPackCommandLineTool { <# .SYNOPSIS Downloads and installs uipcli and its required .NET runtime into the user profile (%LOCALAPPDATA%\cpmf\tools). No admin rights required. Idempotent: already-present artifacts are detected and skipped. For uipcli 23.x (classic): downloads .NET 6.0.36 (base + WindowsDesktop) and extracts uipcli from its NuGet package. For uipcli 25.x+ (dotnet tool): downloads the .NET 8 SDK and installs uipcli via `dotnet tool install` into the user profile. .PARAMETER CliVersion UiPath CLI version to install. Defaults to 23.10.2.6. Versions matching '^23\.' use the classic nupkg extraction path. All other versions use the dotnet tool install path. .PARAMETER ToolBase Root directory for all installed tools. Defaults to %LOCALAPPDATA%\cpmf\tools. #> [CmdletBinding(SupportsShouldProcess)] param( [string]$CliVersion = '23.10.2.6', [string]$ToolBase = (Join-Path $env:LOCALAPPDATA 'cpmf\tools') ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $p = Get-CpmfUipsToolPaths -CliVersion $CliVersion -ToolBase $ToolBase if ($CliVersion -match '^23\.') { # ── Classic path: .NET 6.0.36 (base + WindowsDesktop) + nupkg extraction ── Write-Verbose "[Install] Checking .NET 6.0.36 WindowsDesktop runtime in $($p.DotnetDir)" if (Test-Path $p.DotnetMarker) { Write-Verbose "[Install] .NET 6.0.36 already installed — skipping" } elseif ($PSCmdlet.ShouldProcess($p.DotnetDir, 'Install .NET 6.0.36 (base + WindowsDesktop)')) { Write-Progress -Activity 'CpmfUipsPack: install' -Status 'Downloading .NET 6.0.36 runtime …' Write-Verbose "[Install] Installing .NET 6.0.36 into $($p.DotnetDir) ..." $null = New-Item -ItemType Directory -Path $p.DotnetDir -Force $installScript = Join-Path ([System.IO.Path]::GetTempPath()) 'dotnet-install.ps1' try { Invoke-WebRequest ` -Uri 'https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.ps1' ` -OutFile $installScript ` -UseBasicParsing ` -TimeoutSec 120 Write-Verbose "[Install] Installing base runtime ..." & $installScript -Runtime dotnet -Version 6.0.36 -InstallDir $p.DotnetDir if ($LASTEXITCODE -ne 0) { throw "dotnet-install.ps1 (base) exited with code $LASTEXITCODE" } if (-not (Test-Path (Join-Path $p.DotnetDir 'dotnet.exe'))) { throw "Base runtime install failed — dotnet.exe not found in $($p.DotnetDir)" } Write-Verbose "[Install] Installing WindowsDesktop runtime ..." & $installScript -Runtime windowsdesktop -Version 6.0.36 -InstallDir $p.DotnetDir if ($LASTEXITCODE -ne 0) { throw "dotnet-install.ps1 (windowsdesktop) exited with code $LASTEXITCODE" } if (-not (Test-Path $p.DotnetMarker)) { throw "WindowsDesktop runtime install failed — marker not found: $($p.DotnetMarker)" } } finally { Remove-Item $installScript -Force -ErrorAction SilentlyContinue } # Persist PATH using unexpanded token (portable; stored as REG_EXPAND_SZ) if (Add-ToUserPath $p.DotnetToken) { Write-Verbose "[Install] Added $($p.DotnetToken) to user PATH" } # DOTNET_ROOT stored expanded (REG_SZ — Windows does not expand it automatically) [Environment]::SetEnvironmentVariable('DOTNET_ROOT', $p.DotnetDir, 'User') Write-Verbose "[Install] .NET 6.0.36 installed at $($p.DotnetDir)" } # Ensure current session sees the local runtime $env:DOTNET_ROOT = $p.DotnetDir if ($env:PATH -notlike "*$($p.DotnetDir)*") { $env:PATH = "$($p.DotnetDir);$env:PATH" } # ── Step 1a: uipcli 23.x — nupkg download + ZipFile extraction ── Write-Verbose "[Install] Checking uipcli $CliVersion in $($p.CliToolDir)" if (Test-Path $p.UipcliExe) { Write-Verbose "[Install] uipcli $CliVersion already installed — skipping" return } if (-not $PSCmdlet.ShouldProcess($p.CliToolDir, "Download and extract uipcli $CliVersion")) { return } Write-Progress -Activity 'CpmfUipsPack: install' -Status "Downloading uipcli $CliVersion …" $feedBase = 'https://uipath.pkgs.visualstudio.com/Public.Feeds/_packaging/UiPath-Official/nuget/v3/flat2/uipath.cli.windows' $nupkgUrl = "$feedBase/$CliVersion/uipath.cli.windows.$CliVersion.nupkg" $downloadPath = Join-Path $p.CliToolDir 'uipcli.nupkg' $null = New-Item -ItemType Directory -Path $p.CliToolDir -Force try { Write-Verbose "[Install] Downloading uipcli $CliVersion ..." Invoke-WebRequest -Uri $nupkgUrl -OutFile $downloadPath -UseBasicParsing -TimeoutSec 120 Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory($downloadPath, (Join-Path $p.CliToolDir 'extracted')) if (-not (Test-Path $p.UipcliExe)) { throw "uipcli extraction failed — exe not found at $($p.UipcliExe)" } } catch { Remove-Item $p.CliToolDir -Recurse -Force -ErrorAction SilentlyContinue throw } finally { Remove-Item $downloadPath -Force -ErrorAction SilentlyContinue } Write-Progress -Activity 'CpmfUipsPack: install' -Completed Write-Verbose "[Install] Installed uipcli $CliVersion at $($p.UipcliExe)" } else { # ── dotnet-tool path: minimal .NET 8 SDK + dotnet tool install ── Write-Verbose "[Install] Checking .NET 8 SDK in $($p.DotnetDir)" $dotnetExe = Join-Path $p.DotnetDir 'dotnet.exe' if (Test-Path $dotnetExe) { Write-Verbose "[Install] .NET 8 SDK already installed — skipping" } elseif ($PSCmdlet.ShouldProcess($p.DotnetDir, 'Install .NET 8 SDK (minimal)')) { Write-Verbose "[Install] Installing .NET 8 SDK into $($p.DotnetDir) ..." $null = New-Item -ItemType Directory -Path $p.DotnetDir -Force $installScript = Join-Path ([System.IO.Path]::GetTempPath()) 'dotnet-install-8.ps1' try { Invoke-WebRequest ` -Uri 'https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.ps1' ` -OutFile $installScript ` -UseBasicParsing ` -TimeoutSec 120 # No -Runtime flag = SDK install (includes dotnet CLI for tool commands) & $installScript -Channel 8.0 -InstallDir $p.DotnetDir if ($LASTEXITCODE -ne 0) { throw "dotnet-install.ps1 (.NET 8 SDK) exited with code $LASTEXITCODE" } if (-not (Test-Path $dotnetExe)) { throw ".NET 8 SDK install failed — dotnet.exe not found in $($p.DotnetDir)" } } finally { Remove-Item $installScript -Force -ErrorAction SilentlyContinue } # Persist PATH so the uipcli shim can locate dotnet at runtime if (Add-ToUserPath $p.DotnetToken) { Write-Verbose "[Install] Added $($p.DotnetToken) to user PATH" } Write-Verbose "[Install] .NET 8 SDK installed at $($p.DotnetDir)" } # Ensure current session sees the local .NET 8 SDK if ($env:PATH -notlike "*$($p.DotnetDir)*") { $env:PATH = "$($p.DotnetDir);$env:PATH" } # ── Step 1b: uipcli 25.x+ — dotnet tool install ── Write-Verbose "[Install] Checking uipcli $CliVersion in $($p.CliToolDir)" if (Test-Path $p.UipcliExe) { Write-Verbose "[Install] uipcli $CliVersion already installed — skipping" return } if (-not $PSCmdlet.ShouldProcess($p.CliToolDir, "dotnet tool install UiPath.CLI.Windows $CliVersion")) { return } $null = New-Item -ItemType Directory -Path $p.CliToolDir -Force $feedUrl = 'https://uipath.pkgs.visualstudio.com/Public.Feeds/_packaging/UiPath-Official/nuget/v3/index.json' try { Write-Verbose "[Install] Installing uipcli $CliVersion via dotnet tool ..." & $dotnetExe tool install UiPath.CLI.Windows ` --tool-path $p.CliToolDir ` --version $CliVersion ` --add-source $feedUrl if ($LASTEXITCODE -ne 0) { throw "dotnet tool install UiPath.CLI.Windows $CliVersion failed (exit $LASTEXITCODE)" } if (-not (Test-Path $p.UipcliExe)) { throw "dotnet tool install succeeded but uipcli.exe not found at $($p.UipcliExe)" } } catch { Remove-Item $p.CliToolDir -Recurse -Force -ErrorAction SilentlyContinue throw } Write-Verbose "[Install] Installed uipcli $CliVersion at $($p.UipcliExe)" } } |