2016-04-07 10:32:52 -07:00
#
# Copyright (c) .NET Foundation and contributors. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
#
<#
. SYNOPSIS
Installs dotnet cli
. DESCRIPTION
Installs dotnet cli . If dotnet installation already exists in the given directory
it will update it only if the requested version differs from the one already installed .
. PARAMETER Channel
2017-06-09 12:00:29 -07:00
Default : LTS
2017-06-13 16:45:29 -07:00
Download from the Channel specified . Possible values :
- Current - most current release
- LTS - most current supported release
- 2 -part version in a format A . B - represents a specific release
examples : 2.0 ; 1.0
- Branch name
examples : release / 2.0 . 0 ; Master
2016-04-07 10:32:52 -07:00
. PARAMETER Version
Default : latest
Represents a build version on specific channel . Possible values :
- latest - most latest build on specific channel
2017-06-13 16:45:29 -07:00
- coherent - most latest coherent build on specific channel
coherent applies only to SDK downloads
2017-05-22 12:53:52 -07:00
- 3 -part version in a format A . B . C - represents specific version of build
2017-06-13 16:45:29 -07:00
examples : 2.0 . 0 -preview2 - 006120 ; 1.1 . 0
2016-04-07 10:32:52 -07:00
. PARAMETER InstallDir
Default : % LocalAppData % \ Microsoft \ dotnet
Path to where to install dotnet . Note that binaries will be placed directly in a given directory .
. PARAMETER Architecture
Default : < auto > - this value represents currently running OS architecture
Architecture of dotnet binaries to be installed .
Possible values are : < auto > , x64 and x86
2016-05-27 12:19:53 -07:00
. PARAMETER SharedRuntime
2018-01-05 09:24:10 -08:00
This parameter is obsolete and may be removed in a future version of this script .
The recommended alternative is '-Runtime dotnet' .
2016-05-27 12:19:53 -07:00
Default : false
2018-01-05 09:24:10 -08:00
Installs just the shared runtime bits , not the entire SDK .
This is equivalent to specifying `- Runtime dotnet ` .
. PARAMETER Runtime
Installs just a shared runtime , not the entire SDK .
Possible values :
2018-02-14 11:50:14 -08:00
- dotnet - the Microsoft . NETCore . App shared runtime
- aspnetcore - the Microsoft . AspNetCore . App shared runtime
2016-04-07 10:32:52 -07:00
. PARAMETER DryRun
If set it will not perform installation but instead display what command line to use to consistently install
currently requested version of dotnet cli . In example if you specify version 'latest' it will display a link
with specific version so that this command can be used deterministicly in a build script .
It also displays binaries location if you prefer to install or download it yourself .
. PARAMETER NoPath
By default this script will set environment variable PATH for the current process to the binaries folder inside installation folder .
If set it will display binaries location but not set any environment variable .
. PARAMETER Verbose
Displays diagnostics information .
. PARAMETER AzureFeed
2016-07-15 15:36:01 -04:00
Default : https : / / dotnetcli . azureedge . net / dotnet
2017-05-22 12:53:52 -07:00
This parameter typically is not changed by the user .
2017-11-28 10:11:22 -08:00
It allows changing the URL for the Azure feed used by this installer .
2017-05-22 12:53:52 -07:00
. PARAMETER UncachedFeed
This parameter typically is not changed by the user .
2017-11-28 10:11:22 -08:00
It allows changing the URL for the Uncached feed used by this installer .
. PARAMETER FeedCredential
Used as a query string to append to the Azure feed .
It allows changing the URL to use non-public blob storage accounts .
2016-10-10 17:49:28 +01:00
. PARAMETER ProxyAddress
2016-10-08 20:10:56 +01:00
If set , the installer will use the proxy when making web requests
2017-02-28 08:02:51 +01:00
. PARAMETER ProxyUseDefaultCredentials
Default : false
Use default credentials , when using proxy address .
2017-08-24 14:06:38 -07:00
. PARAMETER SkipNonVersionedFiles
Default : false
Skips installing non-versioned files if they already exist , such as dotnet . exe .
2016-04-07 10:32:52 -07:00
#>
[ cmdletbinding ( ) ]
param (
2017-06-09 12:00:29 -07:00
[ string ] $Channel = " LTS " ,
2016-04-07 10:32:52 -07:00
[ string ] $Version = " Latest " ,
[ string ] $InstallDir = " <auto> " ,
[ string ] $Architecture = " <auto> " ,
2018-01-05 09:24:10 -08:00
[ ValidateSet ( " dotnet " , " aspnetcore " , IgnoreCase = $false ) ]
[ string ] $Runtime ,
[ Obsolete ( " This parameter may be removed in a future version of this script. The recommended alternative is '-Runtime dotnet'. " ) ]
2016-05-27 12:19:53 -07:00
[ switch ] $SharedRuntime ,
2016-04-07 10:32:52 -07:00
[ switch ] $DryRun ,
[ switch ] $NoPath ,
2016-08-09 08:28:53 -05:00
[ string ] $AzureFeed = " https://dotnetcli.azureedge.net/dotnet " ,
2016-10-08 20:10:56 +01:00
[ string ] $UncachedFeed = " https://dotnetcli.blob.core.windows.net/dotnet " ,
2017-11-28 10:11:22 -08:00
[ string ] $FeedCredential ,
2017-02-28 08:02:51 +01:00
[ string ] $ProxyAddress ,
2017-08-24 14:06:38 -07:00
[ switch ] $ProxyUseDefaultCredentials ,
[ switch ] $SkipNonVersionedFiles
2016-04-07 10:32:52 -07:00
)
Set-StrictMode -Version Latest
$ErrorActionPreference = " Stop "
$ProgressPreference = " SilentlyContinue "
$BinFolderRelativePath = " "
2018-01-05 09:24:10 -08:00
if ( $SharedRuntime -and ( -not $Runtime ) ) {
$Runtime = " dotnet "
}
2016-04-07 10:32:52 -07:00
# example path with regex: shared/1.0.0-beta-12345/somepath
$VersionRegEx = " /\d+\.\d+[^/]+/ "
2017-08-24 14:06:38 -07:00
$OverrideNonVersionedFiles = ! $SkipNonVersionedFiles
2016-04-07 10:32:52 -07:00
function Say($str ) {
2017-06-21 16:20:51 -07:00
Write-Host " dotnet-install: $str "
2016-04-07 10:32:52 -07:00
}
function Say-Verbose($str ) {
Write-Verbose " dotnet-install: $str "
}
function Say-Invocation($Invocation ) {
$command = $Invocation . MyCommand ;
$args = ( ( $Invocation . BoundParameters . Keys | foreach { " - $_ `" $( $Invocation . BoundParameters [ $_ ] ) `" " } ) -join " " )
Say-Verbose " $command $args "
}
2017-05-26 15:46:56 -07:00
function Invoke-With-Retry([ScriptBlock]$ScriptBlock , [ int ] $MaxAttempts = 3 , [ int ] $SecondsBetweenAttempts = 1 ) {
$Attempts = 0
while ( $true ) {
try {
return $ScriptBlock . Invoke ( )
}
catch {
$Attempts + +
if ( $Attempts -lt $MaxAttempts ) {
Start-Sleep $SecondsBetweenAttempts
}
else {
throw
}
}
}
}
2016-04-07 10:32:52 -07:00
function Get-Machine-Architecture ( ) {
Say-Invocation $MyInvocation
# possible values: AMD64, IA64, x86
return $ENV:PROCESSOR_ARCHITECTURE
}
# TODO: Architecture and CLIArchitecture should be unified
function Get-CLIArchitecture-From-Architecture([string]$Architecture ) {
Say-Invocation $MyInvocation
switch ( $Architecture . ToLower ( ) ) {
{ $_ -eq " <auto> " } { return Get-CLIArchitecture -From -Architecture $ ( Get-Machine -Architecture ) }
{ ( $_ -eq " amd64 " ) -or ( $_ -eq " x64 " ) } { return " x64 " }
{ $_ -eq " x86 " } { return " x86 " }
default { throw " Architecture not supported. If you think this is a bug, please report it at https://github.com/dotnet/cli/issues " }
}
}
function Get-Version-Info-From-Version-Text([string]$VersionText ) {
Say-Invocation $MyInvocation
$Data = @ ( $VersionText . Split ( [ char[] ] @ ( ) , [ StringSplitOptions ] :: RemoveEmptyEntries ) ) ;
$VersionInfo = @ { }
$VersionInfo . CommitHash = $Data [ 0 ] . Trim ( )
$VersionInfo . Version = $Data [ 1 ] . Trim ( )
return $VersionInfo
}
2016-08-08 15:03:36 -05:00
function Load-Assembly([string ] $Assembly ) {
try {
Add-Type -Assembly $Assembly | Out-Null
}
catch {
# On Nano Server, Powershell Core Edition is used. Add-Type is unable to resolve base class assemblies because they are not GAC'd.
# Loading the base class assemblies is not unnecessary as the types will automatically get resolved.
}
}
2016-08-25 11:41:24 -05:00
function GetHTTPResponse([Uri ] $Uri )
{
2017-05-26 15:46:56 -07:00
Invoke-With -Retry (
{
2016-04-07 10:32:52 -07:00
2017-05-26 15:46:56 -07:00
$HttpClient = $null
try {
# HttpClient is used vs Invoke-WebRequest in order to support Nano Server which doesn't support the Invoke-WebRequest cmdlet.
Load-Assembly -Assembly System . Net . Http
2017-09-22 11:25:15 -07:00
if ( -not $ProxyAddress ) {
2017-09-18 11:54:20 -07:00
try {
# Despite no proxy being explicitly specified, we may still be behind a default proxy
$DefaultProxy = [ System.Net.WebRequest ] :: DefaultWebProxy ;
if ( $DefaultProxy -and ( -not $DefaultProxy . IsBypassed ( $Uri ) ) ) {
2017-09-18 13:05:43 -07:00
$ProxyAddress = $DefaultProxy . GetProxy ( $Uri ) . OriginalString
2017-09-18 11:54:20 -07:00
$ProxyUseDefaultCredentials = $true
}
} catch {
# Eat the exception and move forward as the above code is an attempt
# at resolving the DefaultProxy that may not have been a problem.
2017-09-18 13:05:43 -07:00
$ProxyAddress = $null
2017-09-18 11:54:20 -07:00
Say-Verbose ( " Exception ignored: $_ .Exception.Message - moving forward... " )
}
2017-09-18 13:05:43 -07:00
}
if ( $ProxyAddress ) {
$HttpClientHandler = New-Object System . Net . Http . HttpClientHandler
$HttpClientHandler . Proxy = New-Object System . Net . WebProxy -Property @ { Address = $ProxyAddress ; UseDefaultCredentials = $ProxyUseDefaultCredentials }
$HttpClient = New-Object System . Net . Http . HttpClient -ArgumentList $HttpClientHandler
}
else {
2017-09-18 11:54:20 -07:00
2017-05-26 15:46:56 -07:00
$HttpClient = New-Object System . Net . Http . HttpClient
}
# Default timeout for HttpClient is 100s. For a 50 MB download this assumes 500 KB/s average, any less will time out
# 10 minutes allows it to work over much slower connections.
$HttpClient . Timeout = New-TimeSpan -Minutes 10
2017-11-28 14:23:30 -08:00
$Response = $HttpClient . GetAsync ( " ${Uri} ${FeedCredential} " ) . Result
2017-09-18 11:54:20 -07:00
if ( ( $Response -eq $null ) -or ( -not ( $Response . IsSuccessStatusCode ) ) ) {
2017-11-28 14:23:30 -08:00
# The feed credential is potentially sensitive info. Do not log FeedCredential to console output.
2017-05-26 15:46:56 -07:00
$ErrorMsg = " Failed to download $Uri . "
2017-09-18 11:54:20 -07:00
if ( $Response -ne $null ) {
2017-05-26 15:46:56 -07:00
$ErrorMsg + = " $Response "
}
throw $ErrorMsg
2016-08-25 11:41:24 -05:00
}
2016-08-04 14:55:40 -05:00
2017-05-26 15:46:56 -07:00
return $Response
2016-08-04 14:55:40 -05:00
}
2017-05-26 15:46:56 -07:00
finally {
if ( $HttpClient -ne $null ) {
$HttpClient . Dispose ( )
}
2016-08-04 14:55:40 -05:00
}
2017-06-21 16:20:51 -07:00
} )
2016-08-25 11:41:24 -05:00
}
2017-06-13 16:45:29 -07:00
function Get-Latest-Version-Info([string]$AzureFeed , [ string ] $Channel , [ bool ] $Coherent ) {
2016-08-25 11:41:24 -05:00
Say-Invocation $MyInvocation
$VersionFileUrl = $null
2018-01-05 09:24:10 -08:00
if ( $Runtime -eq " dotnet " ) {
2017-05-22 12:53:52 -07:00
$VersionFileUrl = " $UncachedFeed /Runtime/ $Channel /latest.version "
2016-08-25 11:41:24 -05:00
}
2018-02-14 11:50:14 -08:00
elseif ( $Runtime -eq " aspnetcore " ) {
$VersionFileUrl = " $UncachedFeed /aspnetcore/Runtime/ $Channel /latest.version "
2018-01-05 09:24:10 -08:00
}
2018-02-14 11:50:14 -08:00
elseif ( -not $Runtime ) {
2017-06-13 16:45:29 -07:00
if ( $Coherent ) {
$VersionFileUrl = " $UncachedFeed /Sdk/ $Channel /latest.coherent.version "
}
else {
$VersionFileUrl = " $UncachedFeed /Sdk/ $Channel /latest.version "
}
2016-08-25 11:41:24 -05:00
}
2018-02-14 11:50:14 -08:00
else {
throw " Invalid value for `$ Runtime "
}
2017-06-21 16:20:51 -07:00
2016-08-25 11:41:24 -05:00
$Response = GetHTTPResponse -Uri $VersionFileUrl
$StringContent = $Response . Content . ReadAsStringAsync ( ) . Result
switch ( $Response . Content . Headers . ContentType ) {
2017-08-14 17:57:16 -07:00
{ ( $_ -eq " application/octet-stream " ) } { $VersionText = $StringContent }
2016-08-25 11:41:24 -05:00
{ ( $_ -eq " text/plain " ) } { $VersionText = $StringContent }
2017-05-23 16:41:46 -07:00
{ ( $_ -eq " text/plain; charset=UTF-8 " ) } { $VersionText = $StringContent }
2016-08-25 11:41:24 -05:00
default { throw " `` $Response .Content.Headers.ContentType `` is an unknown .version file content type. " }
}
2016-04-07 10:32:52 -07:00
$VersionInfo = Get-Version -Info -From -Version -Text $VersionText
return $VersionInfo
}
2017-05-23 16:41:46 -07:00
function Get-Specific-Version-From-Version([string]$AzureFeed , [ string ] $Channel , [ string ] $Version ) {
2016-04-07 10:32:52 -07:00
Say-Invocation $MyInvocation
switch ( $Version . ToLower ( ) ) {
{ $_ -eq " latest " } {
2017-06-13 16:45:29 -07:00
$LatestVersionInfo = Get-Latest -Version -Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $False
return $LatestVersionInfo . Version
}
{ $_ -eq " coherent " } {
$LatestVersionInfo = Get-Latest -Version -Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $True
2016-04-07 10:32:52 -07:00
return $LatestVersionInfo . Version
}
default { return $Version }
}
}
2017-08-31 13:18:42 -07:00
function Get-Download-Link([string]$AzureFeed , [ string ] $SpecificVersion , [ string ] $CLIArchitecture ) {
2016-04-07 10:32:52 -07:00
Say-Invocation $MyInvocation
2017-06-21 16:20:51 -07:00
2018-02-14 11:50:14 -08:00
if ( $Runtime -eq " dotnet " ) {
$PayloadURL = " $AzureFeed /Runtime/ $SpecificVersion /dotnet-runtime- $SpecificVersion -win- $CLIArchitecture .zip "
2017-05-26 15:46:56 -07:00
}
2018-02-14 11:50:14 -08:00
elseif ( $Runtime -eq " aspnetcore " ) {
$PayloadURL = " $AzureFeed /aspnetcore/Runtime/ $SpecificVersion /aspnetcore-runtime- $SpecificVersion -win- $CLIArchitecture .zip "
}
elseif ( -not $Runtime ) {
2017-06-07 10:18:05 -07:00
$PayloadURL = " $AzureFeed /Sdk/ $SpecificVersion /dotnet-sdk- $SpecificVersion -win- $CLIArchitecture .zip "
2017-05-26 15:46:56 -07:00
}
2018-02-14 11:50:14 -08:00
else {
throw " Invalid value for `$ Runtime "
}
2017-05-26 15:46:56 -07:00
Say-Verbose " Constructed primary payload URL: $PayloadURL "
return $PayloadURL
}
2017-08-31 13:18:42 -07:00
function Get-LegacyDownload-Link([string]$AzureFeed , [ string ] $SpecificVersion , [ string ] $CLIArchitecture ) {
2017-05-26 15:46:56 -07:00
Say-Invocation $MyInvocation
2017-06-21 16:20:51 -07:00
2018-01-05 09:24:10 -08:00
if ( -not $Runtime ) {
$PayloadURL = " $AzureFeed /Sdk/ $SpecificVersion /dotnet-dev-win- $CLIArchitecture . $SpecificVersion .zip "
}
elseif ( $Runtime -eq " dotnet " ) {
2017-05-23 10:45:15 -07:00
$PayloadURL = " $AzureFeed /Runtime/ $SpecificVersion /dotnet-win- $CLIArchitecture . $SpecificVersion .zip "
2016-05-27 12:19:53 -07:00
}
else {
2018-01-05 09:24:10 -08:00
return $null
2016-04-07 10:32:52 -07:00
}
2017-06-09 12:00:29 -07:00
Say-Verbose " Constructed legacy payload URL: $PayloadURL "
2016-06-21 18:36:43 -05:00
2017-05-26 15:46:56 -07:00
return $PayloadURL
2016-04-07 10:32:52 -07:00
}
function Get-User-Share-Path ( ) {
Say-Invocation $MyInvocation
$InstallRoot = $env:DOTNET_INSTALL_DIR
if ( ! $InstallRoot ) {
$InstallRoot = " $env:LocalAppData \Microsoft\dotnet "
}
return $InstallRoot
}
function Resolve-Installation-Path([string]$InstallDir ) {
Say-Invocation $MyInvocation
if ( $InstallDir -eq " <auto> " ) {
return Get-User -Share -Path
}
return $InstallDir
}
function Get-Version-Info-From-Version-File([string]$InstallRoot , [ string ] $RelativePathToVersionFile ) {
Say-Invocation $MyInvocation
$VersionFile = Join-Path -Path $InstallRoot -ChildPath $RelativePathToVersionFile
Say-Verbose " Local version file: $VersionFile "
2017-06-21 16:20:51 -07:00
2016-04-07 10:32:52 -07:00
if ( Test-Path $VersionFile ) {
$VersionText = cat $VersionFile
Say-Verbose " Local version file text: $VersionText "
return Get-Version -Info -From -Version -Text $VersionText
}
Say-Verbose " Local version file not found. "
return $null
}
function Is-Dotnet-Package-Installed([string]$InstallRoot , [ string ] $RelativePathToPackage , [ string ] $SpecificVersion ) {
Say-Invocation $MyInvocation
2017-06-21 16:20:51 -07:00
2016-04-07 10:32:52 -07:00
$DotnetPackagePath = Join-Path -Path $InstallRoot -ChildPath $RelativePathToPackage | Join-Path -ChildPath $SpecificVersion
Say-Verbose " Is-Dotnet-Package-Installed: Path to a package: $DotnetPackagePath "
return Test-Path $DotnetPackagePath -PathType Container
}
function Get-Absolute-Path([string]$RelativeOrAbsolutePath ) {
# Too much spam
# Say-Invocation $MyInvocation
return $ExecutionContext . SessionState . Path . GetUnresolvedProviderPathFromPSPath ( $RelativeOrAbsolutePath )
}
function Get-Path-Prefix-With-Version($path ) {
$match = [ regex ] :: match ( $path , $VersionRegEx )
if ( $match . Success ) {
return $entry . FullName . Substring ( 0 , $match . Index + $match . Length )
}
2017-06-21 16:20:51 -07:00
2016-04-07 10:32:52 -07:00
return $null
}
function Get-List-Of-Directories-And-Versions-To-Unpack-From-Dotnet-Package([System.IO.Compression.ZipArchive]$Zip , [ string ] $OutPath ) {
Say-Invocation $MyInvocation
2017-06-21 16:20:51 -07:00
2016-04-07 10:32:52 -07:00
$ret = @ ( )
foreach ( $entry in $Zip . Entries ) {
$dir = Get-Path -Prefix -With -Version $entry . FullName
if ( $dir -ne $null ) {
$path = Get-Absolute -Path $ ( Join-Path -Path $OutPath -ChildPath $dir )
if ( -Not ( Test-Path $path -PathType Container ) ) {
$ret + = $dir
}
}
}
2017-06-21 16:20:51 -07:00
2016-04-07 10:32:52 -07:00
$ret = $ret | Sort-Object | Get-Unique
2017-06-21 16:20:51 -07:00
2016-04-07 10:32:52 -07:00
$values = ( $ret | foreach { " $_ " } ) -join " ; "
Say-Verbose " Directories to unpack: $values "
2017-06-21 16:20:51 -07:00
2016-04-07 10:32:52 -07:00
return $ret
}
# Example zip content and extraction algorithm:
# Rule: files if extracted are always being extracted to the same relative path locally
# .\
# a.exe # file does not exist locally, extract
# b.dll # file exists locally, override only if $OverrideFiles set
# aaa\ # same rules as for files
# ...
# abc\1.0.0\ # directory contains version and exists locally
# ... # do not extract content under versioned part
# abc\asd\ # same rules as for files
# ...
# def\ghi\1.0.1\ # directory contains version and does not exist locally
# ... # extract content
function Extract-Dotnet-Package([string]$ZipPath , [ string ] $OutPath ) {
Say-Invocation $MyInvocation
2016-08-08 15:03:36 -05:00
Load-Assembly -Assembly System . IO . Compression . FileSystem
2016-04-07 10:32:52 -07:00
Set-Variable -Name Zip
try {
$Zip = [ System.IO.Compression.ZipFile ] :: OpenRead ( $ZipPath )
2017-06-21 16:20:51 -07:00
2016-04-07 10:32:52 -07:00
$DirectoriesToUnpack = Get-List -Of -Directories -And -Versions -To -Unpack -From -Dotnet -Package -Zip $Zip -OutPath $OutPath
2017-06-21 16:20:51 -07:00
2016-04-07 10:32:52 -07:00
foreach ( $entry in $Zip . Entries ) {
$PathWithVersion = Get-Path -Prefix -With -Version $entry . FullName
if ( ( $PathWithVersion -eq $null ) -Or ( $DirectoriesToUnpack -contains $PathWithVersion ) ) {
$DestinationPath = Get-Absolute -Path $ ( Join-Path -Path $OutPath -ChildPath $entry . FullName )
$DestinationDir = Split-Path -Parent $DestinationPath
$OverrideFiles = $OverrideNonVersionedFiles -Or ( -Not ( Test-Path $DestinationPath ) )
if ( ( -Not $DestinationPath . EndsWith ( " \ " ) ) -And $OverrideFiles ) {
New-Item -ItemType Directory -Force -Path $DestinationDir | Out-Null
[ System.IO.Compression.ZipFileExtensions ] :: ExtractToFile ( $entry , $DestinationPath , $OverrideNonVersionedFiles )
}
}
}
}
finally {
if ( $Zip -ne $null ) {
$Zip . Dispose ( )
}
}
}
2016-08-04 14:55:40 -05:00
function DownloadFile([Uri]$Uri , [ string ] $OutPath ) {
2016-08-25 11:41:24 -05:00
$Stream = $null
2016-08-04 14:55:40 -05:00
try {
2016-08-25 11:41:24 -05:00
$Response = GetHTTPResponse -Uri $Uri
$Stream = $Response . Content . ReadAsStreamAsync ( ) . Result
2016-08-04 14:55:40 -05:00
$File = [ System.IO.File ] :: Create ( $OutPath )
$Stream . CopyTo ( $File )
$File . Close ( )
}
finally {
if ( $Stream -ne $null ) {
$Stream . Dispose ( )
}
}
}
2016-11-30 23:36:24 -05:00
function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot , [ string ] $BinFolderRelativePath ) {
$BinPath = Get-Absolute -Path $ ( Join-Path -Path $InstallRoot -ChildPath $BinFolderRelativePath )
if ( -Not $NoPath ) {
Say " Adding to current process PATH: `" $BinPath `" . Note: This change will not be visible if PowerShell was run as a child process. "
$env:path = " $BinPath ; " + $env:path
}
else {
Say " Binaries of dotnet can be found in $BinPath "
}
}
2016-04-07 10:32:52 -07:00
$CLIArchitecture = Get-CLIArchitecture -From -Architecture $Architecture
2017-05-23 16:41:46 -07:00
$SpecificVersion = Get-Specific -Version -From -Version -AzureFeed $AzureFeed -Channel $Channel -Version $Version
2017-08-31 13:18:42 -07:00
$DownloadLink = Get-Download -Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
$LegacyDownloadLink = Get-LegacyDownload -Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
2016-04-07 10:32:52 -07:00
if ( $DryRun ) {
Say " Payload URLs: "
2017-05-26 15:46:56 -07:00
Say " Primary - $DownloadLink "
2018-01-05 09:24:10 -08:00
if ( $LegacyDownloadLink ) {
Say " Legacy - $LegacyDownloadLink "
}
2017-08-31 13:18:42 -07:00
Say " Repeatable invocation: .\ $( $MyInvocation . Line ) "
2016-05-13 11:39:28 -07:00
exit 0
2016-04-07 10:32:52 -07:00
}
$InstallRoot = Resolve-Installation -Path $InstallDir
Say-Verbose " InstallRoot: $InstallRoot "
2018-01-05 09:24:10 -08:00
if ( $Runtime -eq " dotnet " ) {
$assetName = " .NET Core Runtime "
$dotnetPackageRelativePath = " shared\Microsoft.NETCore.App "
}
elseif ( $Runtime -eq " aspnetcore " ) {
$assetName = " ASP.NET Core Runtime "
2018-02-14 11:50:14 -08:00
$dotnetPackageRelativePath = " shared\Microsoft.AspNetCore.App "
2018-01-05 09:24:10 -08:00
}
2018-02-14 11:50:14 -08:00
elseif ( -not $Runtime ) {
2018-01-05 09:24:10 -08:00
$assetName = " .NET Core SDK "
$dotnetPackageRelativePath = " sdk "
}
2018-02-14 11:50:14 -08:00
else {
throw " Invalid value for `$ Runtime "
}
2018-01-05 09:24:10 -08:00
$isAssetInstalled = Is-Dotnet -Package -Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $SpecificVersion
if ( $isAssetInstalled ) {
Say " $assetName version $SpecificVersion is already installed. "
2016-11-30 23:36:24 -05:00
Prepend-Sdk -InstallRoot -To -Path -InstallRoot $InstallRoot -BinFolderRelativePath $BinFolderRelativePath
2016-05-13 11:39:28 -07:00
exit 0
2016-04-07 10:32:52 -07:00
}
New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
2017-05-26 15:46:56 -07:00
$installDrive = $ ( ( Get-Item $InstallRoot ) . PSDrive . Name ) ;
$free = Get-CimInstance -Class win32_logicaldisk | where Deviceid -eq " ${installDrive} : "
if ( $free . Freespace / 1 MB -le 100 ) {
Say " There is not enough disk space on drive ${installDrive} : "
2016-11-15 12:19:12 -08:00
exit 0
}
2017-08-31 13:18:42 -07:00
$ZipPath = [ System.IO.Path ] :: combine ( [ System.IO.Path ] :: GetTempPath ( ) , [ System.IO.Path ] :: GetRandomFileName ( ) )
2017-06-13 16:45:29 -07:00
Say-Verbose " Zip path: $ZipPath "
Say " Downloading link: $DownloadLink "
2017-05-26 15:46:56 -07:00
try {
DownloadFile -Uri $DownloadLink -OutPath $ZipPath
}
catch {
2017-06-13 16:45:29 -07:00
Say " Cannot download: $DownloadLink "
2018-01-05 09:24:10 -08:00
if ( $LegacyDownloadLink ) {
$DownloadLink = $LegacyDownloadLink
$ZipPath = [ System.IO.Path ] :: combine ( [ System.IO.Path ] :: GetTempPath ( ) , [ System.IO.Path ] :: GetRandomFileName ( ) )
Say-Verbose " Legacy zip path: $ZipPath "
Say " Downloading legacy link: $DownloadLink "
DownloadFile -Uri $DownloadLink -OutPath $ZipPath
}
else {
throw " Could not download $assetName version $SpecificVersion "
}
2017-05-26 15:46:56 -07:00
}
2016-04-07 10:32:52 -07:00
2017-05-26 15:46:56 -07:00
Say " Extracting zip from $DownloadLink "
Extract-Dotnet -Package -ZipPath $ZipPath -OutPath $InstallRoot
2016-04-07 10:32:52 -07:00
2017-05-26 15:46:56 -07:00
Remove-Item $ZipPath
2016-04-07 10:32:52 -07:00
2016-11-30 23:36:24 -05:00
Prepend-Sdk -InstallRoot -To -Path -InstallRoot $InstallRoot -BinFolderRelativePath $BinFolderRelativePath
2016-04-07 10:32:52 -07:00
Say " Installation finished "
2016-05-13 11:39:28 -07:00
exit 0