From d8eb06c0f0771d9fcba6f0e5429ccfa3f22ef98a Mon Sep 17 00:00:00 2001 From: David Fowler Date: Fri, 5 Sep 2014 01:10:26 -0700 Subject: [PATCH] Updated kvm to the latest - Added -runtime switch --- build/_k-test.shade | 2 +- build/kvm.ps1 | 774 +++++++++++++++++++++++++------------------- 2 files changed, 447 insertions(+), 329 deletions(-) diff --git a/build/_k-test.shade b/build/_k-test.shade index f231a8468e..60fba460c9 100644 --- a/build/_k-test.shade +++ b/build/_k-test.shade @@ -48,7 +48,7 @@ projectFile='' } else if (!IsMono) { - K("test", projectFolder, "default -svrc50"); + K("test", projectFolder, "default -runtime CoreCLR"); } } } diff --git a/build/kvm.ps1 b/build/kvm.ps1 index 3bc6e82d8d..a2aad0848f 100644 --- a/build/kvm.ps1 +++ b/build/kvm.ps1 @@ -6,20 +6,36 @@ param( [alias("g")][switch] $global = $false, [alias("p")][switch] $persistent = $false, [alias("f")][switch] $force = $false, + [alias("r")][string] $runtime, [switch] $x86 = $false, + [switch] $amd64 = $false, + #deprecated [switch] $x64 = $false, + #deprecated [switch] $svr50 = $false, + #deprecated [switch] $svrc50 = $false, + [alias("w")][switch] $wait = $false, + [alias("a")] + [string] $alias = $null, [parameter(Position=1, ValueFromRemainingArguments=$true)] [string[]]$args=@() ) +$selectedArch=$null; +$defaultArch="x86" +$selectedRuntime=$null +$defaultRuntime="CLR" $userKrePath = $env:USERPROFILE + "\.kre" $userKrePackages = $userKrePath + "\packages" $globalKrePath = $env:ProgramFiles + "\KRE" $globalKrePackages = $globalKrePath + "\packages" $feed = $env:KRE_NUGET_API_URL +function String-IsEmptyOrWhitespace([string]$str) { + return [string]::IsNullOrEmpty($str) -or $str.Trim().length -eq 0 +} + if (!$feed) { $feed = "https://www.myget.org/F/aspnetvnext/api/v2"; @@ -29,11 +45,11 @@ $scriptPath = $myInvocation.MyCommand.Definition function Kvm-Help { @" -K Runtime Environment Version Manager - Build {{BUILD_NUMBER}} +K Runtime Environment Version Manager - Build 10014 USAGE: kvm [options] -kvm upgrade [-x86][-x64] [-svr50][-svrc50] [-g|-global] [-proxy
] +kvm upgrade [-x86][-amd64] [-r|-runtime CLR|CoreCLR] [-g|-global] [-f|-force] [-proxy
] install latest KRE from feed set 'default' alias to installed version add KRE bin to user PATH environment variable @@ -41,137 +57,148 @@ kvm upgrade [-x86][-x64] [-svr50][-svrc50] [-g|-global] [-proxy
] -f|-force upgrade even if latest is already installed -proxy
use given address as proxy when accessing remote server -kvm install || [-x86][-x64] [-svr50][-svrc50] [-g|-global] - install requested KRE from feed +kvm install |||latest [-x86][-amd64] [-r|-runtime CLR|CoreCLR] [-a|-alias ] [-g|-global] [-f|-force] + | install requested KRE from feed + install requested KRE from package on local filesystem + latest install latest KRE from feed add KRE bin to path of current command line + -p|-persistent add KRE bin to PATH environment variables persistently + -a|-alias set alias for requested KRE on install -g|-global install to machine-wide location -f|-force install even if specified version is already installed -kvm use ||none [-x86][-x64] [-svr50][-svrc50] [-p|-persistent] [-g|-global] - | add KRE bin to path of current command line +kvm use ||none [-x86][-amd64] [-r|-runtime CLR|CoreCLR] [-p|-persistent] [-g|-global] + | add KRE bin to path of current command line none remove KRE bin from path of current command line -p|-persistent add KRE bin to PATH environment variables persistently -g|-global combined with -p to change machine PATH instead of user PATH kvm list - list KRE versions installed + list KRE versions installed kvm alias list KRE aliases which have been defined kvm alias - display value of named alias + display value of the specified alias -kvm alias [-x86][-x64] [-svr50][-svrc50] - set alias to specific version +kvm alias | [-x86][-amd64] [-r|-runtime CLR|CoreCLR] + The name of the alias to set + | The KRE version to set the alias to. Alternatively use the version of the specified alias -"@ | Write-Host +kvm unalias + remove the specified alias + +"@ -replace "`n","`r`n" | Write-Host } function Kvm-Global-Setup { - If (Needs-Elevation) - { - $arguments = "& '$scriptPath' setup $(Requested-Switches) -persistent" - Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments -Wait - Write-Host "Setup complete" - Kvm-Help - break - } - - $scriptFolder = [System.IO.Path]::GetDirectoryName($scriptPath) - - $kvmBinPath = "$userKrePath\bin" - - Write-Host "Copying file $kvmBinPath\kvm.ps1" - md $kvmBinPath -Force | Out-Null - copy "$scriptFolder\kvm.ps1" "$kvmBinPath\kvm.ps1" - - Write-Host "Copying file $kvmBinPath\kvm.cmd" - copy "$scriptFolder\kvm.cmd" "$kvmBinPath\kvm.cmd" + $kvmBinPath = "$userKrePath\bin" + If (Needs-Elevation) + { + $arguments = "-ExecutionPolicy unrestricted & '$scriptPath' setup -global -wait" + Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments -Wait Write-Host "Adding $kvmBinPath to process PATH" Set-Path (Change-Path $env:Path $kvmBinPath ($kvmBinPath)) - - Write-Host "Adding $kvmBinPath to user PATH" - $userPath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User) - $userPath = Change-Path $userPath $kvmBinPath ($kvmBinPath) - [Environment]::SetEnvironmentVariable("Path", $userPath, [System.EnvironmentVariableTarget]::User) - Write-Host "Adding $globalKrePath;%USERPROFILE%\.kre to process KRE_HOME" $envKreHome = $env:KRE_HOME $envKreHome = Change-Path $envKreHome "%USERPROFILE%\.kre" ("%USERPROFILE%\.kre") $envKreHome = Change-Path $envKreHome $globalKrePath ($globalKrePath) $env:KRE_HOME = $envKreHome + Write-Host "Setup complete" + break + } - Write-Host "Adding $globalKrePath;%USERPROFILE%\.kre to machine KRE_HOME" - $machineKreHome = [Environment]::GetEnvironmentVariable("KRE_HOME", [System.EnvironmentVariableTarget]::Machine) - $machineKreHome = Change-Path $machineKreHome "%USERPROFILE%\.kre" ("%USERPROFILE%\.kre") - $machineKreHome = Change-Path $machineKreHome $globalKrePath ($globalKrePath) - [Environment]::SetEnvironmentVariable("KRE_HOME", $machineKreHome, [System.EnvironmentVariableTarget]::Machine) + $scriptFolder = [System.IO.Path]::GetDirectoryName($scriptPath) - Write-Host "Press any key to continue ..." - $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,AllowCtrlC") + Write-Host "Copying file $kvmBinPath\kvm.ps1" + md $kvmBinPath -Force | Out-Null + copy "$scriptFolder\kvm.ps1" "$kvmBinPath\kvm.ps1" + + Write-Host "Copying file $kvmBinPath\kvm.cmd" + copy "$scriptFolder\kvm.cmd" "$kvmBinPath\kvm.cmd" + + Write-Host "Adding $kvmBinPath to process PATH" + Set-Path (Change-Path $env:Path $kvmBinPath ($kvmBinPath)) + + Write-Host "Adding $kvmBinPath to user PATH" + $userPath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User) + $userPath = Change-Path $userPath $kvmBinPath ($kvmBinPath) + [Environment]::SetEnvironmentVariable("Path", $userPath, [System.EnvironmentVariableTarget]::User) + + Write-Host "Adding $globalKrePath;%USERPROFILE%\.kre to process KRE_HOME" + $envKreHome = $env:KRE_HOME + $envKreHome = Change-Path $envKreHome "%USERPROFILE%\.kre" ("%USERPROFILE%\.kre") + $envKreHome = Change-Path $envKreHome $globalKrePath ($globalKrePath) + $env:KRE_HOME = $envKreHome + + Write-Host "Adding $globalKrePath;%USERPROFILE%\.kre to machine KRE_HOME" + $machineKreHome = [Environment]::GetEnvironmentVariable("KRE_HOME", [System.EnvironmentVariableTarget]::Machine) + $machineKreHome = Change-Path $machineKreHome "%USERPROFILE%\.kre" ("%USERPROFILE%\.kre") + $machineKreHome = Change-Path $machineKreHome $globalKrePath ($globalKrePath) + [Environment]::SetEnvironmentVariable("KRE_HOME", $machineKreHome, [System.EnvironmentVariableTarget]::Machine) } function Kvm-Global-Upgrade { - $persistent = $true - If (Needs-Elevation) { - $arguments = "& '$scriptPath' upgrade -global $(Requested-Switches)" - Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments -Wait - break - } - $version = Kvm-Find-Latest (Requested-Platform "svr50") (Requested-Architecture "x86") - Kvm-Global-Install $version - Kvm-Alias-Set "default" $version + $persistent = $true + $alias="default" + $versionOrAlias = Kvm-Find-Latest $selectedRuntime $selectedArch + If (Needs-Elevation) { + $arguments = "-ExecutionPolicy unrestricted & '$scriptPath' install '$versionOrAlias' -global $(Requested-Switches) -wait" + Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments -Wait + Kvm-Set-Global-Process-Path $versionOrAlias + break + } + Kvm-Install $versionOrAlias $true } function Kvm-Upgrade { - $persistent = $true - $version = Kvm-Find-Latest (Requested-Platform "svr50") (Requested-Architecture "x86") - Kvm-Install $version - Kvm-Alias-Set "default" $version + $persistent = $true + $alias="default" + Kvm-Install "latest" $false } function Add-Proxy-If-Specified { param( - [System.Net.WebClient] $wc + [System.Net.WebClient] $wc ) - if (!$proxy) { - $proxy = $env:http_proxy - } - if ($proxy) { - $wp = New-Object System.Net.WebProxy($proxy) - $pb = New-Object UriBuilder($proxy) - if (!$pb.UserName) { - $wp.Credentials = [System.Net.CredentialCache]::DefaultCredentials - } else { - $wp.Credentials = New-Object System.Net.NetworkCredential($pb.UserName, $pb.Password) - } - $wc.Proxy = $wp + if (!$proxy) { + $proxy = $env:http_proxy + } + if ($proxy) { + $wp = New-Object System.Net.WebProxy($proxy) + $pb = New-Object UriBuilder($proxy) + if (!$pb.UserName) { + $wp.Credentials = [System.Net.CredentialCache]::DefaultCredentials + } else { + $wp.Credentials = New-Object System.Net.NetworkCredential($pb.UserName, $pb.Password) } + $wc.Proxy = $wp + } } function Kvm-Find-Latest { param( - [string] $platform, - [string] $architecture + [string] $platform, + [string] $architecture ) - Write-Host "Determining latest version" + Write-Host "Determining latest version" - $url = "$feed/GetUpdates()?packageIds=%27KRE-$platform-$architecture%27&versions=%270.0%27&includePrerelease=true&includeAllVersions=false" + $url = "$feed/GetUpdates()?packageIds=%27KRE-$platform-$architecture%27&versions=%270.0%27&includePrerelease=true&includeAllVersions=false" - $wc = New-Object System.Net.WebClient - $wc.Credentials = new-object System.Net.NetworkCredential("aspnetreadonly", "4d8a2d9c-7b80-4162-9978-47e918c9658c") - Add-Proxy-If-Specified($wc) - [xml]$xml = $wc.DownloadString($url) + $wc = New-Object System.Net.WebClient + $wc.Credentials = new-object System.Net.NetworkCredential("aspnetreadonly", "4d8a2d9c-7b80-4162-9978-47e918c9658c") + Add-Proxy-If-Specified($wc) + [xml]$xml = $wc.DownloadString($url) - $version = Select-Xml "//d:Version" -Namespace @{d='http://schemas.microsoft.com/ado/2007/08/dataservices'} $xml + $version = Select-Xml "//d:Version" -Namespace @{d='http://schemas.microsoft.com/ado/2007/08/dataservices'} $xml - return $version -} + if (String-IsEmptyOrWhitespace($version)) { + throw "There are no packages for platform '$platform', architecture '$architecture' in the feed '$feed'" + } -function Kvm-Install-Latest { - Kvm-Install (Kvm-Find-Latest (Requested-Platform "svr50") (Requested-Architecture "x86")) + return $version } function Do-Kvm-Download { @@ -179,44 +206,45 @@ param( [string] $kreFullName, [string] $packagesFolder ) - $parts = $kreFullName.Split(".", 2) + $parts = $kreFullName.Split(".", 2) - $url = "$feed/package/" + $parts[0] + "/" + $parts[1] - $kreFolder = Join-Path $packagesFolder $kreFullName - $kreFile = Join-Path $kreFolder "$kreFullName.nupkg" + $url = "$feed/package/" + $parts[0] + "/" + $parts[1] + $kreFolder = Join-Path $packagesFolder $kreFullName + $kreFile = Join-Path $kreFolder "$kreFullName.nupkg" - If (Test-Path $kreFolder) { - if($force) - { - rm $kreFolder -Recurse -Force - } else { - Write-Host "$kreFullName already installed." - return; - } - } - - Write-Host "Downloading" $kreFullName "from https://www.myget.org/F/aspnetvnext/api/v2/" - - #Downloading to temp location - $kreTempDownload = Join-Path $packagesFolder "temp" - $tempKreFile = Join-Path $kreTempDownload "$kreFullName.nupkg" - - if(Test-Path $kreTempDownload) { - del "$kreTempDownload\*" -recurse + If (Test-Path $kreFolder) { + if($force) + { + rm $kreFolder -Recurse -Force } else { - md $kreTempDownload -Force | Out-Null + Write-Host "$kreFullName already installed." + return; } + } - $wc = New-Object System.Net.WebClient - $wc.Credentials = new-object System.Net.NetworkCredential("aspnetreadonly", "4d8a2d9c-7b80-4162-9978-47e918c9658c") - Add-Proxy-If-Specified($wc) - $wc.DownloadFile($url, $tempKreFile) + Write-Host "Downloading" $kreFullName "from $feed" - Do-Kvm-Unpack $tempKreFile $kreTempDownload + #Downloading to temp location + $kreTempDownload = Join-Path $packagesFolder "temp" + $tempKreFile = Join-Path $kreTempDownload "$kreFullName.nupkg" - md $kreFolder -Force | Out-Null - Write-Host "Installing to $kreFolder" - mv "$kreTempDownload\*" $kreFolder + if(Test-Path $kreTempDownload) { + del "$kreTempDownload\*" -recurse + } else { + md $kreTempDownload -Force | Out-Null + } + + $wc = New-Object System.Net.WebClient + $wc.Credentials = new-object System.Net.NetworkCredential("aspnetreadonly", "4d8a2d9c-7b80-4162-9978-47e918c9658c") + Add-Proxy-If-Specified($wc) + $wc.DownloadFile($url, $tempKreFile) + + Do-Kvm-Unpack $tempKreFile $kreTempDownload + + md $kreFolder -Force | Out-Null + Write-Host "Installing to $kreFolder" + mv "$kreTempDownload\*" $kreFolder + Remove-Item "$kreTempDownload" -Force | Out-Null } function Do-Kvm-Unpack { @@ -224,114 +252,129 @@ param( [string] $kreFile, [string] $kreFolder ) - Write-Host "Unpacking to" $kreFolder - try { - #Shell will not recognize nupkg as a zip and throw, so rename it to zip - $kreZip = [System.IO.Path]::ChangeExtension($kreFile, "zip") - Rename-Item $kreFile $kreZip - #Use the shell to uncompress the nupkg - $shell_app=new-object -com shell.application - $zip_file = $shell_app.namespace($kreZip) - $destination = $shell_app.namespace($kreFolder) - $destination.Copyhere($zip_file.items(), 0x14) #0x4 = don't show UI, 0x10 = overwrite files - } - finally { - #make it a nupkg again - Rename-Item $kreZip $kreFile - } - - If (Test-Path ($kreFolder + "\[Content_Types].xml")) { - Remove-Item ($kreFolder + "\[Content_Types].xml") - } - If (Test-Path ($kreFolder + "\_rels\")) { - Remove-Item ($kreFolder + "\_rels\") -Force -Recurse - } - If (Test-Path ($kreFolder + "\package\")) { - Remove-Item ($kreFolder + "\package\") -Force -Recurse - } -} + Write-Host "Unpacking to" $kreFolder + try { + #Shell will not recognize nupkg as a zip and throw, so rename it to zip + $kreZip = [System.IO.Path]::ChangeExtension($kreFile, "zip") + Rename-Item $kreFile $kreZip + #Use the shell to uncompress the nupkg + $shell_app=new-object -com shell.application + $zip_file = $shell_app.namespace($kreZip) + $destination = $shell_app.namespace($kreFolder) + $destination.Copyhere($zip_file.items(), 0x14) #0x4 = don't show UI, 0x10 = overwrite files + } + finally { + #make it a nupkg again + Rename-Item $kreZip $kreFile + } -function Kvm-Global-Install { -param( - [string] $versionOrAlias -) - If (Needs-Elevation) { - $arguments = "& '$scriptPath' install -global $versionOrAlias $(Requested-Switches)" - Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments -Wait - Kvm-Global-Use $versionOrAlias - break - } - - $kreFullName = Requested-VersionOrAlias $versionOrAlias - - Do-Kvm-Download $kreFullName $globalKrePackages - Kvm-Use $versionOrAlias + If (Test-Path ($kreFolder + "\[Content_Types].xml")) { + Remove-Item ($kreFolder + "\[Content_Types].xml") + } + If (Test-Path ($kreFolder + "\_rels\")) { + Remove-Item ($kreFolder + "\_rels\") -Force -Recurse + } + If (Test-Path ($kreFolder + "\package\")) { + Remove-Item ($kreFolder + "\package\") -Force -Recurse + } } function Kvm-Install { param( - [string] $versionOrAlias + [string] $versionOrAlias, + [boolean] $isGlobal ) - if ($versionOrAlias.EndsWith(".nupkg")) - { - $kreFullName = [System.IO.Path]::GetFileNameWithoutExtension($versionOrAlias) - $kreFolder = "$userKrePackages\$kreFullName" - $folderExists = Test-Path $kreFolder + if ($versionOrAlias -eq "latest") { + $versionOrAlias = Kvm-Find-Latest (Requested-Platform $defaultRuntime) (Requested-Architecture $defaultArch) + } - if($folderExists -and $force) { - del $kreFolder -Recurse -Force - $folderExists = $false; - } - - if($folderExists) { - Write-Host "Target folder '$kreFolder' already exists" - } else { - $tempUnpackFolder = Join-Path $userKrePackages "temp" - $tempKreFile = Join-Path $tempUnpackFolder "$kreFullName.nupkg" - - if(Test-Path $tempUnpackFolder) { - del "$tempUnpackFolder\*" -recurse - } else { - md $tempUnpackFolder -Force | Out-Null - } - copy $versionOrAlias $tempKreFile - - Do-Kvm-Unpack $tempKreFile $tempUnpackFolder - md $kreFolder -Force | Out-Null - Write-Host "Installing to $kreFolder" - mv "$tempUnpackFolder\*" $kreFolder - } + if ($versionOrAlias.EndsWith(".nupkg")) { + $kreFullName = [System.IO.Path]::GetFileNameWithoutExtension($versionOrAlias) + } else { + $kreFullName = Requested-VersionOrAlias $versionOrAlias + } - $kreBin = "$kreFolder\bin" - Write-Host "Adding" $kreBin "to process PATH" - Set-Path (Change-Path $env:Path $kreBin ($globalKrePackages, $userKrePackages)) + if ($isGlobal) { + if (Needs-Elevation) { + $arguments = "-ExecutionPolicy unrestricted & '$scriptPath' install '$versionOrAlias' -global $(Requested-Switches) -wait" + Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments -Wait + Kvm-Set-Global-Process-Path $versionOrAlias + break } - else - { - $kreFullName = Requested-VersionOrAlias $versionOrAlias + $packageFolder = $globalKrePackages + } else { + $packageFolder = $userKrePackages + } - Do-Kvm-Download $kreFullName $userKrePackages - Kvm-Use $versionOrAlias + if ($versionOrAlias.EndsWith(".nupkg")) { + $kreFolder = "$packageFolder\$kreFullName" + $folderExists = Test-Path $kreFolder + + if ($folderExists -and $force) { + del $kreFolder -Recurse -Force + $folderExists = $false; } + + if ($folderExists) { + Write-Host "Target folder '$kreFolder' already exists" + } else { + $tempUnpackFolder = Join-Path $packageFolder "temp" + $tempKreFile = Join-Path $tempUnpackFolder "$kreFullName.nupkg" + + if(Test-Path $tempUnpackFolder) { + del "$tempUnpackFolder\*" -recurse + } else { + md $tempUnpackFolder -Force | Out-Null + } + copy $versionOrAlias $tempKreFile + + Do-Kvm-Unpack $tempKreFile $tempUnpackFolder + md $kreFolder -Force | Out-Null + Write-Host "Installing to $kreFolder" + mv "$tempUnpackFolder\*" $kreFolder + Remove-Item "$tempUnpackFolder" -Force | Out-Null + } + + $packageVersion = Package-Version $kreFullName + Kvm-Use $packageVersion + if (!$(String-IsEmptyOrWhitespace($alias))) { + Kvm-Alias-Set $alias $packageVersion + } + } + else + { + Do-Kvm-Download $kreFullName $packageFolder + Kvm-Use $versionOrAlias + if (!$(String-IsEmptyOrWhitespace($alias))) { + Kvm-Alias-Set "$alias" $versionOrAlias + } + } } function Kvm-List { $kreHome = $env:KRE_HOME if (!$kreHome) { - $kreHome = $env:ProgramFiles + "\KRE;%USERPROFILE%\.kre" + $kreHome = "$globalKrePath;$userKrePath" } + + md ($userKrePath + "\alias\") -Force | Out-Null + $aliases = Get-ChildItem ($userKrePath + "\alias\") | Select @{label='Alias';expression={$_.BaseName}}, @{label='Name';expression={Get-Content $_.FullName }} + $items = @() foreach($portion in $kreHome.Split(';')) { $path = [System.Environment]::ExpandEnvironmentVariables($portion) if (Test-Path("$path\packages")) { - $items += Get-ChildItem ("$path\packages\KRE-*") | List-Parts + $items += Get-ChildItem ("$path\packages\KRE-*") | List-Parts $aliases } } - $items | Sort-Object Version, Runtime, Architecture | Format-Table -AutoSize -Property @{name="Active";expression={$_.Active};alignment="center"}, "Version", "Runtime", "Architecture", "Location" + + $items | Sort-Object Version, Runtime, Architecture, Alias | Format-Table -AutoSize -Property @{name="Active";expression={$_.Active};alignment="center"}, "Version", "Runtime", "Architecture", "Location", "Alias" } filter List-Parts { - $hasBin = Test-Path($_.FullName+"\bin") + param($aliases) + + $hasBin = Test-Path($_.FullName+"\bin") if (!$hasBin) { return } @@ -341,14 +384,26 @@ filter List-Parts { $active = $true } } + + $fullAlias="" + $delim="" + + foreach($alias in $aliases){ + if($_.Name.Split('\', 2).Contains($alias.Name)){ + $fullAlias += $delim + $alias.Alias + $delim = ", " + } + } + $parts1 = $_.Name.Split('.', 2) $parts2 = $parts1[0].Split('-', 3) return New-Object PSObject -Property @{ - Active = if($active){"*"}else{""} + Active = if ($active) { "*" } else { "" } Version = $parts1[1] Runtime = $parts2[1] Architecture = $parts2[2] Location = $_.Parent.FullName + Alias = $fullAlias } } @@ -356,95 +411,114 @@ function Kvm-Global-Use { param( [string] $versionOrAlias ) - If (Needs-Elevation) { - $arguments = "& '$scriptPath' use -global $versionOrAlias $(Requested-Switches)" - if ($persistent) { - $arguments = $arguments + " -persistent" - } - Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments -Wait - break - } + If (Needs-Elevation) { + $arguments = "-ExecutionPolicy unrestricted & '$scriptPath' use '$versionOrAlias' -global $(Requested-Switches) -wait" + Start-Process "$psHome\powershell.exe" -Verb runAs -ArgumentList $arguments -Wait + Kvm-Set-Global-Process-Path $versionOrAlias + break + } - if ($versionOrAlias -eq "none") { - Write-Host "Removing KRE from process PATH" - Set-Path (Change-Path $env:Path "" ($globalKrePackages, $userKrePackages)) - - if ($persistent) { - Write-Host "Removing KRE from machine PATH" - $machinePath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine) - $machinePath = Change-Path $machinePath "" ($globalKrePackages, $userKrePackages) - [Environment]::SetEnvironmentVariable("Path", $machinePath, [System.EnvironmentVariableTarget]::Machine) - } - return; - } - - $kreFullName = Requested-VersionOrAlias $versionOrAlias - - $kreBin = Locate-KreBinFromFullName $kreFullName - if ($kreBin -eq $null) { - Write-Host "Cannot find $kreFullName, do you need to run 'kvm install $versionOrAlias'?" - return - } - - Write-Host "Adding" $kreBin "to process PATH" - Set-Path (Change-Path $env:Path $kreBin ($globalKrePackages, $userKrePackages)) + Kvm-Set-Global-Process-Path "$versionOrAlias" + if ($versionOrAlias -eq "none") { if ($persistent) { - Write-Host "Adding $kreBin to machine PATH" - $machinePath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine) - $machinePath = Change-Path $machinePath $kreBin ($globalKrePackages, $userKrePackages) - [Environment]::SetEnvironmentVariable("Path", $machinePath, [System.EnvironmentVariableTarget]::Machine) + Write-Host "Removing KRE from machine PATH" + $machinePath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine) + $machinePath = Change-Path $machinePath "" ($globalKrePackages, $userKrePackages) + [Environment]::SetEnvironmentVariable("Path", $machinePath, [System.EnvironmentVariableTarget]::Machine) } + return; + } + + $kreFullName = Requested-VersionOrAlias "$versionOrAlias" + $kreBin = Locate-KreBinFromFullName $kreFullName + if ($kreBin -eq $null) { + Write-Host "Cannot find $kreFullName, do you need to run 'kvm install $versionOrAlias'?" + return + } + + if ($persistent) { + Write-Host "Adding $kreBin to machine PATH" + $machinePath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::Machine) + $machinePath = Change-Path $machinePath $kreBin ($globalKrePackages, $userKrePackages) + [Environment]::SetEnvironmentVariable("Path", $machinePath, [System.EnvironmentVariableTarget]::Machine) + } +} + +function Kvm-Set-Global-Process-Path { +param( + [string] $versionOrAlias +) + if ($versionOrAlias -eq "none") { + Write-Host "Removing KRE from process PATH" + Set-Path (Change-Path $env:Path "" ($globalKrePackages, $userKrePackages)) + return + } + + $kreFullName = Requested-VersionOrAlias $versionOrAlias + $kreBin = Locate-KreBinFromFullName $kreFullName + if ($kreBin -eq $null) { + Write-Host "Cannot find $kreFullName, do you need to run 'kvm install $versionOrAlias'?" + return + } + + Write-Host "Adding" $kreBin "to process PATH" + Set-Path (Change-Path $env:Path $kreBin ($globalKrePackages, $userKrePackages)) } function Kvm-Use { param( [string] $versionOrAlias ) - if ($versionOrAlias -eq "none") { - Write-Host "Removing KRE from process PATH" - Set-Path (Change-Path $env:Path "" ($globalKrePackages, $userKrePackages)) + if ($versionOrAlias -eq "none") { + Write-Host "Removing KRE from process PATH" + Set-Path (Change-Path $env:Path "" ($globalKrePackages, $userKrePackages)) - if ($persistent) { - Write-Host "Removing KRE from user PATH" - $userPath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User) - $userPath = Change-Path $userPath "" ($globalKrePackages, $userKrePackages) - [Environment]::SetEnvironmentVariable("Path", $userPath, [System.EnvironmentVariableTarget]::User) - } - return; + if ($persistent) { + Write-Host "Removing KRE from user PATH" + $userPath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User) + $userPath = Change-Path $userPath "" ($globalKrePackages, $userKrePackages) + [Environment]::SetEnvironmentVariable("Path", $userPath, [System.EnvironmentVariableTarget]::User) } + return; + } - $kreFullName = Requested-VersionOrAlias $versionOrAlias + $kreFullName = Requested-VersionOrAlias $versionOrAlias - $kreBin = Locate-KreBinFromFullName $kreFullName - if ($kreBin -eq $null) { - Write-Host "Cannot find $kreFullName, do you need to run 'kvm install $versionOrAlias'?" - return - } + $kreBin = Locate-KreBinFromFullName $kreFullName + if ($kreBin -eq $null) { + Write-Host "Cannot find $kreFullName, do you need to run 'kvm install $versionOrAlias'?" + return + } - Write-Host "Adding" $kreBin "to process PATH" - Set-Path (Change-Path $env:Path $kreBin ($globalKrePackages, $userKrePackages)) + Write-Host "Adding" $kreBin "to process PATH" + Set-Path (Change-Path $env:Path $kreBin ($globalKrePackages, $userKrePackages)) - if ($persistent) { - Write-Host "Adding $kreBin to user PATH" - $userPath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User) - $userPath = Change-Path $userPath $kreBin ($globalKrePackages, $userKrePackages) - [Environment]::SetEnvironmentVariable("Path", $userPath, [System.EnvironmentVariableTarget]::User) - } + if ($persistent) { + Write-Host "Adding $kreBin to user PATH" + $userPath = [Environment]::GetEnvironmentVariable("Path", [System.EnvironmentVariableTarget]::User) + $userPath = Change-Path $userPath $kreBin ($globalKrePackages, $userKrePackages) + [Environment]::SetEnvironmentVariable("Path", $userPath, [System.EnvironmentVariableTarget]::User) + } } function Kvm-Alias-List { - md ($userKrePath + "\alias\") -Force | Out-Null + md ($userKrePath + "\alias\") -Force | Out-Null - Get-ChildItem ($userKrePath + "\alias\") | Select @{label='Alias';expression={$_.BaseName}}, @{label='Name';expression={Get-Content $_.FullName }} | Format-Table -AutoSize + Get-ChildItem ($userKrePath + "\alias\") | Select @{label='Alias';expression={$_.BaseName}}, @{label='Name';expression={Get-Content $_.FullName }} | Format-Table -AutoSize } function Kvm-Alias-Get { param( [string] $name ) - md ($userKrePath + "\alias\") -Force | Out-Null + md ($userKrePath + "\alias\") -Force | Out-Null + $aliasFilePath=$userKrePath + "\alias\" + $name + ".txt" + if (!(Test-Path $aliasFilePath)) { + Write-Host "Alias '$name' does not exist" + } else { Write-Host "Alias '$name' is set to" (Get-Content ($userKrePath + "\alias\" + $name + ".txt")) + } } function Kvm-Alias-Set { @@ -452,11 +526,25 @@ param( [string] $name, [string] $value ) - $kreFullName = "KRE-" + (Requested-Platform "svr50") + "-" + (Requested-Architecture "x86") + "." + $value + $kreFullName = Requested-VersionOrAlias $value + $aliasFilePath = $userKrePath + "\alias\" + $name + ".txt" + $action = if (Test-Path $aliasFilePath) { "Updating" } else { "Setting" } + Write-Host "$action alias '$name' to '$kreFullName'" + md ($userKrePath + "\alias\") -Force | Out-Null + $kreFullName | Out-File ($aliasFilePath) ascii +} - Write-Host "Setting alias '$name' to '$kreFullName'" - md ($userKrePath + "\alias\") -Force | Out-Null - $kreFullName | Out-File ($userKrePath + "\alias\" + $name + ".txt") ascii +function Kvm-Unalias { +param( + [string] $name +) + $aliasPath=$userKrePath + "\alias\" + $name + ".txt" + if (Test-Path -literalPath "$aliasPath") { + Write-Host "Removing alias $name" + Remove-Item -literalPath $aliasPath + } else { + Write-Host "Cannot remove alias, '$name' is not a valid alias name" + } } function Locate-KreBinFromFullName() { @@ -465,7 +553,7 @@ param( ) $kreHome = $env:KRE_HOME if (!$kreHome) { - $kreHome = $env:ProgramFiles + ";%USERPROFILE%\.kre" + $kreHome = "$globalKrePath;$userKrePath" } foreach($portion in $kreHome.Split(';')) { $path = [System.Environment]::ExpandEnvironmentVariables($portion) @@ -477,55 +565,46 @@ param( return $null } +function Package-Version() { +param( + [string] $kreFullName +) + return $kreFullName -replace '[^.]*.(.*)', '$1' +} + function Requested-VersionOrAlias() { param( [string] $versionOrAlias ) - If (Test-Path ($userKrePath + "\alias\" + $versionOrAlias + ".txt")) { - $aliasValue = Get-Content ($userKrePath + "\alias\" + $versionOrAlias + ".txt") - $parts = $aliasValue.Split('.', 2) - $pkgVersion = $parts[1] - $parts =$parts[0].Split('-', 3) - $pkgPlatform = Requested-Platform $parts[1] - $pkgArchitecture = Requested-Architecture $parts[2] - } else { - $pkgVersion = $versionOrAlias - $pkgPlatform = Requested-Platform "svr50" - $pkgArchitecture = Requested-Architecture "x86" - } - return "KRE-" + $pkgPlatform + "-" + $pkgArchitecture + "." + $pkgVersion + If (Test-Path ($userKrePath + "\alias\" + $versionOrAlias + ".txt")) { + $aliasValue = Get-Content ($userKrePath + "\alias\" + $versionOrAlias + ".txt") + $parts = $aliasValue.Split('.', 2) + $pkgVersion = $parts[1] + $parts =$parts[0].Split('-', 3) + $pkgPlatform = Requested-Platform $parts[1] + $pkgArchitecture = Requested-Architecture $parts[2] + } else { + $pkgVersion = $versionOrAlias + $pkgPlatform = Requested-Platform $defaultRuntime + $pkgArchitecture = Requested-Architecture $defaultArch + } + return "KRE-" + $pkgPlatform + "-" + $pkgArchitecture + "." + $pkgVersion } function Requested-Platform() { param( [string] $default ) - if ($svr50 -and $svrc50) { - Throw "This command cannot accept both -svr50 and -svrc50" - } - if ($svr50) { - return "svr50" - } - if ($svrc50) { - return "svrc50" - } - return $default + if (!(String-IsEmptyOrWhitespace($selectedRuntime))) {return $selectedRuntime} + return $default } function Requested-Architecture() { param( [string] $default ) - if ($x86 -and $x64) { - Throw "This command cannot accept both -x86 and -x64" - } - if ($x86) { - return "x86" - } - if ($x64) { - return "x64" - } - return $default + if (!(String-IsEmptyOrWhitespace($selectedArch))) {return $selectedArch} + return $default } function Change-Path() { @@ -534,19 +613,19 @@ param( [string] $prependPath, [string[]] $removePaths ) - $newPath = $prependPath - foreach($portion in $existingPaths.Split(';')) { - $skip = $portion -eq "" - foreach($removePath in $removePaths) { - if ($portion.StartsWith($removePath)) { - $skip = $true - } - } - if (!$skip) { - $newPath = $newPath + ";" + $portion + $newPath = $prependPath + foreach($portion in $existingPaths.Split(';')) { + $skip = $portion -eq "" + foreach($removePath in $removePaths) { + if ($portion.StartsWith($removePath)) { + $skip = $true } } - return $newPath + if (!$skip) { + $newPath = $newPath + ";" + $portion + } + } + return $newPath } function Set-Path() { @@ -561,48 +640,87 @@ SET "PATH=$newPath" } function Needs-Elevation() { - $user = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() - $elevated = $user.IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") - return -NOT $elevated + $user = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() + $elevated = $user.IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") + return -NOT $elevated } function Requested-Switches() { $arguments = "" if ($x86) {$arguments = "$arguments -x86"} + if ($amd64) {$arguments = "$arguments -amd64"} + #deprecated if ($x64) {$arguments = "$arguments -x64"} - if ($svr50) {$arguments = "$arguments -svr50"} - if ($svrc50) {$arguments = "$arguments -svrc50"} + if ($selectedRuntime) {$arguments = "$arguments -runtime $selectedRuntime"} + if ($persistent) {$arguments = "$arguments -persistent"} + if ($force) {$arguments = "$arguments -force"} + if (!$(String-IsEmptyOrWhitespace($alias))) {$arguments = "$arguments -alias '$alias'"} return $arguments } - try { - if ($global) { +function Validate-And-Santitise-Switches() +{ + if ($svr50 -and $runtime) {throw "You cannot select both the -runtime switch and the -svr50 runtimes"} + if ($svrc50 -and $runtime) {throw "You cannot select both the -runtime switch and the -svrc50 runtimes"} + if ($x86 -and $amd64) {throw "You cannot select both x86 and amd64 architectures"} + if ($x86 -and $x64) {throw "You cannot select both x86 and x64 architectures"} + if ($x64 -and $amd64) {throw "You cannot select both x64 and amd64 architectures"} + + if ($runtime) { + $validRuntimes = "CoreCLR", "CLR", "svr50", "svrc50" + $match = $validRuntimes | ? { $_ -like $runtime } | Select -First 1 + if (!$match) {throw "'$runtime' is not a valid runtime"} + Set-Variable -Name "selectedRuntime" -Value $match -Scope Script + } elseif ($svr50) { + Write-Host "Warning: -svr50 is deprecated, use -runtime CLR for new packages." + Set-Variable -Name "selectedRuntime" -Value "svr50" -Scope Script + } elseif ($svrc50) { + Write-Host "Warning: -svrc50 is deprecated, use -runtime CoreCLR for new packages." + Set-Variable -Name "selectedRuntime" -Value "svrc50" -Scope Script + } + + if ($x64) { + Write-Host "Warning: -x64 is deprecated, use -amd64 for new packages." + Set-Variable -Name "selectedArch" -Value "x64" -Scope Script + } elseif ($amd64) { + Set-Variable -Name "selectedArch" -Value "amd64" -Scope Script + } elseif ($x86) { + Set-Variable -Name "selectedArch" -Value "x86" -Scope Script + } +} + +try { + Validate-And-Santitise-Switches + if ($global) { switch -wildcard ($command + " " + $args.Count) { "setup 0" {Kvm-Global-Setup} "upgrade 0" {Kvm-Global-Upgrade} -# "install 0" {Kvm-Global-Install-Latest} - "install 1" {Kvm-Global-Install $args[0]} -# "list 0" {Kvm-Global-List} + "install 1" {Kvm-Install $args[0] $true} "use 1" {Kvm-Global-Use $args[0]} - default {Write-Host 'Unknown command, or global switch not supported'; Kvm-Help;} + default {throw "Unknown command, or global switch not supported"}; } - } else { + } else { switch -wildcard ($command + " " + $args.Count) { "setup 0" {Kvm-Global-Setup} "upgrade 0" {Kvm-Upgrade} -# "install 0" {Kvm-Install-Latest} - "install 1" {Kvm-Install $args[0]} + "install 1" {Kvm-Install $args[0] $false} "list 0" {Kvm-List} "use 1" {Kvm-Use $args[0]} "alias 0" {Kvm-Alias-List} "alias 1" {Kvm-Alias-Get $args[0]} "alias 2" {Kvm-Alias-Set $args[0] $args[1]} - "help 0" {Kvm-Help} - " 0" {Kvm-Help} - default {Write-Host 'Unknown command'; Kvm-Help;} + "unalias 1" {Kvm-Unalias $args[0]} + "help 0" {Kvm-Help} + " 0" {Kvm-Help} + default {throw "Unknown command"}; } - } - } - catch { - Write-Host $_ -ForegroundColor Red ; } +} +catch { + Write-Host $_ -ForegroundColor Red ; + Write-Host "Type 'kvm help' for help on how to use kvm." +} +if ($wait) { + Write-Host "Press any key to continue ..." + $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,AllowCtrlC") +}