4
4
//
5
5
6
6
using System ;
7
+ using System . Management . Automation ;
8
+ using System . Text ;
7
9
using System . Threading ;
8
10
using System . Threading . Tasks ;
9
11
using Microsoft . Extensions . Logging ;
12
+ using Microsoft . PowerShell . EditorServices . Services ;
13
+ using Microsoft . PowerShell . EditorServices . Services . PowerShellContext ;
10
14
using Microsoft . PowerShell . EditorServices . Utility ;
15
+ using OmniSharp . Extensions . LanguageServer . Protocol . Models ;
16
+ using OmniSharp . Extensions . LanguageServer . Protocol . Server ;
11
17
12
18
namespace Microsoft . PowerShell . EditorServices . Handlers
13
19
{
14
20
internal class GetVersionHandler : IGetVersionHandler
15
21
{
22
+ private static readonly Version s_desiredPackageManagementVersion = new Version ( 1 , 4 , 6 ) ;
23
+
16
24
private readonly ILogger < GetVersionHandler > _logger ;
25
+ private readonly PowerShellContextService _powerShellContextService ;
26
+ private readonly ILanguageServer _languageServer ;
27
+ private readonly ConfigurationService _configurationService ;
17
28
18
- public GetVersionHandler ( ILoggerFactory factory )
29
+ public GetVersionHandler (
30
+ ILoggerFactory factory ,
31
+ PowerShellContextService powerShellContextService ,
32
+ ILanguageServer languageServer ,
33
+ ConfigurationService configurationService )
19
34
{
20
35
_logger = factory . CreateLogger < GetVersionHandler > ( ) ;
36
+ _powerShellContextService = powerShellContextService ;
37
+ _languageServer = languageServer ;
38
+ _configurationService = configurationService ;
21
39
}
22
40
23
- public Task < PowerShellVersion > Handle ( GetVersionParams request , CancellationToken cancellationToken )
41
+ public async Task < PowerShellVersion > Handle ( GetVersionParams request , CancellationToken cancellationToken )
24
42
{
25
43
var architecture = PowerShellProcessArchitecture . Unknown ;
26
44
// This should be changed to using a .NET call sometime in the future... but it's just for logging purposes.
@@ -37,13 +55,18 @@ public Task<PowerShellVersion> Handle(GetVersionParams request, CancellationToke
37
55
}
38
56
}
39
57
40
- return Task . FromResult ( new PowerShellVersion
58
+ if ( VersionUtils . IsPS5 && _configurationService . CurrentSettings . PromptToUpdatePackageManagement )
59
+ {
60
+ await CheckPackageManagement ( ) . ConfigureAwait ( false ) ;
61
+ }
62
+
63
+ return new PowerShellVersion
41
64
{
42
65
Version = VersionUtils . PSVersionString ,
43
66
Edition = VersionUtils . PSEdition ,
44
67
DisplayVersion = VersionUtils . PSVersion . ToString ( 2 ) ,
45
68
Architecture = architecture . ToString ( )
46
- } ) ;
69
+ } ;
47
70
}
48
71
49
72
private enum PowerShellProcessArchitecture
@@ -52,5 +75,68 @@ private enum PowerShellProcessArchitecture
52
75
X86 ,
53
76
X64
54
77
}
78
+
79
+ private async Task CheckPackageManagement ( )
80
+ {
81
+ PSCommand getModule = new PSCommand ( ) . AddCommand ( "Get-Module" ) . AddParameter ( "ListAvailable" ) . AddParameter ( "Name" , "PackageManagement" ) ;
82
+ foreach ( PSModuleInfo module in await _powerShellContextService . ExecuteCommandAsync < PSModuleInfo > ( getModule ) )
83
+ {
84
+ // The user has a good enough version of PackageManagement
85
+ if ( module . Version >= s_desiredPackageManagementVersion )
86
+ {
87
+ break ;
88
+ }
89
+
90
+ _logger . LogDebug ( "Old version of PackageManagement detected. Attempting to update." ) ;
91
+
92
+ var takeActionText = "Yes" ;
93
+ MessageActionItem messageAction = await _languageServer . Window . ShowMessage ( new ShowMessageRequestParams
94
+ {
95
+ Message = "You have an older version of PackageManagement known to cause issues with the PowerShell extension. Would you like to update PackageManagement (You will need to restart the PowerShell extension after)?" ,
96
+ Type = MessageType . Warning ,
97
+ Actions = new [ ]
98
+ {
99
+ new MessageActionItem
100
+ {
101
+ Title = takeActionText
102
+ } ,
103
+ new MessageActionItem
104
+ {
105
+ Title = "Not now"
106
+ }
107
+ }
108
+ } ) ;
109
+
110
+ // If the user chose "Not now" ignore it for the rest of the session.
111
+ if ( messageAction ? . Title == takeActionText )
112
+ {
113
+ StringBuilder errors = new StringBuilder ( ) ;
114
+ await _powerShellContextService . ExecuteScriptStringAsync (
115
+ "powershell.exe -NoLogo -NoProfile -Command 'Install-Module -Name PackageManagement -Force -MinimumVersion 1.4.6 -Scope CurrentUser -AllowClobber'" ,
116
+ errors ,
117
+ writeInputToHost : true ,
118
+ writeOutputToHost : true ,
119
+ addToHistory : true ) . ConfigureAwait ( false ) ;
120
+
121
+ // There were errors installing PackageManagement.
122
+ if ( errors . Length == 0 )
123
+ {
124
+ _languageServer . Window . ShowMessage ( new ShowMessageParams
125
+ {
126
+ Type = MessageType . Info ,
127
+ Message = "PackageManagement updated, If you already had PackageManagement loaded in your session, please restart the PowerShell extension."
128
+ } ) ;
129
+ }
130
+ else
131
+ {
132
+ _languageServer . Window . ShowMessage ( new ShowMessageParams
133
+ {
134
+ Type = MessageType . Error ,
135
+ Message = "PackageManagement update failed. Please run the following command in a Windows PowerShell prompt and restart the PowerShell extension: `Install-Module PackageManagement -Force -AllowClobber -MinimumVersion 1.4.6`"
136
+ } ) ;
137
+ }
138
+ }
139
+ }
140
+ }
55
141
}
56
142
}
0 commit comments