Skip to content

Commit 62f2763

Browse files
install-module doesn't work...
1 parent 6e3fa17 commit 62f2763

File tree

3 files changed

+106
-12
lines changed

3 files changed

+106
-12
lines changed

src/PowerShellEditorServices/Services/PowerShellContext/Handlers/GetCommandHandler.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@
33
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
44
//
55

6+
using System;
67
using System.Collections.Generic;
78
using System.Management.Automation;
9+
using System.Text;
810
using System.Threading;
911
using System.Threading.Tasks;
1012
using Microsoft.Extensions.Logging;
1113
using Microsoft.PowerShell.EditorServices.Services;
1214
using MediatR;
1315
using OmniSharp.Extensions.JsonRpc;
16+
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
17+
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
1418

1519
namespace Microsoft.PowerShell.EditorServices.Handlers
1620
{
@@ -48,29 +52,38 @@ public async Task<List<PSCommandMessage>> Handle(GetCommandParams request, Cance
4852
PSCommand psCommand = new PSCommand();
4953

5054
// Executes the following:
51-
// Get-Command -CommandType Function,Cmdlet,ExternalScript | Select-Object -Property Name,ModuleName | Sort-Object -Property Name
55+
// Get-Command -CommandType Function,Cmdlet,ExternalScript | Sort-Object -Property Name
5256
psCommand
5357
.AddCommand("Microsoft.PowerShell.Core\\Get-Command")
5458
.AddParameter("CommandType", new[] { "Function", "Cmdlet", "ExternalScript" })
55-
.AddCommand("Microsoft.PowerShell.Utility\\Select-Object")
56-
.AddParameter("Property", new[] { "Name", "ModuleName" })
5759
.AddCommand("Microsoft.PowerShell.Utility\\Sort-Object")
5860
.AddParameter("Property", "Name");
5961

60-
IEnumerable<PSObject> result = await _powerShellContextService.ExecuteCommandAsync<PSObject>(psCommand).ConfigureAwait(false);
62+
IEnumerable<CommandInfo> result = await _powerShellContextService.ExecuteCommandAsync<CommandInfo>(psCommand).ConfigureAwait(false);
6163

6264
var commandList = new List<PSCommandMessage>();
6365
if (result != null)
6466
{
65-
foreach (dynamic command in result)
67+
foreach (CommandInfo command in result)
6668
{
69+
// Get the default ParameterSet
70+
string defaultParameterSet = null;
71+
foreach (CommandParameterSetInfo parameterSetInfo in command.ParameterSets)
72+
{
73+
if (parameterSetInfo.IsDefault)
74+
{
75+
defaultParameterSet = parameterSetInfo.Name;
76+
break;
77+
}
78+
}
79+
6780
commandList.Add(new PSCommandMessage
6881
{
6982
Name = command.Name,
7083
ModuleName = command.ModuleName,
7184
Parameters = command.Parameters,
7285
ParameterSets = command.ParameterSets,
73-
DefaultParameterSet = command.DefaultParameterSet
86+
DefaultParameterSet = defaultParameterSet
7487
});
7588
}
7689
}

src/PowerShellEditorServices/Services/PowerShellContext/Handlers/GetVersionHandler.cs

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,35 @@
44
//
55

66
using System;
7+
using System.Management.Automation;
8+
using System.Text;
79
using System.Threading;
810
using System.Threading.Tasks;
911
using Microsoft.Extensions.Logging;
12+
using Microsoft.PowerShell.EditorServices.Services;
13+
using Microsoft.PowerShell.EditorServices.Services.PowerShellContext;
1014
using Microsoft.PowerShell.EditorServices.Utility;
15+
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
16+
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
1117

1218
namespace 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

test/PowerShellEditorServices.Test.E2E/LanguageServerProtocolMessageTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,8 +1004,8 @@ await LanguageClient.SendRequest<EvaluateResponseBody>(
10041004
[Fact]
10051005
public async Task CanSendGetCommandRequest()
10061006
{
1007-
List<PSCommandMessage> pSCommandMessages =
1008-
await LanguageClient.SendRequest<List<PSCommandMessage>>("powerShell/getCommand", new GetCommandParams());
1007+
List<object> pSCommandMessages =
1008+
await LanguageClient.SendRequest<List<object>>("powerShell/getCommand", new GetCommandParams());
10091009

10101010
Assert.NotEmpty(pSCommandMessages);
10111011
// There should be at least 20 commands or so.

0 commit comments

Comments
 (0)