diff --git a/images/win/scripts/ImageHelpers/ImageHelpers.psm1 b/images/win/scripts/ImageHelpers/ImageHelpers.psm1 index 2b716880..94ff7b20 100644 --- a/images/win/scripts/ImageHelpers/ImageHelpers.psm1 +++ b/images/win/scripts/ImageHelpers/ImageHelpers.psm1 @@ -14,6 +14,7 @@ Export-ModuleMember -Function @( 'Get-SystemVariable' 'Set-SystemVariable' 'Install-Binary' + 'Install-VisualStudio' 'Get-ToolcachePackages' 'Get-ToolsetContent' 'Get-ToolsByName' diff --git a/images/win/scripts/ImageHelpers/InstallHelpers.ps1 b/images/win/scripts/ImageHelpers/InstallHelpers.ps1 index c8d70c8b..8ec49e0d 100644 --- a/images/win/scripts/ImageHelpers/InstallHelpers.ps1 +++ b/images/win/scripts/ImageHelpers/InstallHelpers.ps1 @@ -20,7 +20,8 @@ function Install-Binary Install-Binary -Url "https://go.microsoft.com/fwlink/p/?linkid=2083338" -Name "winsdksetup.exe" -ArgumentList ("/features", "+", "/quiet") #> - Param ( + Param + ( [Parameter(Mandatory)] [String] $Url, [Parameter(Mandatory)] @@ -62,6 +63,68 @@ function Install-Binary } } +Function Install-VisualStudio +{ + <# + .SYNOPSIS + A helper function to install Visual Studio. + + .DESCRIPTION + Prepare system environment, and install Visual Studio bootstrapper with selected workloads. + + .PARAMETER BootstrapperUrl + The URL from which the bootstrapper will be downloaded. Required parameter. + + .PARAMETER WorkLoads + The string that contain workloads that will be passed to the installer. + #> + + Param + ( + [Parameter(Mandatory)] + [String] $BootstrapperUrl, + [String] $WorkLoads + ) + + Write-Host "Downloading Bootstrapper ..." + $BootstrapperName = [IO.Path]::GetFileName($BootstrapperUrl) + $bootstrapperFilePath = Start-DownloadWithRetry -Url $BootstrapperUrl -Name $BootstrapperName + + try + { + Write-Host "Enable short name support on Windows needed for Xamarin Android AOT, defaults appear to have been changed in Azure VMs" + $shortNameEnableProcess = Start-Process -FilePath fsutil.exe -ArgumentList ('8dot3name', 'set', '0') -Wait -PassThru + + $shortNameEnableExitCode = $shortNameEnableProcess.ExitCode + if ($shortNameEnableExitCode -ne 0) + { + Write-Host "Enabling short name support on Windows failed. This needs to be enabled prior to VS 2017 install for Xamarin Andriod AOT to work." + exit $shortNameEnableExitCode + } + + Write-Host "Starting Install ..." + $bootstrapperArgumentList = ('/c', $bootstrapperFilePath, $WorkLoads, '--quiet', '--norestart', '--wait', '--nocache' ) + $process = Start-Process -FilePath cmd.exe -ArgumentList $bootstrapperArgumentList -Wait -PassThru + + $exitCode = $process.ExitCode + if ($exitCode -eq 0 -or $exitCode -eq 3010) + { + Write-Host "Installation successful" + return $exitCode + } + else + { + Write-Host "Non zero exit code returned by the installation process : $exitCode" + exit $exitCode + } + } + catch + { + Write-Host "Failed to install Visual Studio; $($_.Exception.Message)" + exit -1 + } +} + function Stop-SvcWithErrHandling { <# @@ -74,7 +137,8 @@ function Stop-SvcWithErrHandling .PARAMETER StopOnError Switch for stopping the script and exit from PowerShell if one service is absent #> - param ( + param + ( [Parameter(Mandatory, ValueFromPipeLine = $true)] [string] $ServiceName, [switch] $StopOnError @@ -123,7 +187,8 @@ function Set-SvcWithErrHandling Hashtable for service arguments #> - param ( + param + ( [Parameter(Mandatory, ValueFromPipeLine = $true)] [string] $ServiceName, [Parameter(Mandatory)] @@ -152,7 +217,8 @@ function Set-SvcWithErrHandling function Start-DownloadWithRetry { - param ( + param + ( [Parameter(Mandatory)] [string] $Url, [Parameter(Mandatory)] @@ -253,7 +319,8 @@ function Install-VsixExtension function Get-VSExtensionVersion { - param ( + Param + ( [Parameter(Mandatory=$true)] [string] $packageName ) @@ -289,7 +356,8 @@ function Get-ToolsetContent { } function Get-ToolsByName { - param ( + Param + ( [Parameter(Mandatory = $True)] [string]$SoftwareName ) diff --git a/images/win/scripts/Installers/Install-DotnetSDK.ps1 b/images/win/scripts/Installers/Install-DotnetSDK.ps1 index 57d7668c..7668e7c2 100644 --- a/images/win/scripts/Installers/Install-DotnetSDK.ps1 +++ b/images/win/scripts/Installers/Install-DotnetSDK.ps1 @@ -32,7 +32,10 @@ function InstallSDKVersion ( } # Fix for issue 1276. This will be fixed in 3.1. - Invoke-WebRequest -Uri "https://raw.githubusercontent.com/dotnet/sdk/82bc30c99f1325dfaa7ad450be96857a4fca2845/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.ImportPublishProfile.targets" -outfile "C:\Program Files\dotnet\sdk\$sdkVersion\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.ImportPublishProfile.targets" + $sdkTargetsName = "Microsoft.NET.Sdk.ImportPublishProfile.targets" + $sdkTargetsUrl = "https://raw.githubusercontent.com/dotnet/sdk/82bc30c99f1325dfaa7ad450be96857a4fca2845/src/Tasks/Microsoft.NET.Build.Tasks/targets/${sdkTargetsName}" + $sdkTargetsPath = "C:\Program Files\dotnet\sdk\$sdkVersion\Sdks\Microsoft.NET.Sdk\targets" + Start-DownloadWithRetry -Url $sdkTargetsUrl -DownloadPath $sdkTargetsPath -Name $sdkTargetsName # warm up dotnet for first time experience $templates | ForEach-Object { @@ -49,8 +52,10 @@ function InstallSDKVersion ( function InstallAllValidSdks() { - Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases-index.json' -UseBasicParsing -OutFile 'releases-index.json' - $dotnetChannels = Get-Content -Path 'releases-index.json' | ConvertFrom-Json + $releaseIndexName = "releases-index.json" + $releaseIndexUrl = "https://raw.githubusercontent.com/dotnet/core/master/release-notes/${releaseIndexName}" + $releasesIndexPath = Start-DownloadWithRetry -Url $releaseIndexUrl -Name $releaseIndexName + $dotnetChannels = Get-Content -Path $releasesIndexPath | ConvertFrom-Json # Consider all channels except preview/eol channels. # Sort the channels in ascending order @@ -58,13 +63,15 @@ function InstallAllValidSdks() $dotnetChannels = $dotnetChannels.'releases-index' | Where-Object { (!$_."support-phase".Equals('preview') -and !$_."support-phase".Equals('eol')) -or ($_."channel-version" -eq "2.2") } | Sort-Object { [Version] $_."channel-version" } # Download installation script. - Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -UseBasicParsing -OutFile 'dotnet-install.ps1' + $installationName = "dotnet-install.ps1" + $installationUrl = "https://dot.net/v1/${installationName}" + Start-DownloadWithRetry -Url $installationUrl -Name $installationName -DownloadPath ".\" ForEach ($dotnetChannel in $dotnetChannels) { $channelVersion = $dotnetChannel.'channel-version'; - Invoke-WebRequest -Uri $dotnetChannel.'releases.json' -UseBasicParsing -OutFile "releases-$channelVersion.json" - $currentReleases = Get-Content -Path "releases-$channelVersion.json" | ConvertFrom-Json + $releasesJsonPath = Start-DownloadWithRetry -Url $dotnetChannel.'releases.json' -Name "releases-$channelVersion.json" + $currentReleases = Get-Content -Path $releasesJsonPath | ConvertFrom-Json # filtering out the preview/rc releases $currentReleases = $currentReleases.'releases' | Where-Object { !$_.'release-version'.Contains('-') } | Sort-Object { [Version] $_.'release-version' } @@ -74,7 +81,6 @@ function InstallAllValidSdks() { Write-Host 'Found sdks property in release: ' + $release.'release-version' + 'with sdks count: ' + $release.'sdks'.Count - # Remove duplicate entries & preview/rc version from download list # Sort the sdks on version $sdks = @($release.'sdk'); diff --git a/images/win/scripts/Installers/Windows2016/Install-VS2017.ps1 b/images/win/scripts/Installers/Windows2016/Install-VS2017.ps1 index 9edcb14f..45fae7cd 100644 --- a/images/win/scripts/Installers/Windows2016/Install-VS2017.ps1 +++ b/images/win/scripts/Installers/Windows2016/Install-VS2017.ps1 @@ -3,63 +3,11 @@ ## Desc: Install Visual Studio 2017 ################################################################################ -Function InstallVS -{ - Param - ( - [String]$WorkLoads, - [String]$Sku, - [String] $VSBootstrapperURL - ) +$ErrorActionPreference = "Stop" - $exitCode = -1 +Import-Module -Name ImageHelpers -Force - try - { - Write-Host "Enable short name support on Windows needed for Xamarin Android AOT, defaults appear to have been changed in Azure VMs" - $shortNameEnableProcess = Start-Process -FilePath fsutil.exe -ArgumentList ('8dot3name', 'set', '0') -Wait -PassThru - $shortNameEnableExitCode = $shortNameEnableProcess.ExitCode - - if ($shortNameEnableExitCode -ne 0) - { - Write-Host -Object 'Enabling short name support on Windows failed. This needs to be enabled prior to VS 2017 install for Xamarin Andriod AOT to work.' - exit $shortNameEnableExitCode - } - - Write-Host "Downloading Bootstrapper ..." - Invoke-WebRequest -Uri $VSBootstrapperURL -OutFile "${env:Temp}\vs_$Sku.exe" - - $FilePath = "${env:Temp}\vs_$Sku.exe" - $Arguments = ('/c', $FilePath, $WorkLoads, '--quiet', '--norestart', '--wait', '--nocache' ) - - Write-Host "Starting Install ..." - $process = Start-Process -FilePath cmd.exe -ArgumentList $Arguments -Wait -PassThru - $exitCode = $process.ExitCode - - if ($exitCode -eq 0 -or $exitCode -eq 3010) - { - Write-Host -Object 'Installation successful' - return $exitCode - } - else - { - Write-Host -Object "Non zero exit code returned by the installation process : $exitCode." - - # this wont work because of log size limitation in extension manager - # Get-Content $customLogFilePath | Write-Host - - exit $exitCode - } - } - catch - { - Write-Host -Object "Failed to install Visual Studio. Check the logs for details in $customLogFilePath" - Write-Host -Object $_.Exception.Message - exit -1 - } -} - -$WorkLoads = '--allWorkloads --includeRecommended ' + ` +$WorkLoads = '--allWorkloads --includeRecommended ' + ` '--add Microsoft.Net.Component.4.6.2.SDK ' + ` '--add Microsoft.Net.Component.4.6.2.TargetingPack ' + ` '--add Microsoft.Net.ComponentGroup.4.6.2.DeveloperTools ' + ` @@ -129,20 +77,18 @@ $WorkLoads = '--allWorkloads --includeRecommended ' + ` '--add Microsoft.VisualStudio.Workload.Office ' + ` '--add Microsoft.VisualStudio.Workload.OfficeBuildTools ' -$Sku = 'Enterprise' -$VSBootstrapperURL = 'https://aka.ms/vs/15/release/vs_enterprise.exe' - -$ErrorActionPreference = 'Stop' +$ReleaseInPath = "Enterprise" +$BootstrapperUrl = "https://aka.ms/vs/15/release/vs_${ReleaseInPath}.exe" # Install VS -$exitCode = InstallVS -WorkLoads $WorkLoads -Sku $Sku -VSBootstrapperURL $VSBootstrapperURL +Install-VisualStudio -BootstrapperUrl $BootstrapperUrl -WorkLoads $WorkLoads # Find the version of VS installed for this instance # Only supports a single instance $vsProgramData = Get-Item -Path "C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances" $instanceFolders = Get-ChildItem -Path $vsProgramData.FullName -if($instanceFolders -is [array]) +if ($instanceFolders -is [array]) { Write-Host "More than one instance installed" exit 1 @@ -151,20 +97,19 @@ if($instanceFolders -is [array]) $catalogContent = Get-Content -Path ($instanceFolders.FullName + '\catalog.json') $catalog = $catalogContent | ConvertFrom-Json $version = $catalog.info.id -$VSInstallRoot = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise" -Write-Host "Visual Studio version" $version "installed" +$VSInstallRoot = "C:\Program Files (x86)\Microsoft Visual Studio\2017\$ReleaseInPath" +Write-Host "Visual Studio version ${version} installed" # Initialize Visual Studio Experimental Instance for integration testing -&"$VSInstallRoot\Common7\IDE\devenv.exe" /RootSuffix Exp /ResetSettings General.vssettings /Command File.Exit | Wait-Process +& "$VSInstallRoot\Common7\IDE\devenv.exe" /RootSuffix Exp /ResetSettings General.vssettings /Command File.Exit | Wait-Process # Updating content of MachineState.json file to disable autoupdate of VSIX extensions $newContent = '{"Extensions":[{"Key":"1e906ff5-9da8-4091-a299-5c253c55fdc9","Value":{"ShouldAutoUpdate":false}},{"Key":"Microsoft.VisualStudio.Web.AzureFunctions","Value":{"ShouldAutoUpdate":false}}],"ShouldAutoUpdate":false,"ShouldCheckForUpdates":false}' Set-Content -Path "$VSInstallRoot\Common7\IDE\Extensions\MachineState.json" -Value $newContent - # Adding description of the software to Markdown -$SoftwareName = "Visual Studio 2017 Enterprise" +$SoftwareName = "Visual Studio 2017 $ReleaseInPath" $Description = @" _Version:_ $version
@@ -198,8 +143,4 @@ In addition the following optional components are installed: Add-SoftwareDetailsToMarkdown -SoftwareName $SoftwareName -DescriptionMarkdown $Description # Adding explicitly added Workloads details to markdown by parsing $Workloads -Add-ContentToMarkdown -Content $($WorkLoads.Split('--') | % { if( ($_.Split(" "))[0] -like "add") { "* " +($_.Split(" "))[1] } } ) - - - -exit $exitCode +Add-ContentToMarkdown -Content $($WorkLoads.Split('--') | % { if( ($_.Split(" "))[0] -like "add") { "* " +($_.Split(" "))[1] } } ) \ No newline at end of file diff --git a/images/win/scripts/Installers/Windows2019/Install-VS2019.ps1 b/images/win/scripts/Installers/Windows2019/Install-VS2019.ps1 index 1ccd5c42..627ff18d 100644 --- a/images/win/scripts/Installers/Windows2019/Install-VS2019.ps1 +++ b/images/win/scripts/Installers/Windows2019/Install-VS2019.ps1 @@ -4,61 +4,7 @@ ################################################################################ $ErrorActionPreference = "Stop" -Function InstallVS -{ - Param - ( - [String]$WorkLoads, - [String]$Sku, - [String] $VSBootstrapperURL - ) - - $exitCode = -1 - - try - { - Write-Host "Enable short name support on Windows needed for Xamarin Android AOT, defaults appear to have been changed in Azure VMs" - $shortNameEnableProcess = Start-Process -FilePath fsutil.exe -ArgumentList ('8dot3name', 'set', '0') -Wait -PassThru - $shortNameEnableExitCode = $shortNameEnableProcess.ExitCode - - if ($shortNameEnableExitCode -ne 0) - { - Write-Host -Object 'Enabling short name support on Windows failed. This needs to be enabled prior to VS 2017 install for Xamarin Andriod AOT to work.' - exit $shortNameEnableExitCode - } - - Write-Host "Downloading Bootstrapper ..." - Invoke-WebRequest -Uri $VSBootstrapperURL -OutFile "${env:Temp}\vs_$Sku.exe" - - $FilePath = "${env:Temp}\vs_$Sku.exe" - $Arguments = ('/c', $FilePath, $WorkLoads, '--quiet', '--norestart', '--wait', '--nocache' ) - - Write-Host "Starting Install ..." - $process = Start-Process -FilePath cmd.exe -ArgumentList $Arguments -Wait -PassThru - $exitCode = $process.ExitCode - - if ($exitCode -eq 0 -or $exitCode -eq 3010) - { - Write-Host -Object 'Installation successful' - return $exitCode - } - else - { - Write-Host -Object "Non zero exit code returned by the installation process : $exitCode." - - # this wont work because of log size limitation in extension manager - # Get-Content $customLogFilePath | Write-Host - - exit $exitCode - } - } - catch - { - Write-Host -Object "Failed to install Visual Studio. Check the logs for details in $customLogFilePath" - Write-Host -Object $_.Exception.Message - exit -1 - } -} +Import-Module -Name ImageHelpers -Force $WorkLoads = '--allWorkloads --includeRecommended ' + ` '--add Component.Dotfuscator ' + ` @@ -150,22 +96,18 @@ $WorkLoads = '--allWorkloads --includeRecommended ' + ` '--add Microsoft.VisualStudio.Workload.Universal ' + ` '--add Microsoft.VisualStudio.Workload.VisualStudioExtension' - -$ReleaseInPath = 'Enterprise' -$Sku = 'Enterprise' -$VSBootstrapperURL = 'https://aka.ms/vs/16/release/vs_Enterprise.exe' - -$ErrorActionPreference = 'Stop' +$ReleaseInPath = "Enterprise" +$BootstrapperUrl = "https://aka.ms/vs/16/release/vs_${ReleaseInPath}.exe" # Install VS -$exitCode = InstallVS -WorkLoads $WorkLoads -Sku $Sku -VSBootstrapperURL $VSBootstrapperURL +Install-VisualStudio -BootstrapperUrl $BootstrapperUrl -WorkLoads $WorkLoads # Find the version of VS installed for this instance # Only supports a single instance $vsProgramData = Get-Item -Path "C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances" $instanceFolders = Get-ChildItem -Path $vsProgramData.FullName -if($instanceFolders -is [array]) +if ($instanceFolders -is [array]) { Write-Host "More than one instance installed" exit 1 @@ -174,14 +116,15 @@ if($instanceFolders -is [array]) $catalogContent = Get-Content -Path ($instanceFolders.FullName + '\catalog.json') $catalog = $catalogContent | ConvertFrom-Json $version = $catalog.info.id -Write-Host "Visual Studio version" $version "installed" +$VSInstallRoot = "C:\Program Files (x86)\Microsoft Visual Studio\2019\$ReleaseInPath" +Write-Host "Visual Studio version ${version} installed" # Initialize Visual Studio Experimental Instance -&"C:\Program Files (x86)\Microsoft Visual Studio\2019\$ReleaseInPath\Common7\IDE\devenv.exe" /RootSuffix Exp /ResetSettings General.vssettings /Command File.Exit +& "$VSInstallRoot\Common7\IDE\devenv.exe" /RootSuffix Exp /ResetSettings General.vssettings /Command File.Exit # Updating content of MachineState.json file to disable autoupdate of VSIX extensions $newContent = '{"Extensions":[{"Key":"1e906ff5-9da8-4091-a299-5c253c55fdc9","Value":{"ShouldAutoUpdate":false}},{"Key":"Microsoft.VisualStudio.Web.AzureFunctions","Value":{"ShouldAutoUpdate":false}}],"ShouldAutoUpdate":false,"ShouldCheckForUpdates":false}' -Set-Content -Path "C:\Program Files (x86)\Microsoft Visual Studio\2019\$ReleaseInPath\Common7\IDE\Extensions\MachineState.json" -Value $newContent +Set-Content -Path "$VSInstallRoot\Common7\IDE\Extensions\MachineState.json" -Value $newContent # Adding description of the software to Markdown @@ -190,7 +133,7 @@ $SoftwareName = "Visual Studio 2019 Enterprise" $Description = @" _Version:_ $version
-_Location:_ C:\Program Files (x86)\Microsoft Visual Studio\2019\$ReleaseInPath +_Location:_ $VSInstallRoot The following workloads and components are installed with Visual Studio 2019: "@ @@ -198,7 +141,4 @@ The following workloads and components are installed with Visual Studio 2019: Add-SoftwareDetailsToMarkdown -SoftwareName $SoftwareName -DescriptionMarkdown $Description # Adding explicitly added Workloads details to markdown by parsing $Workloads -Add-ContentToMarkdown -Content $($WorkLoads.Split('--') | % { if( ($_.Split(" "))[0] -like "add") { "* " +($_.Split(" "))[1] } } ) - - -exit $exitCode +Add-ContentToMarkdown -Content $($WorkLoads.Split('--') | % { if( ($_.Split(" "))[0] -like "add") { "* " +($_.Split(" "))[1] } } ) \ No newline at end of file