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 ;
17
27
18
- public GetVersionHandler ( ILoggerFactory factory )
28
+ public GetVersionHandler ( ILoggerFactory factory , PowerShellContextService powerShellContextService , ILanguageServer languageServer )
19
29
{
20
30
_logger = factory . CreateLogger < GetVersionHandler > ( ) ;
31
+ _powerShellContextService = powerShellContextService ;
32
+ _languageServer = languageServer ;
21
33
}
22
34
23
- public Task < PowerShellVersion > Handle ( GetVersionParams request , CancellationToken cancellationToken )
35
+ public async Task < PowerShellVersion > Handle ( GetVersionParams request , CancellationToken cancellationToken )
24
36
{
25
37
var architecture = PowerShellProcessArchitecture . Unknown ;
26
38
// 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
37
49
}
38
50
}
39
51
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
41
122
{
42
123
Version = VersionUtils . PSVersionString ,
43
124
Edition = VersionUtils . PSEdition ,
44
125
DisplayVersion = VersionUtils . PSVersion . ToString ( 2 ) ,
45
126
Architecture = architecture . ToString ( )
46
- } ) ;
127
+ } ;
47
128
}
48
129
49
130
private enum PowerShellProcessArchitecture
0 commit comments