Skip to content

Commit 23b3d47

Browse files
committed
Merge pull request #184 from PowerShell/daviwil/finish-ps3and4-support
Finish PowerShell v3 and v4 support
2 parents a1e6dbc + c5d13f2 commit 23b3d47

File tree

8 files changed

+243
-83
lines changed

8 files changed

+243
-83
lines changed

src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,14 @@ protected Task HandlePauseRequest(
295295
object pauseParams,
296296
RequestContext<object> requestContext)
297297
{
298-
editorSession.DebugService.Break();
298+
try
299+
{
300+
editorSession.DebugService.Break();
301+
}
302+
catch (NotSupportedException e)
303+
{
304+
return requestContext.SendError(e.Message);
305+
}
299306

300307
// This request is responded to by sending the "stopped" event
301308
return Task.FromResult(true);

src/PowerShellEditorServices/PowerShellEditorServices.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,12 @@
9898
<Compile Include="Console\ChoiceDetails.cs" />
9999
<Compile Include="Session\EditorSession.cs" />
100100
<Compile Include="Console\IConsoleHost.cs" />
101+
<Compile Include="Session\IVersionSpecificOperations.cs" />
101102
<Compile Include="Session\OutputType.cs" />
102103
<Compile Include="Session\OutputWrittenEventArgs.cs" />
104+
<Compile Include="Session\PowerShell3Operations.cs" />
105+
<Compile Include="Session\PowerShell4Operations.cs" />
106+
<Compile Include="Session\PowerShell5Operations.cs" />
103107
<Compile Include="Session\PowerShellExecutionResult.cs" />
104108
<Compile Include="Session\PowerShellContext.cs" />
105109
<Compile Include="Session\PowerShellContextState.cs" />

src/PowerShellEditorServices/Session/EditorSession.cs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55

66
using Microsoft.PowerShell.EditorServices.Console;
77
using Microsoft.PowerShell.EditorServices.Utility;
8+
using System;
89
using System.IO;
910
using System.Management.Automation;
1011
using System.Management.Automation.Runspaces;
12+
using System.Reflection;
1113
using System.Threading;
1214

1315
namespace Microsoft.PowerShell.EditorServices
@@ -66,17 +68,34 @@ public void StartSession()
6668
this.DebugService = new DebugService(this.PowerShellContext);
6769
this.ConsoleService = new ConsoleService(this.PowerShellContext);
6870

69-
// AnalysisService will throw FileNotFoundException if
70-
// Script Analyzer binaries are not included.
71-
try
71+
// Only enable the AnalysisService if the machine has PowerShell
72+
// v5 installed. Script Analyzer works on earlier PowerShell
73+
// versions but our hard dependency on their binaries complicates
74+
// the deployment and assembly loading since we would have to
75+
// conditionally load the binaries for v3/v4 support. This problem
76+
// will be solved in the future by using Script Analyzer as a
77+
// module rather than an assembly dependency.
78+
if (this.PowerShellContext.PowerShellVersion.Major >= 5)
7279
{
73-
this.AnalysisService = new AnalysisService();
80+
// AnalysisService will throw FileNotFoundException if
81+
// Script Analyzer binaries are not included.
82+
try
83+
{
84+
this.AnalysisService = new AnalysisService();
85+
}
86+
catch (FileNotFoundException)
87+
{
88+
Logger.Write(
89+
LogLevel.Warning,
90+
"Script Analyzer binaries not found, AnalysisService will be disabled.");
91+
}
7492
}
75-
catch (FileNotFoundException)
93+
else
7694
{
7795
Logger.Write(
78-
LogLevel.Warning,
79-
"Script Analyzer binaries not found, AnalysisService will be disabled.");
96+
LogLevel.Normal,
97+
"Script Analyzer cannot be loaded due to unsupported PowerShell version " +
98+
this.PowerShellContext.PowerShellVersion.ToString());
8099
}
81100

82101
// Create a workspace to contain open files
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System.Collections.Generic;
7+
using System.Management.Automation;
8+
using System.Management.Automation.Runspaces;
9+
10+
namespace Microsoft.PowerShell.EditorServices.Session
11+
{
12+
internal interface IVersionSpecificOperations
13+
{
14+
void ConfigureDebugger(Runspace runspace);
15+
16+
void PauseDebugger(Runspace runspace);
17+
18+
IEnumerable<TResult> ExecuteCommandInDebugger<TResult>(
19+
PowerShellContext powerShellContext,
20+
Runspace currentRunspace,
21+
PSCommand psCommand,
22+
bool sendOutputToHost);
23+
}
24+
}
25+
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using System.Management.Automation;
10+
using System.Management.Automation.Runspaces;
11+
12+
namespace Microsoft.PowerShell.EditorServices.Session
13+
{
14+
internal class PowerShell3Operations : IVersionSpecificOperations
15+
{
16+
public void ConfigureDebugger(Runspace runspace)
17+
{
18+
// The debugger has no SetDebugMode in PowerShell v3.
19+
}
20+
21+
public void PauseDebugger(Runspace runspace)
22+
{
23+
// The debugger cannot be paused in PowerShell v3.
24+
throw new NotSupportedException("Debugger cannot be paused in PowerShell v3");
25+
}
26+
27+
public IEnumerable<TResult> ExecuteCommandInDebugger<TResult>(
28+
PowerShellContext powerShellContext,
29+
Runspace currentRunspace,
30+
PSCommand psCommand,
31+
bool sendOutputToHost)
32+
{
33+
IEnumerable<TResult> executionResult = null;
34+
35+
using (var nestedPipeline = currentRunspace.CreateNestedPipeline())
36+
{
37+
foreach (var command in psCommand.Commands)
38+
{
39+
nestedPipeline.Commands.Add(command);
40+
}
41+
42+
executionResult =
43+
nestedPipeline
44+
.Invoke()
45+
.Select(pso => pso.BaseObject)
46+
.Cast<TResult>();
47+
}
48+
49+
// Write the output to the host if necessary
50+
if (sendOutputToHost)
51+
{
52+
foreach (var line in executionResult)
53+
{
54+
powerShellContext.WriteOutput(line.ToString(), true);
55+
}
56+
}
57+
58+
return executionResult;
59+
}
60+
}
61+
}
62+
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using System.Management.Automation;
10+
using System.Management.Automation.Runspaces;
11+
12+
namespace Microsoft.PowerShell.EditorServices.Session
13+
{
14+
internal class PowerShell4Operations : IVersionSpecificOperations
15+
{
16+
public void ConfigureDebugger(Runspace runspace)
17+
{
18+
#if !PowerShellv3
19+
runspace.Debugger.SetDebugMode(DebugModes.LocalScript | DebugModes.RemoteScript);
20+
#endif
21+
}
22+
23+
public virtual void PauseDebugger(Runspace runspace)
24+
{
25+
// The debugger cannot be paused in PowerShell v4.
26+
throw new NotSupportedException("Debugger cannot be paused in PowerShell v4");
27+
}
28+
29+
public IEnumerable<TResult> ExecuteCommandInDebugger<TResult>(
30+
PowerShellContext powerShellContext,
31+
Runspace currentRunspace,
32+
PSCommand psCommand,
33+
bool sendOutputToHost)
34+
{
35+
PSDataCollection<PSObject> outputCollection = new PSDataCollection<PSObject>();
36+
37+
#if !PowerShellv3
38+
if (sendOutputToHost)
39+
{
40+
outputCollection.DataAdded +=
41+
(obj, e) =>
42+
{
43+
for (int i = e.Index; i < outputCollection.Count; i++)
44+
{
45+
powerShellContext.WriteOutput(
46+
outputCollection[i].ToString(),
47+
true);
48+
}
49+
};
50+
}
51+
52+
DebuggerCommandResults commandResults =
53+
currentRunspace.Debugger.ProcessCommand(
54+
psCommand,
55+
outputCollection);
56+
#endif
57+
58+
return
59+
outputCollection
60+
.Select(pso => pso.BaseObject)
61+
.Cast<TResult>();
62+
}
63+
}
64+
}
65+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
//
5+
6+
using System.Management.Automation.Runspaces;
7+
8+
namespace Microsoft.PowerShell.EditorServices.Session
9+
{
10+
internal class PowerShell5Operations : PowerShell4Operations
11+
{
12+
public override void PauseDebugger(Runspace runspace)
13+
{
14+
#if !PowerShellv3 && !PowerShellv4
15+
runspace.Debugger.SetDebuggerStepMode(true);
16+
#endif
17+
}
18+
}
19+
}
20+

0 commit comments

Comments
 (0)