install.ps1 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. # Sample script to install Python and pip under Windows
  2. # Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer
  3. # License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
  4. $MINICONDA_URL = "http://repo.continuum.io/miniconda/"
  5. $BASE_URL = "https://www.python.org/ftp/python/"
  6. $GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
  7. $GET_PIP_PATH = "C:\get-pip.py"
  8. $PYTHON_PRERELEASE_REGEX = @"
  9. (?x)
  10. (?<major>\d+)
  11. \.
  12. (?<minor>\d+)
  13. \.
  14. (?<micro>\d+)
  15. (?<prerelease>[a-z]{1,2}\d+)
  16. "@
  17. function Download ($filename, $url) {
  18. $webclient = New-Object System.Net.WebClient
  19. $basedir = $pwd.Path + "\"
  20. $filepath = $basedir + $filename
  21. if (Test-Path $filename) {
  22. Write-Host "Reusing" $filepath
  23. return $filepath
  24. }
  25. # Download and retry up to 3 times in case of network transient errors.
  26. Write-Host "Downloading" $filename "from" $url
  27. $retry_attempts = 2
  28. for ($i = 0; $i -lt $retry_attempts; $i++) {
  29. try {
  30. $webclient.DownloadFile($url, $filepath)
  31. break
  32. }
  33. Catch [Exception]{
  34. Start-Sleep 1
  35. }
  36. }
  37. if (Test-Path $filepath) {
  38. Write-Host "File saved at" $filepath
  39. } else {
  40. # Retry once to get the error message if any at the last try
  41. $webclient.DownloadFile($url, $filepath)
  42. }
  43. return $filepath
  44. }
  45. function ParsePythonVersion ($python_version) {
  46. if ($python_version -match $PYTHON_PRERELEASE_REGEX) {
  47. return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro,
  48. $matches.prerelease)
  49. }
  50. $version_obj = [version]$python_version
  51. return ($version_obj.major, $version_obj.minor, $version_obj.build, "")
  52. }
  53. function DownloadPython ($python_version, $platform_suffix) {
  54. $major, $minor, $micro, $prerelease = ParsePythonVersion $python_version
  55. if (($major -le 2 -and $micro -eq 0) `
  56. -or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) `
  57. ) {
  58. $dir = "$major.$minor"
  59. $python_version = "$major.$minor$prerelease"
  60. } else {
  61. $dir = "$major.$minor.$micro"
  62. }
  63. if ($prerelease) {
  64. if (($major -le 2) `
  65. -or ($major -eq 3 -and $minor -eq 1) `
  66. -or ($major -eq 3 -and $minor -eq 2) `
  67. -or ($major -eq 3 -and $minor -eq 3) `
  68. ) {
  69. $dir = "$dir/prev"
  70. }
  71. }
  72. if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) {
  73. $ext = "msi"
  74. if ($platform_suffix) {
  75. $platform_suffix = ".$platform_suffix"
  76. }
  77. } else {
  78. $ext = "exe"
  79. if ($platform_suffix) {
  80. $platform_suffix = "-$platform_suffix"
  81. }
  82. }
  83. $filename = "python-$python_version$platform_suffix.$ext"
  84. $url = "$BASE_URL$dir/$filename"
  85. $filepath = Download $filename $url
  86. return $filepath
  87. }
  88. function InstallPython ($python_version, $architecture, $python_home) {
  89. Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
  90. if (Test-Path $python_home) {
  91. Write-Host $python_home "already exists, skipping."
  92. return $false
  93. }
  94. if ($architecture -eq "32") {
  95. $platform_suffix = ""
  96. } else {
  97. $platform_suffix = "amd64"
  98. }
  99. $installer_path = DownloadPython $python_version $platform_suffix
  100. $installer_ext = [System.IO.Path]::GetExtension($installer_path)
  101. Write-Host "Installing $installer_path to $python_home"
  102. $install_log = $python_home + ".log"
  103. if ($installer_ext -eq '.msi') {
  104. InstallPythonMSI $installer_path $python_home $install_log
  105. } else {
  106. InstallPythonEXE $installer_path $python_home $install_log
  107. }
  108. if (Test-Path $python_home) {
  109. Write-Host "Python $python_version ($architecture) installation complete"
  110. } else {
  111. Write-Host "Failed to install Python in $python_home"
  112. Get-Content -Path $install_log
  113. Exit 1
  114. }
  115. }
  116. function InstallPythonEXE ($exepath, $python_home, $install_log) {
  117. $install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home"
  118. RunCommand $exepath $install_args
  119. }
  120. function InstallPythonMSI ($msipath, $python_home, $install_log) {
  121. $install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home"
  122. $uninstall_args = "/qn /x $msipath"
  123. RunCommand "msiexec.exe" $install_args
  124. if (-not(Test-Path $python_home)) {
  125. Write-Host "Python seems to be installed else-where, reinstalling."
  126. RunCommand "msiexec.exe" $uninstall_args
  127. RunCommand "msiexec.exe" $install_args
  128. }
  129. }
  130. function RunCommand ($command, $command_args) {
  131. Write-Host $command $command_args
  132. Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru
  133. }
  134. function InstallPip ($python_home) {
  135. $pip_path = $python_home + "\Scripts\pip.exe"
  136. $python_path = $python_home + "\python.exe"
  137. if (-not(Test-Path $pip_path)) {
  138. Write-Host "Installing pip..."
  139. $webclient = New-Object System.Net.WebClient
  140. $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
  141. Write-Host "Executing:" $python_path $GET_PIP_PATH
  142. & $python_path $GET_PIP_PATH
  143. } else {
  144. Write-Host "pip already installed."
  145. }
  146. }
  147. function DownloadMiniconda ($python_version, $platform_suffix) {
  148. if ($python_version -eq "3.4") {
  149. $filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe"
  150. } else {
  151. $filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe"
  152. }
  153. $url = $MINICONDA_URL + $filename
  154. $filepath = Download $filename $url
  155. return $filepath
  156. }
  157. function InstallMiniconda ($python_version, $architecture, $python_home) {
  158. Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
  159. if (Test-Path $python_home) {
  160. Write-Host $python_home "already exists, skipping."
  161. return $false
  162. }
  163. if ($architecture -eq "32") {
  164. $platform_suffix = "x86"
  165. } else {
  166. $platform_suffix = "x86_64"
  167. }
  168. $filepath = DownloadMiniconda $python_version $platform_suffix
  169. Write-Host "Installing" $filepath "to" $python_home
  170. $install_log = $python_home + ".log"
  171. $args = "/S /D=$python_home"
  172. Write-Host $filepath $args
  173. Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
  174. if (Test-Path $python_home) {
  175. Write-Host "Python $python_version ($architecture) installation complete"
  176. } else {
  177. Write-Host "Failed to install Python in $python_home"
  178. Get-Content -Path $install_log
  179. Exit 1
  180. }
  181. }
  182. function InstallMinicondaPip ($python_home) {
  183. $pip_path = $python_home + "\Scripts\pip.exe"
  184. $conda_path = $python_home + "\Scripts\conda.exe"
  185. if (-not(Test-Path $pip_path)) {
  186. Write-Host "Installing pip..."
  187. $args = "install --yes pip"
  188. Write-Host $conda_path $args
  189. Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
  190. } else {
  191. Write-Host "pip already installed."
  192. }
  193. }
  194. function main () {
  195. InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
  196. InstallPip $env:PYTHON
  197. }
  198. main