|
1 | 1 | // Copyright (c) Microsoft Corporation.
|
2 | 2 | // Licensed under the MIT License.
|
3 | 3 |
|
4 |
| -using System.Linq; |
5 |
| -using System.Threading.Tasks; |
6 |
| -using Microsoft.Extensions.Logging; |
7 |
| -using Microsoft.PowerShell.EditorServices.Logging; |
8 |
| -using Microsoft.PowerShell.EditorServices.Services.DebugAdapter; |
9 | 4 | using System;
|
10 | 5 | using System.Collections.Generic;
|
11 |
| -using System.Collections.ObjectModel; |
| 6 | +using System.Linq; |
12 | 7 | using System.Management.Automation;
|
13 | 8 | using System.Threading;
|
14 |
| -using SMA = System.Management.Automation; |
15 |
| -using Microsoft.PowerShell.EditorServices.Services.PowerShell.Utility; |
16 |
| -using Microsoft.PowerShell.EditorServices.Services.PowerShell.Runspace; |
| 9 | +using System.Threading.Tasks; |
| 10 | +using Microsoft.Extensions.Logging; |
| 11 | +using Microsoft.PowerShell.EditorServices.Services.DebugAdapter; |
| 12 | +using Microsoft.PowerShell.EditorServices.Services.PowerShell.Execution; |
17 | 13 | using Microsoft.PowerShell.EditorServices.Services.PowerShell.Host;
|
| 14 | +using Microsoft.PowerShell.EditorServices.Services.PowerShell.Runspace; |
18 | 15 |
|
19 | 16 | namespace Microsoft.PowerShell.EditorServices.Services.PowerShell.Debugging
|
20 | 17 | {
|
21 | 18 | internal class DscBreakpointCapability
|
22 | 19 | {
|
| 20 | + private static bool? isDscInstalled; |
23 | 21 | private string[] dscResourceRootPaths = Array.Empty<string>();
|
24 |
| - |
25 | 22 | private readonly Dictionary<string, int[]> breakpointsPerFile = new();
|
26 | 23 |
|
27 | 24 | public async Task<IEnumerable<BreakpointDetails>> SetLineBreakpointsAsync(
|
@@ -79,88 +76,57 @@ public bool IsDscResourcePath(string scriptPath)
|
79 | 76 | StringComparison.CurrentCultureIgnoreCase));
|
80 | 77 | }
|
81 | 78 |
|
82 |
| - public static Task<DscBreakpointCapability> GetDscCapabilityAsync( |
| 79 | + public static async Task<DscBreakpointCapability> GetDscCapabilityAsync( |
83 | 80 | ILogger logger,
|
84 | 81 | IRunspaceInfo currentRunspace,
|
85 |
| - PsesInternalHost psesHost, |
86 |
| - CancellationToken cancellationToken) |
| 82 | + PsesInternalHost psesHost) |
87 | 83 | {
|
88 | 84 | // DSC support is enabled only for Windows PowerShell.
|
89 | 85 | if ((currentRunspace.PowerShellVersionDetails.Version.Major >= 6) &&
|
90 | 86 | (currentRunspace.RunspaceOrigin != RunspaceOrigin.DebuggedRunspace))
|
91 | 87 | {
|
92 |
| - return Task.FromResult<DscBreakpointCapability>(null); |
| 88 | + return null; |
93 | 89 | }
|
94 | 90 |
|
95 |
| - DscBreakpointCapability getDscBreakpointCapabilityFunc(SMA.PowerShell pwsh, CancellationToken _) |
| 91 | + if (!isDscInstalled.HasValue) |
96 | 92 | {
|
97 |
| - PSInvocationSettings invocationSettings = new() |
98 |
| - { |
99 |
| - AddToHistory = false, |
100 |
| - ErrorActionPreference = ActionPreference.Stop |
101 |
| - }; |
102 |
| - |
103 |
| - PSModuleInfo dscModule = null; |
104 |
| - try |
105 |
| - { |
106 |
| - dscModule = pwsh.AddCommand("Import-Module") |
107 |
| - .AddArgument(@"C:\Program Files\DesiredStateConfiguration\1.0.0.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psd1") |
108 |
| - .AddParameter("PassThru") |
109 |
| - .InvokeAndClear<PSModuleInfo>(invocationSettings) |
110 |
| - .FirstOrDefault(); |
111 |
| - } |
112 |
| - catch (RuntimeException e) |
113 |
| - { |
114 |
| - logger.LogException("Could not load the DSC module!", e); |
115 |
| - } |
116 |
| - |
117 |
| - if (dscModule == null) |
118 |
| - { |
119 |
| - logger.LogTrace("Side-by-side DSC module was not found."); |
120 |
| - return null; |
121 |
| - } |
122 |
| - |
123 |
| - logger.LogTrace("Side-by-side DSC module found, gathering DSC resource paths..."); |
124 |
| - |
125 |
| - // The module was loaded, add the breakpoint capability |
126 |
| - DscBreakpointCapability capability = new(); |
127 |
| - |
128 |
| - pwsh.AddCommand("Microsoft.PowerShell.Utility\\Write-Host") |
129 |
| - .AddArgument("Gathering DSC resource paths, this may take a while...") |
130 |
| - .InvokeAndClear(invocationSettings); |
131 |
| - |
132 |
| - Collection<string> resourcePaths = null; |
133 |
| - try |
134 |
| - { |
135 |
| - // Get the list of DSC resource paths |
136 |
| - resourcePaths = pwsh.AddCommand("Get-DscResource") |
137 |
| - .AddCommand("Select-Object") |
138 |
| - .AddParameter("ExpandProperty", "ParentPath") |
139 |
| - .InvokeAndClear<string>(invocationSettings); |
140 |
| - } |
141 |
| - catch (CmdletInvocationException e) |
142 |
| - { |
143 |
| - logger.LogException("Get-DscResource failed!", e); |
144 |
| - } |
145 |
| - |
146 |
| - if (resourcePaths == null) |
147 |
| - { |
148 |
| - logger.LogTrace("No DSC resources found."); |
149 |
| - return null; |
150 |
| - } |
| 93 | + PSCommand psCommand = new PSCommand() |
| 94 | + .AddCommand("Import-Module") |
| 95 | + .AddArgument(@"C:\Program Files\DesiredStateConfiguration\1.0.0.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psd1") |
| 96 | + .AddParameter("PassThru"); |
| 97 | + |
| 98 | + IReadOnlyList<PSModuleInfo> dscModule = |
| 99 | + await psesHost.ExecutePSCommandAsync<PSModuleInfo>( |
| 100 | + psCommand, |
| 101 | + CancellationToken.None, |
| 102 | + new PowerShellExecutionOptions { ThrowOnError = false }).ConfigureAwait(false); |
| 103 | + |
| 104 | + isDscInstalled = dscModule.Count > 0; |
| 105 | + logger.LogTrace("Side-by-side DSC module found: " + isDscInstalled.Value); |
| 106 | + } |
151 | 107 |
|
152 |
| - capability.dscResourceRootPaths = resourcePaths.ToArray(); |
| 108 | + if (isDscInstalled.Value) |
| 109 | + { |
| 110 | + PSCommand psCommand = new PSCommand() |
| 111 | + .AddCommand("Get-DscResource") |
| 112 | + .AddCommand("Select-Object") |
| 113 | + .AddParameter("ExpandProperty", "ParentPath"); |
| 114 | + |
| 115 | + IReadOnlyList<string> resourcePaths = |
| 116 | + await psesHost.ExecutePSCommandAsync<string>( |
| 117 | + psCommand, |
| 118 | + CancellationToken.None, |
| 119 | + new PowerShellExecutionOptions { ThrowOnError = false } |
| 120 | + ).ConfigureAwait(false); |
153 | 121 |
|
154 | 122 | logger.LogTrace($"DSC resources found: {resourcePaths.Count}");
|
155 |
| - |
156 |
| - return capability; |
| 123 | + return new DscBreakpointCapability |
| 124 | + { |
| 125 | + dscResourceRootPaths = resourcePaths.ToArray() |
| 126 | + }; |
157 | 127 | }
|
158 | 128 |
|
159 |
| - return psesHost.ExecuteDelegateAsync( |
160 |
| - nameof(getDscBreakpointCapabilityFunc), |
161 |
| - executionOptions: null, |
162 |
| - getDscBreakpointCapabilityFunc, |
163 |
| - cancellationToken); |
| 129 | + return null; |
164 | 130 | }
|
165 | 131 | }
|
166 | 132 | }
|
0 commit comments