44//
55
66using System ;
7+ using System . Management . Automation ;
8+ using System . Text ;
79using System . Threading ;
810using System . Threading . Tasks ;
911using Microsoft . Extensions . Logging ;
12+ using Microsoft . PowerShell . EditorServices . Services ;
13+ using Microsoft . PowerShell . EditorServices . Services . PowerShellContext ;
1014using Microsoft . PowerShell . EditorServices . Utility ;
15+ using OmniSharp . Extensions . LanguageServer . Protocol . Models ;
16+ using OmniSharp . Extensions . LanguageServer . Protocol . Server ;
1117
1218namespace Microsoft . PowerShell . EditorServices . Handlers
1319{
1420 internal class GetVersionHandler : IGetVersionHandler
1521 {
22+ private static readonly Version s_desiredPackageManagementVersion = new Version ( 1 , 4 , 6 ) ;
23+
1624 private readonly ILogger < GetVersionHandler > _logger ;
25+ private readonly PowerShellContextService _powerShellContextService ;
26+ private readonly ILanguageServer _languageServer ;
1727
18- public GetVersionHandler ( ILoggerFactory factory )
28+ public GetVersionHandler ( ILoggerFactory factory , PowerShellContextService powerShellContextService , ILanguageServer languageServer )
1929 {
2030 _logger = factory . CreateLogger < GetVersionHandler > ( ) ;
31+ _powerShellContextService = powerShellContextService ;
32+ _languageServer = languageServer ;
2133 }
2234
23- public Task < PowerShellVersion > Handle ( GetVersionParams request , CancellationToken cancellationToken )
35+ public async Task < PowerShellVersion > Handle ( GetVersionParams request , CancellationToken cancellationToken )
2436 {
2537 var architecture = PowerShellProcessArchitecture . Unknown ;
2638 // This should be changed to using a .NET call sometime in the future... but it's just for logging purposes.
@@ -37,13 +49,82 @@ public Task<PowerShellVersion> Handle(GetVersionParams request, CancellationToke
3749 }
3850 }
3951
40- return Task . FromResult ( new PowerShellVersion
52+ PSCommand getModule = new PSCommand ( ) . AddCommand ( "Get-Module" ) . AddParameter ( "ListAvailable" ) . AddParameter ( "Name" , "PackageManagement" ) ;
53+ foreach ( PSModuleInfo module in await _powerShellContextService . ExecuteCommandAsync < PSModuleInfo > ( getModule ) )
54+ {
55+ // The user has a good enough version of PackageManagement
56+ if ( module . Version >= s_desiredPackageManagementVersion )
57+ {
58+ break ;
59+ }
60+
61+ _logger . LogDebug ( "Old version of PackageManagement detected. Attempting to update." ) ;
62+
63+ var takeActionText = "Yes" ;
64+ MessageActionItem messageAction = await _languageServer . Window . ShowMessage ( new ShowMessageRequestParams
65+ {
66+ Message = "You have a version of PackageManagement that causes issues with the PowerShell extension. Would you like to update PackageManagement (You will need to restart the PowerShell extension after)?" ,
67+ Type = MessageType . Warning ,
68+ Actions = new [ ]
69+ {
70+ new MessageActionItem
71+ {
72+ Title = takeActionText
73+ } ,
74+ new MessageActionItem
75+ {
76+ Title = "Not now"
77+ }
78+ }
79+ } ) ;
80+
81+ // If the user chose "Not now" ignore it for the rest of the session.
82+ if ( messageAction ? . Title == takeActionText )
83+ {
84+ // Update PackageManagement
85+ PSCommand psCommand = new PSCommand ( )
86+ . AddCommand ( "Install-Module" )
87+ . AddParameter ( "Name" , "PackageManagement" )
88+ . AddParameter ( "Force" )
89+ . AddParameter ( "MinimumVersion" , s_desiredPackageManagementVersion )
90+ . AddParameter ( "Scope" , "CurrentUser" )
91+ . AddParameter ( "AllowClobber" ) ;
92+
93+ StringBuilder errors = new StringBuilder ( ) ;
94+ await _powerShellContextService . ExecuteCommandAsync < object > ( psCommand , errors , new ExecutionOptions
95+ {
96+ WriteInputToHost = true ,
97+ WriteErrorsToHost = true ,
98+ WriteOutputToHost = true
99+ } ) . ConfigureAwait ( false ) ;
100+
101+ // There were errors installing PackageManagement.
102+ if ( errors . Length == 0 )
103+ {
104+ _languageServer . Window . ShowMessage ( new ShowMessageParams
105+ {
106+ Type = MessageType . Warning ,
107+ Message = "PackageManagement updated, please restart the PowerShell extension."
108+ } ) ;
109+ }
110+ else
111+ {
112+ _languageServer . Window . ShowMessage ( new ShowMessageParams
113+ {
114+ Type = MessageType . Error ,
115+ Message = "PackageManagement update failed. Please run the following command in a Windows PowerShell prompt and restart the PowerShell extension: `Install-Module PackageManagement -Force -AllowClobber`"
116+ } ) ;
117+ }
118+ }
119+ }
120+
121+ return new PowerShellVersion
41122 {
42123 Version = VersionUtils . PSVersionString ,
43124 Edition = VersionUtils . PSEdition ,
44125 DisplayVersion = VersionUtils . PSVersion . ToString ( 2 ) ,
45126 Architecture = architecture . ToString ( )
46- } ) ;
127+ } ;
47128 }
48129
49130 private enum PowerShellProcessArchitecture
0 commit comments