Skip to content

Instantly share code, notes, and snippets.

@rexxiang
Last active April 18, 2017 02:28
Show Gist options
  • Save rexxiang/353f824e96ad6bc69abb8f307cef2ac9 to your computer and use it in GitHub Desktop.
Save rexxiang/353f824e96ad6bc69abb8f307cef2ac9 to your computer and use it in GitHub Desktop.

Revisions

  1. rexxiang revised this gist Apr 18, 2017. No changes.
  2. rexxiang created this gist Apr 18, 2017.
    71 changes: 71 additions & 0 deletions vs2017-offline-downloader.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,71 @@
    Param(
    [string]$OfflineDir = ".\vs2017offline"
    )

    Set-Location $PSScriptRoot

    $installerDir = ".\.vs2017.installer"
    $installer = "$installerDir\vs_enterprise.exe"

    # download installer
    if (!(Test-Path $installer)) {
    New-Item -Path $installerDir -ItemType Directory -Force
    Invoke-WebRequest "https://aka.ms/vs/15/release/vs_enterprise.exe" -OutFile $installer
    }

    if (!(Test-Path $offlineDir)) {
    New-Item -path $offlineDir -ItemType Directory -Force
    }

    # start installer
    Start-Process $installer -ArgumentList @("--layout $offlineDir", '--all', '--lang en-US') -Wait

    # cleanup expired packages
    start-job -ArgumentList @($PSScriptRoot, $OfflineDir) -ScriptBlock {
    param($Root, $OfflineDir)

    $OfflineDir = [System.IO.Path]::Combine($Root, $OfflineDir)
    Write-Host Offline files are in $OfflineDir

    $source = @"
    using System;
    using System.IO;
    using System.Linq;
    public class DuplicationRemover {
    public static void Remove(string offlineDir) {
    var dirs = Directory.GetDirectories(offlineDir);
    var info =
    from path in dirs
    let dir = Path.GetFileName(path)
    let parts = dir.Split(new [] {','}, StringSplitOptions.RemoveEmptyEntries)
    where parts.Length > 1
    let name = parts[0]
    let version = parts.FirstOrDefault(p => p.StartsWith("version="))
    let chip = parts.FirstOrDefault(p => p.StartsWith("chip="))
    let language = parts.FirstOrDefault(p => p.StartsWith("language="))
    where version != null
    select new { name, version, chip, language, parts, path, };
    var r =
    from i1 in info
    from i2 in info
    where
    i1.name == i2.name
    && i1.chip == i2.chip
    && i1.language == i2.language
    && i1.version.CompareTo(i2.version) > 0
    select new { new_path = i1.path, old_path = i2.path };
    foreach(var dir in r) {
    Directory.Delete(dir.old_path, true);
    }
    }
    }
    "@

    Add-Type -TypeDefinition $source -ReferencedAssemblies ("System", "System.Core") -Language CSharp

    [DuplicationRemover]::Remove($OfflineDir)
    } | Receive-Job -Wait -AutoRemoveJob