Public/WaykAgentPackage.ps1
. "$PSScriptRoot/../Private/PlatformHelpers.ps1" function Get-WaykAgentVersion { [CmdletBinding()] param() if (Get-IsWindows) { $UninstallReg = Get-UninstallRegistryKey 'Wayk Agent' if ($UninstallReg) { $Version = $UninstallReg.DisplayVersion if ($Version -lt 2000) { $Version = "20" + $Version } return $Version } } elseif ($IsMacOS) { $InfoPlistPath = "/Applications/WaykAgent.app/Contents/Info.plist" $CfBundleVersionXpath = "//dict/key[. ='CFBundleVersion']/following-sibling::string[1]" if (Test-Path -Path $InfoPlistPath) { $Version = $(Select-Xml -Path $InfoPlistPath -XPath $CfBundleVersionXpath ` | Foreach-Object {$_.Node.InnerXML }).Trim() return $Version } } elseif ($IsLinux) { $DpkgStatus = $(dpkg -s wayk-agent) $DpkgMatches = $($DpkgStatus | Select-String -AllMatches -Pattern 'Version: (\S+)').Matches if ($DpkgMatches) { $Version = $DpkgMatches.Groups[1].Value return $Version } } return $null } function Get-WaykAgentPackage { [CmdletBinding()] param( [string] $RequiredVersion, [ValidateSet("Windows","macOS","Linux")] [string] $Platform, [ValidateSet("x86","x64")] [string] $Architecture ) $VersionQuad = ''; $ProductsUrl = "https://devolutions.net/products.htm" if ($Env:WAYK_PRODUCT_INFO_URL) { $ProductsUrl = $Env:WAYK_PRODUCT_INFO_URL } $ProductsHtm = Invoke-RestMethod -Uri $ProductsUrl -Method 'GET' -ContentType 'text/plain' $VersionMatches = $($ProductsHtm | Select-String -AllMatches -Pattern "Wayk.Version=(\S+)").Matches $LatestVersion = $VersionMatches.Groups[1].Value if ($RequiredVersion) { if ($RequiredVersion -Match "^\d+`.\d+`.\d+$") { $RequiredVersion = $RequiredVersion + ".0" } $VersionQuad = $RequiredVersion } else { $VersionQuad = $LatestVersion } $VersionMatches = $($VersionQuad | Select-String -AllMatches -Pattern "(\d+)`.(\d+)`.(\d+)`.(\d+)").Matches $VersionMajor = $VersionMatches.Groups[1].Value $VersionMinor = $VersionMatches.Groups[2].Value $VersionPatch = $VersionMatches.Groups[3].Value $VersionTriple = "${VersionMajor}.${VersionMinor}.${VersionPatch}" $WaykMatches = $($ProductsHtm | Select-String -AllMatches -Pattern "(Wayk\S+).Url=(\S+)").Matches $WaykAgentMsi64 = $WaykMatches | Where-Object { $_.Groups[1].Value -eq 'WaykAgentmsi64' } $WaykAgentMsi86 = $WaykMatches | Where-Object { $_.Groups[1].Value -eq 'WaykAgentmsi86' } $WaykAgentMac = $WaykMatches | Where-Object { $_.Groups[1].Value -eq 'WaykAgentMac' } $WaykAgentLinux = $WaykMatches | Where-Object { $_.Groups[1].Value -eq 'WaykAgentLinuxbin' } if ($WaykAgentMsi86) { $DownloadUrlX86 = $WaykAgentMsi86.Groups[2].Value } if ($WaykAgentMsi64) { $DownloadUrlX64 = $WaykAgentMsi64.Groups[2].Value } if ($WaykAgentMac) { $DownloadUrlMac = $WaykAgentMac.Groups[2].Value } if ($WaykAgentLinux) { $DownloadUrlLinux = $WaykAgentLinux.Groups[2].Value } $DownloadUrl = $null if (-Not $Platform) { if ($IsLinux) { $Platform = 'Linux' } elseif ($IsMacOS) { $Platform = 'macOS' } else { $Platform = 'Windows' } } if (-Not $Architecture) { if (Get-IsWindows) { if ([System.Environment]::Is64BitOperatingSystem) { if ((Get-WindowsHostArch) -eq 'ARM64') { $Architecture = 'x86' # Windows on ARM64, use intel 32-bit build } else { $Architecture = 'x64' } } else { $Architecture = 'x86' } } else { $Architecture = 'x64' # default } } if ($Platform -eq 'Windows') { if ($Architecture -eq 'x64') { $DownloadUrl = $DownloadUrlX64 } elseif ($Architecture -eq 'x86') { $DownloadUrl = $DownloadUrlX86 } } elseif ($Platform -eq 'macOS') { $DownloadUrl = $DownloadUrlMac } elseif ($Platform -eq 'Linux') { $DownloadUrl = $DownloadUrlLinux } if ($RequiredVersion) { # both variables are in quadruple Version format $DownloadUrl = $DownloadUrl -Replace $LatestVersion, $RequiredVersion } $result = [PSCustomObject]@{ Url = $DownloadUrl Version = $VersionTriple } return $result } function Install-WaykAgent { [CmdletBinding()] param( [switch] $Force, [switch] $Quiet, [string] $Version, [switch] $NoDesktopShortcut, [switch] $NoStartMenuShortcut ) $TempDirectory = New-TemporaryDirectory $Package = Get-WaykAgentPackage $Version $LatestVersion = $Package.Version $CurrentVersion = Get-WaykAgentVersion if (([Version]$LatestVersion -gt [Version]$CurrentVersion) -Or $Force) { Write-Host "Installing Wayk Agent ${LatestVersion}" } else { Write-Host "Wayk Agent is already up to date" return } $DownloadUrl = $Package.url $DownloadFile = Split-Path -Path $DownloadUrl -Leaf $DownloadFilePath = Join-Path $TempDirectory $DownloadFile Write-Host "Downloading $DownloadUrl" $WebClient = [System.Net.WebClient]::new() $WebClient.DownloadFile($DownloadUrl, $DownloadFilePath) $WebClient.Dispose() $DownloadFilePath = Resolve-Path $DownloadFilePath if (([Version]$CurrentVersion -gt [Version]$LatestVersion) -And $Force) { Uninstall-WaykAgent -Quiet:$Quiet } if (Get-IsWindows) { $Display = '/passive' if ($Quiet){ $Display = '/quiet' } $InstallLogFile = "$TempDirectory/WaykAgent_Install.log" $MsiArgs = @( '/i', "`"$DownloadFilePath`"", $Display, '/norestart', '/log', "`"$InstallLogFile`"" ) if ($NoDesktopShortcut){ $MsiArgs += "INSTALLDESKTOPSHORTCUT=`"`"" } if ($NoStartMenuShortcut){ $MsiArgs += "INSTALLSTARTMENUSHORTCUT=`"`"" } Start-Process "msiexec.exe" -ArgumentList $MsiArgs -Wait -NoNewWindow Remove-Item -Path $InstallLogFile -Force -ErrorAction SilentlyContinue } elseif ($IsMacOS) { $VolumesWaykAgent = "/Volumes/WaykAgent" if (Test-Path -Path $VolumesWaykAgent -PathType 'Container') { Start-Process 'hdiutil' -ArgumentList @('unmount', $VolumesWaykAgent) -Wait } Start-Process 'hdiutil' -ArgumentList @('mount', "$DownloadFilePath") ` -Wait -RedirectStandardOutput '/dev/null' Wait-Process $(Start-Process 'sudo' -ArgumentList @('cp', '-R', ` "${VolumesWaykAgent}/WaykAgent.app", "/Applications") -PassThru).Id Start-Process 'hdiutil' -ArgumentList @('unmount', $VolumesWaykAgent) ` -Wait -RedirectStandardOutput '/dev/null' Wait-Process $(Start-Process 'sudo' -ArgumentList @('ln', '-sfn', ` "/Applications/WaykAgent.app/Contents/MacOS/WaykAgent", "/usr/local/bin/wayk-now") -PassThru).Id } elseif ($IsLinux) { $DpkgArgs = @( '-i', $DownloadFilePath ) if ((id -u) -eq 0) { Start-Process 'dpkg' -ArgumentList $DpkgArgs -Wait } else { $DpkgArgs = @('dpkg') + $DpkgArgs Start-Process 'sudo' -ArgumentList $DpkgArgs -Wait } } Remove-Item -Path $TempDirectory -Force -Recurse } function Uninstall-WaykAgent { [CmdletBinding()] param( [switch] $Quiet ) Stop-WaykAgent if (Get-IsWindows) { # https://stackoverflow.com/a/25546511 $UninstallReg = Get-UninstallRegistryKey 'Wayk Agent' if ($UninstallReg) { $UninstallString = $($UninstallReg.UninstallString ` -Replace "msiexec.exe", "" -Replace "/I", "" -Replace "/X", "").Trim() $Display = '/passive' if ($Quiet){ $Display = '/quiet' } $MsiArgs = @( '/X', $UninstallString, $Display ) Start-Process "msiexec.exe" -ArgumentList $MsiArgs -Wait } } elseif ($IsMacOS) { $WaykAgentApp = "/Applications/WaykAgent.app" if (Test-Path -Path $WaykAgentApp -PathType 'Container') { Start-Process 'sudo' -ArgumentList @('rm', '-rf', $WaykAgentApp) -Wait } $WaykNowSymlink = "/usr/local/bin/wayk-now" if (Test-Path -Path $WaykNowSymlink) { Start-Process 'sudo' -ArgumentList @('rm', $WaykNowSymlink) -Wait } } elseif ($IsLinux) { if (Get-WaykAgentVersion) { $AptArgs = @( '-y', 'remove', 'wayk-agent', '--purge' ) if ((id -u) -eq 0) { Start-Process 'apt-get' -ArgumentList $AptArgs -Wait } else { $AptArgs = @('apt-get') + $AptArgs Start-Process 'sudo' -ArgumentList $AptArgs -Wait } } } } function Update-WaykAgent { [CmdletBinding()] param( [switch] $Force, [switch] $Quiet ) $ProcessWasRunning = Get-WaykAgentProcess $ServiceWasRunning = (Get-WaykAgentService).Status -Eq 'Running' try { Install-WaykAgent -Force:$Force -Quiet:$Quiet } catch { throw $_ } if ($ProcessWasRunning) { Start-WaykAgent } elseif ($ServiceWasRunning) { Start-WaykAgentService } } function Get-WaykAgentPath() { [CmdletBinding()] param( [Parameter(Position=0)] [string] $PathType = "ConfigPath" ) if (Get-IsWindows) { $ConfigPath = $Env:ALLUSERSPROFILE + '\Wayk' } elseif ($IsMacOS) { $ConfigPath = "/Library/Application Support/Wayk" } elseif ($IsLinux) { $ConfigPath = '/etc/wayk' } if (Test-Path Env:WAYK_SYSTEM_PATH) { $ConfigPath = $Env:WAYK_SYSTEM_PATH } switch ($PathType) { 'ConfigPath' { $ConfigPath } default { throw("Invalid path type: $PathType") } } } |