-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall_rust.ps1
More file actions
143 lines (122 loc) · 5.61 KB
/
install_rust.ps1
File metadata and controls
143 lines (122 loc) · 5.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# Run with:
# powershell -ExecutionPolicy Unrestricted -File install_rust.ps1
function Make-Directory {
param (
$Path
)
# Create directory
# -Force - similar to "mkdir --parents" to create nested directories
# https://stackoverflow.com/a/20983885
# -ErrorAction SilentlyContinue - parents will also not error out if directory already exist
# https://serverfault.com/a/336139
New-Item -Path "$Path" -Type directory -Force -ErrorAction SilentlyContinue > $null
}
function Update-Path {
$env:Path = ((Get-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment").GetValue("Path", "") + ";" + (Get-Item -Path "HKCU:\Environment").GetValue("Path", "")).Replace(";;", ",")
}
function Add-Path {
param (
$Destination,
[bool]$Prepend
)
$expanded = cmd /c "echo $Destination"
Update-Path
if ((Test-Path $expanded) -And ! ($env:Path.Contains($expanded))) {
# https://superuser.com/a/1341040
$reg = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
if ("$expanded".Contains($env:USERPROFILE)) {
$reg = "HKCU:\Environment"
}
$path = (Get-Item -Path $reg).GetValue("Path", "", "DoNotExpandEnvironmentNames")
$collapsed = $Destination.
Replace("$env:APPDATA", "%APPDATA%").
Replace("$env:LOCALAPPDATA", "%LOCALAPPDATA%").
Replace("$env:USERPROFILE", "%USERPROFILE%").
Replace("$env:PUBLIC", "%PUBLIC%").
Replace("$env:ProgramData", "%ProgramData%").
Replace("$env:CommonProgramFiles", "%CommonProgramFiles%").
Replace("${env:CommonProgramFiles(x86)}", "%CommonProgramFiles(x86)%").
Replace("$env:ProgramFiles", "%ProgramFiles%").
Replace("${env:ProgramFiles(x86)}", "%ProgramFiles(x86)%").
Replace("$env:DriverData", "%DriverData%").
Replace("$env:SystemRoot", "%SystemRoot%").
Replace("$env:SystemDrive", "%SystemDrive%")
if (! $Prepend) {
$path = ($path + ";" + $collapsed).Replace(";;", ";")
"Appending Path Environment variable: $collapsed" | Out-Host
} else {
$path = ($collapsed + ";" + $path).Replace(";;", ";")
"Prepending Path Environment variable: $collapsed" | Out-Host
}
# Use PS's New-ItemProperty because older PS errors out on RegistryKey.SetValue's overload with RegistryValueKind.ExpandString
New-ItemProperty -Path "$reg" -Name "Path" -Value "$path" -PropertyType ExpandString -Force > $null
Update-Path
}
}
function Install-Msvc {
# Visual Studio does not add to PATH as the IDE will load vcvarsall.bat or Launch-VsDevShell.ps1
# Look for both ${env:ProgramFiles(x86)} and ${env:ProgramFiles}
# because MS BuildTools is in ${env:ProgramFiles(x86)} while the rest is in ${env:ProgramFiles}
# @todo fix the security exception for invalid path
[string[]] $vswhere = (Get-ChildItem -Path "${env:ProgramFiles(x86)}\Microsoft Visual Studio" -Filter "vswhere.exe" -Recurse).FullName
if (! $vswhere) {
$vswhere = (Get-ChildItem -Path "${env:ProgramFiles}\Microsoft Visual Studio" -Filter "vswhere.exe" -Recurse).FullName
}
if (! $vswhere) {
$file = "vs_BuildTools.exe"
if (! (Test-Path $file)) {
"Downloading MSVC..." | Out-Host
Invoke-WebRequest -Uri "https://aka.ms/vs/stable/vs_BuildTools.exe" -OutFile $file -UseBasicParsing 2> $null
}
if (Test-Path $file) {
"Installing MSVC..." | Out-Host
Start-Process $file -ArgumentList @(
"--add Microsoft.VisualStudio.Workload.VCTools",
"--includeRecommended",
"--includeOptional",
"--passive",
"--norestart",
"--wait"
) -Wait -NoNewWindow -PassThru > $null
}
}
}
function Install-Rustup {
if (! (Get-Command cargo -ErrorAction SilentlyContinue)) {
$file = "rustup-init.exe"
if (! (Test-Path $file)) {
"Downloading rustup..." | Out-Host
# https://www.rust-lang.org/tools/install
Invoke-WebRequest -Uri "https://win.rustup.rs/x86_64" -OutFile $file -UseBasicParsing 2> $null
}
if (Test-Path $file) {
"Installing rustup..." | Out-Host
Start-Process $file -ArgumentList "-y" -Wait -NoNewWindow -PassThru > $null
Add-Path "$env:USERPROFILE\.cargo\bin" $true
}
}
}
function Main {
Update-Path
Install-Msvc
Install-Rustup
}
Make-Directory $env:USERPROFILE\Downloads
Push-Location $env:USERPROFILE\Downloads
# https://serverfault.com/a/95464
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if ($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
# @todo only Install-Msvc needs admin privilege, try to limit administrator scope...
$ret = Main
# The built-in `Pause` function is ugly, use the cmd version instead
# https://stackoverflow.com/a/20886446
cmd /c pause
} else {
Write-Host -ForegroundColor red "This script ($PSCommandPath) needs to run as Administrator!"
# Relaunching as Administrator, -Verb runAs is not compatible with -NoNewWindow -PassThru,
# so a new console will pop up
# Nothing could be captured either, especially the exit code, the workaround is to write-then-read a temp file
Start-Process powershell -ArgumentList "-ExecutionPolicy Unrestricted -File $PSCommandPath" -Verb runAs -Wait
}
Pop-Location
return $ret