Wednesday 4 October 2017

Automated installation of VS 2017 build tools

Visual Studio 2017 has re-done the whole installation procedure, with the goal of making what used to be very painful - preparing a UI-less build agent image for automated .NET builds - nice and simple. And fast. Well, it's not quite there yet. So as I was reading Chris' post on building AMI images for TeamCity build agents with Packer I was nodding along until I came to the bit where VS 2015 tools get installed. What about current tooling?

I wouldn't recommend using chocolatey to install it, unfortunately, even though a package is available. The new installer has a nasty habit of exiting silently (or hanging) if something is amiss - and you'll want to be able to choose your VS workload packages which chocolatey doesn't support.

What can fail? The installer tends to abort if any of the folders it tries to create already exists. That's why you're likely to have more luck if you don't install the .NET 4.7 framework separately - also, any .target or task dlls that are not yet provided by the installer, should be scripted for installation later, not before. Took me a whole day to find this out.

The command line parameters for the installer aren't too obvious either. "wait" doesn't wait unless you wrap it in a PowerShell script. "quiet" prints no diagnostics (well, duh) but "passive" displays a UI - there's no option for "print errors to the command line". If you're struggling, you'll end up re-creating your test VMs and switching between multiple runs of "passive" and "quiet" to see if things finally work. Oh and the download link isn't easy to find either (seriously, it seems to be completely missing from the documentation - thankfully, StackOverflow helps). And getting the parameters in the wrong order end up with the installer hanging.

The short PowerShell script that finally worked for me is:

$Url = 'https://aka.ms/vs/15/release/vs_buildtools.exe'
$Exe = "vs_buildtools.exe"
$Dest = "c:\\tmp\\" + $Exe
$client = new-object System.Net.WebClient
$client.DownloadFile($Url,$Dest)
$Params = "--add Microsoft.VisualStudio.Workload.MSBuildTools `
--add Microsoft.VisualStudio.Workload.WebBuildTools `
--add Microsoft.Net.Component.4.7.SDK `
--add Microsoft.Net.Component.4.7.TargetingPack `
--add Microsoft.Net.ComponentGroup.4.7.DeveloperTools `
--quiet --wait"
Start-Process $Dest -ArgumentList $Params -Wait
Remove-Item $Dest

Is it faster than the VS 2015 installation? Not really, the old one had an offline version you could pre-load, the new one is completely online (if you re-run it you'll get newer components!). And with VS15, a t2.micro instance was enough to run the AMI creation job - this one needs a t2.medium to finish installation in a reasonable amount of time. At least it includes most of the things that were missing before (still waiting for dotnetcore-2.0 to be included).