Running the Latest .NET Core SDK on Visual Studio Team Services Hosted Build Agent

Depending on your project, you might need to run the latest version of the .NET Core SDK on your hosted build agent. Hosted agents are pulled from the VSTS hosted pool. With great flexibility comes great responsibility, so the build agent has some limitations when it comes to picking the software that needs to be deployed.

Drake Laughing GIF

Specifically, if you go over the existing constraints, you will notice that there are two that will prevent a simple silent install:

Q: Does your build depend on software other than this software that is installed on hosted build resources?

A: No. Then you can use the hosted pool.

Q: Do any of the processes for your build need administrator privileges?

A: No. Then you can use the hosted pool.

So what do you do in this case? The great thing about the .NET Core SDK is the fact that you don’t really need to perform an install, but rather simply copy the files to the build agent and re-set the PATH environment variable to point to the newly deployed SDK.

NOTE: The original .NET Core SDK is installed under C:\Program Files\dotnet. You will get an “Access Denied” error if you attempt to overwrite the contents.

The solution revolves around some PowerShell trickery. First, you need to create a new script that will download and extract the .NET Core SDK. In my case, I deployed this to my GitHub repo:


[reflection.assembly]::LoadWithPartialName("System.Net.Http") | Out-Null
[reflection.assembly]::LoadWithPartialName("System.Threading") | Out-Null
[reflection.assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
$SourcePath = "https://dotnetcli.blob.core.windows.net/dotnet/Sdk/rel-1.0.0/dotnet-dev-win-x64.latest.zip";
$DestinationPath = "C:\dotnet"
$TempPath = [System.IO.Path]::GetTempFileName()
if (($SourcePath -as [System.URI]).AbsoluteURI -ne $null)
{
$handler = New-Object System.Net.Http.HttpClientHandler
$client = New-Object System.Net.Http.HttpClient($handler)
$client.Timeout = New-Object System.TimeSpan(0, 30, 0)
$cancelTokenSource = New-Object System.Threading.CancellationTokenSource
$uri = New-Object -TypeName System.Uri $SourcePath
$responseMsg = $client.GetAsync($uri, $cancelTokenSource.Token)
$responseMsg.Wait()
if (!$responseMsg.IsCanceled)
{
$response = $responseMsg.Result
if ($response.IsSuccessStatusCode)
{
$fileMode = [System.IO.FileMode]::Create
$fileAccess = [System.IO.FileAccess]::Write
$downloadedFileStream = New-Object System.IO.FileStream $TempPath,$fileMode,$fileAccess
$copyStreamOp = $response.Content.CopyToAsync($downloadedFileStream)
$copyStreamOp.Wait()
$downloadedFileStream.Close()
if ($copyStreamOp.Exception -ne $null)
{
throw $copyStreamOp.Exception
}
}
}
}
else
{
throw "Cannot copy from $SourcePath"
}
[System.IO.Compression.ZipFile]::ExtractToDirectory($TempPath, $DestinationPath)
Remove-Item $TempPath

The URL for the 1.0.0 release is hard-coded in the script – I am downloading it and extracting locally. Remember that in a hosted agent, no files are persistent, so post-build those are deleted. You will need to re-download the package every single time you want to kick off a new build.

Once the package is deployed, you will need to simply run this snippet of PowerShell code:


dotnet --version; $path = Get-ChildItem Env:path; Write-Host $path.Value; $pathValue = $path.Value -Replace "C:\\Program Files\\dotnet","C:\dotnet"; Write-Host $pathValue; $env:Path = $pathValue; dotnet --version

What this snippet does is get the PATH from the current environment variables, swap it for the right location for the .NET Core SDK and then display it – for your convenience, I am also showing the dotnet version before an after. You can reduce it to just the necessary parts.

After the execution, you will be able to trigger dotnet build and dotnet run (and other capabilities) with the latest version.

3 thoughts on “Running the Latest .NET Core SDK on Visual Studio Team Services Hosted Build Agent”

  1. Hi,
    Thanks for your post. I was able to reproduce it. However, the build still failing for me when I try to build the project:
    dotnet restore
    dotnet build -c Production -o $env:BUILD_ARTIFACTSTAGINGDIRECTORY -f net461
    I’m getting the following error message:
    2016-07-08T01:41:14.3025519Z ##[error]Failed to make the following project runnable: MyProject (.NETFramework,Version=v4.6.1) reason: Could not read assembly info for C:\a\1\s\src\MyProject\bin\Production\net461\win7-x64\Kloud.Training.Api.exe
    2016-07-08T01:41:14.3035518Z ##[error]Process completed with exit code 1 and had 1 error(s) written to the error stream.

Leave a Reply

Your email address will not be published. Required fields are marked *