22 * Copyright (C) Microsoft Corporation. All rights reserved.
33 *--------------------------------------------------------*/
44
5+ import { spawn } from "child_process" ;
6+ import * as fs from "fs" ;
57import fetch , { RequestInit } from "node-fetch" ;
8+ import * as os from "os" ;
9+ import * as path from "path" ;
610import * as semver from "semver" ;
7- import { MessageItem , window } from "vscode" ;
11+ import * as stream from "stream" ;
12+ import * as util from "util" ;
13+ import { MessageItem , ProgressLocation , window } from "vscode" ;
814import { LanguageClient } from "vscode-languageclient" ;
15+ import { SessionManager } from "../session" ;
916import * as Settings from "../settings" ;
17+ import { isMacOS , isWindows } from "../utils" ;
1018import { EvaluateRequestType } from "./Console" ;
1119
20+ const streamPipeline = util . promisify ( stream . pipeline ) ;
21+
1222const PowerShellGitHubReleasesUrl =
1323 "https://api.github.com/repos/PowerShell/PowerShell/releases/latest" ;
1424const PowerShellGitHubPrereleasesUrl =
@@ -67,6 +77,7 @@ interface IUpdateMessageItem extends MessageItem {
6777}
6878
6979export async function InvokePowerShellUpdateCheck (
80+ sessionManager : SessionManager ,
7081 languageServerClient : LanguageClient ,
7182 localVersion : semver . SemVer ,
7283 arch : string ,
@@ -103,7 +114,6 @@ export async function InvokePowerShellUpdateCheck(
103114 return ;
104115 }
105116
106- const isMacOS : boolean = process . platform === "darwin" ;
107117 const result = await window . showInformationMessage (
108118 `${ commonText } Would you like to update the version? ${
109119 isMacOS ? "(Homebrew is required on macOS)" : ""
@@ -116,39 +126,50 @@ export async function InvokePowerShellUpdateCheck(
116126 switch ( result . id ) {
117127 // Yes choice.
118128 case 0 :
119- let script : string ;
120- if ( process . platform === "win32" ) {
129+ if ( isWindows ) {
121130 const msiMatcher = arch === "x86" ?
122131 "win-x86.msi" : "win-x64.msi" ;
123132
124- const assetUrl = release . assets . filter ( ( asset : any ) =>
125- asset . name . indexOf ( msiMatcher ) >= 0 ) [ 0 ] . browser_download_url ;
126-
127- // Grab MSI and run it.
128- // tslint:disable-next-line: max-line-length
129- script = `
130- $randomFileName = [System.IO.Path]::GetRandomFileName()
131- $tmpMsiPath = Microsoft.PowerShell.Management\\Join-Path ([System.IO.Path]::GetTempPath()) "$randomFileName.msi"
132- Microsoft.PowerShell.Utility\\Invoke-RestMethod -Uri ${ assetUrl } -OutFile $tmpMsiPath
133- try
134- {
135- Microsoft.PowerShell.Management\\Start-Process -Wait -Path $tmpMsiPath
136- }
137- finally
138- {
139- Microsoft.PowerShell.Management\\Remove-Item $tmpMsiPath
140- }` ;
133+ const asset = release . assets . filter ( ( a : any ) => a . name . indexOf ( msiMatcher ) >= 0 ) [ 0 ] ;
134+ const msiDownloadPath = path . join ( os . tmpdir ( ) , asset . name ) ;
141135
142- } else if ( isMacOS ) {
143- script = "brew cask upgrade powershell" ;
144- if ( release . isPreview ) {
145- script = "brew cask upgrade powershell-preview" ;
136+ const res = await fetch ( asset . browser_download_url ) ;
137+ if ( ! res . ok ) {
138+ throw new Error ( "unable to fetch MSI" ) ;
146139 }
140+
141+ await window . withProgress ( {
142+ title : "Downloading PowerShell Installer..." ,
143+ location : ProgressLocation . Notification ,
144+ cancellable : false ,
145+ } ,
146+ async ( ) => {
147+ // Streams the body of the request to a file.
148+ await streamPipeline ( res . body , fs . createWriteStream ( msiDownloadPath ) ) ;
149+ } ) ;
150+
151+ // Stop the Integrated Console session because Windows likes to hold on to files.
152+ sessionManager . stop ( ) ;
153+
154+ // Invoke the MSI via cmd.
155+ const msi = spawn ( "msiexec" , [ "/i" , msiDownloadPath ] ) ;
156+
157+ msi . on ( "close" , ( code ) => {
158+ // Now that the MSI is finished, start the Integrated Console session.
159+ sessionManager . start ( ) ;
160+ fs . unlinkSync ( msiDownloadPath ) ;
161+ } ) ;
162+
163+ } else if ( isMacOS ) {
164+ const script = release . isPreview
165+ ? "brew cask upgrade powershell-preview"
166+ : "brew cask upgrade powershell" ;
167+
168+ await languageServerClient . sendRequest ( EvaluateRequestType , {
169+ expression : script ,
170+ } ) ;
147171 }
148172
149- await languageServerClient . sendRequest ( EvaluateRequestType , {
150- expression : script ,
151- } ) ;
152173 break ;
153174
154175 // Never choice.
0 commit comments