@@ -26,6 +26,9 @@ public class AnalysisService : IDisposable
26
26
27
27
private Runspace analysisRunspace ;
28
28
private PSModuleInfo scriptAnalyzerModuleInfo ;
29
+ private Object runspaceLock ;
30
+ private string [ ] activeRules ;
31
+ private string settingsPath ;
29
32
30
33
/// <summary>
31
34
/// Defines the list of Script Analyzer rules to include by default if
@@ -54,16 +57,39 @@ public class AnalysisService : IDisposable
54
57
/// <summary>
55
58
/// Set of PSScriptAnalyzer rules used for analysis
56
59
/// </summary>
57
- public string [ ] ActiveRules { get ; set ; }
60
+ public string [ ] ActiveRules
61
+ {
62
+ get
63
+ {
64
+ return activeRules ;
65
+ }
66
+
67
+ set
68
+ {
69
+ lock ( runspaceLock )
70
+ {
71
+ activeRules = value ;
72
+ }
73
+ }
74
+ }
58
75
59
76
/// <summary>
60
77
/// Gets or sets the path to a settings file (.psd1)
61
78
/// containing PSScriptAnalyzer settings.
62
79
/// </summary>
63
80
public string SettingsPath
64
81
{
65
- get ;
66
- set ;
82
+ get
83
+ {
84
+ return settingsPath ;
85
+ }
86
+ set
87
+ {
88
+ lock ( runspaceLock )
89
+ {
90
+ settingsPath = value ;
91
+ }
92
+ }
67
93
}
68
94
69
95
#endregion
@@ -80,6 +106,7 @@ public AnalysisService(IConsoleHost consoleHost, string settingsPath = null)
80
106
{
81
107
try
82
108
{
109
+ this . runspaceLock = new Object ( ) ;
83
110
this . SettingsPath = settingsPath ;
84
111
this . analysisRunspace = RunspaceFactory . CreateRunspace ( InitialSessionState . CreateDefault2 ( ) ) ;
85
112
this . analysisRunspace . ThreadOptions = PSThreadOptions . ReuseThread ;
@@ -117,10 +144,10 @@ public ScriptFileMarker[] GetSemanticMarkers(ScriptFile file)
117
144
Task . Factory . StartNew < ScriptFileMarker [ ] > (
118
145
( ) =>
119
146
{
120
- return
121
- GetDiagnosticRecords ( file )
122
- . Select ( ScriptFileMarker . FromDiagnosticRecord )
123
- . ToArray ( ) ;
147
+ return
148
+ GetDiagnosticRecords ( file )
149
+ . Select ( ScriptFileMarker . FromDiagnosticRecord )
150
+ . ToArray ( ) ;
124
151
} ,
125
152
CancellationToken . None ,
126
153
TaskCreationOptions . None ,
@@ -143,13 +170,16 @@ public IEnumerable<string> GetPSScriptAnalyzerRules()
143
170
List < string > ruleNames = new List < string > ( ) ;
144
171
if ( scriptAnalyzerModuleInfo != null )
145
172
{
146
- using ( var ps = System . Management . Automation . PowerShell . Create ( ) )
173
+ lock ( runspaceLock )
147
174
{
148
- ps . Runspace = this . analysisRunspace ;
149
- var ruleObjects = ps . AddCommand ( "Get-ScriptAnalyzerRule" ) . Invoke ( ) ;
150
- foreach ( var rule in ruleObjects )
175
+ using ( var ps = System . Management . Automation . PowerShell . Create ( ) )
151
176
{
152
- ruleNames . Add ( ( string ) rule . Members [ "RuleName" ] . Value ) ;
177
+ ps . Runspace = this . analysisRunspace ;
178
+ var ruleObjects = ps . AddCommand ( "Get-ScriptAnalyzerRule" ) . Invoke ( ) ;
179
+ foreach ( var rule in ruleObjects )
180
+ {
181
+ ruleNames . Add ( ( string ) rule . Members [ "RuleName" ] . Value ) ;
182
+ }
153
183
}
154
184
}
155
185
}
@@ -175,38 +205,33 @@ public void Dispose()
175
205
#region Private Methods
176
206
private void FindPSScriptAnalyzer ( )
177
207
{
178
- using ( var ps = System . Management . Automation . PowerShell . Create ( ) )
208
+ lock ( runspaceLock )
179
209
{
180
- ps . Runspace = this . analysisRunspace ;
181
-
182
- ps . AddCommand ( "Get-Module" )
183
- . AddParameter ( "ListAvailable" )
184
- . AddParameter ( "Name" , "PSScriptAnalyzer" ) ;
185
-
186
- ps . AddCommand ( "Sort-Object" )
187
- . AddParameter ( "Descending" )
188
- . AddParameter ( "Property" , "Version" ) ;
189
-
190
- ps . AddCommand ( "Select-Object" )
191
- . AddParameter ( "First" , 1 ) ;
210
+ using ( var ps = System . Management . Automation . PowerShell . Create ( ) )
211
+ {
212
+ ps . Runspace = this . analysisRunspace ;
192
213
193
- var modules = ps . Invoke ( ) ;
214
+ var modules = ps . AddCommand ( "Get-Module" )
215
+ . AddParameter ( "List" )
216
+ . AddParameter ( "Name" , "PSScriptAnalyzer" )
217
+ . Invoke ( ) ;
194
218
195
- var psModule = modules == null ? null : modules . FirstOrDefault ( ) ;
196
- if ( psModule != null )
197
- {
198
- scriptAnalyzerModuleInfo = psModule . ImmediateBaseObject as PSModuleInfo ;
199
- Logger . Write (
200
- LogLevel . Normal ,
201
- string . Format (
202
- "PSScriptAnalyzer found at {0}" ,
203
- scriptAnalyzerModuleInfo . Path ) ) ;
204
- }
205
- else
206
- {
207
- Logger . Write (
208
- LogLevel . Normal ,
209
- "PSScriptAnalyzer module was not found." ) ;
219
+ var psModule = modules == null ? null : modules . FirstOrDefault ( ) ;
220
+ if ( psModule != null )
221
+ {
222
+ scriptAnalyzerModuleInfo = psModule . ImmediateBaseObject as PSModuleInfo ;
223
+ Logger . Write (
224
+ LogLevel . Normal ,
225
+ string . Format (
226
+ "PSScriptAnalyzer found at {0}" ,
227
+ scriptAnalyzerModuleInfo . Path ) ) ;
228
+ }
229
+ else
230
+ {
231
+ Logger . Write (
232
+ LogLevel . Normal ,
233
+ "PSScriptAnalyzer module was not found." ) ;
234
+ }
210
235
}
211
236
}
212
237
}
@@ -215,25 +240,28 @@ private void ImportPSScriptAnalyzer()
215
240
{
216
241
if ( scriptAnalyzerModuleInfo != null )
217
242
{
218
- using ( var ps = System . Management . Automation . PowerShell . Create ( ) )
243
+ lock ( runspaceLock )
219
244
{
220
- ps . Runspace = this . analysisRunspace ;
245
+ using ( var ps = System . Management . Automation . PowerShell . Create ( ) )
246
+ {
247
+ ps . Runspace = this . analysisRunspace ;
221
248
222
- var module = ps . AddCommand ( "Import-Module" )
223
- . AddParameter ( "ModuleInfo" , scriptAnalyzerModuleInfo )
224
- . AddParameter ( "PassThru" )
225
- . Invoke ( ) ;
249
+ var module = ps . AddCommand ( "Import-Module" )
250
+ . AddParameter ( "ModuleInfo" , scriptAnalyzerModuleInfo )
251
+ . AddParameter ( "PassThru" )
252
+ . Invoke ( ) ;
226
253
227
- if ( module == null )
228
- {
229
- this . scriptAnalyzerModuleInfo = null ;
230
- Logger . Write ( LogLevel . Warning ,
231
- String . Format ( "Cannot Import PSScriptAnalyzer: {0}" ) ) ;
232
- }
233
- else
234
- {
235
- Logger . Write ( LogLevel . Normal ,
236
- String . Format ( "Successfully imported PSScriptAnalyzer" ) ) ;
254
+ if ( module == null )
255
+ {
256
+ this . scriptAnalyzerModuleInfo = null ;
257
+ Logger . Write ( LogLevel . Warning ,
258
+ String . Format ( "Cannot Import PSScriptAnalyzer: {0}" ) ) ;
259
+ }
260
+ else
261
+ {
262
+ Logger . Write ( LogLevel . Normal ,
263
+ String . Format ( "Successfully imported PSScriptAnalyzer" ) ) ;
264
+ }
237
265
}
238
266
}
239
267
}
@@ -268,28 +296,31 @@ private IEnumerable<PSObject> GetDiagnosticRecords(ScriptFile file)
268
296
269
297
if ( this . scriptAnalyzerModuleInfo != null )
270
298
{
271
- using ( var powerShell = System . Management . Automation . PowerShell . Create ( ) )
299
+ lock ( runspaceLock )
272
300
{
273
- powerShell . Runspace = this . analysisRunspace ;
274
- Logger . Write (
275
- LogLevel . Verbose ,
276
- String . Format ( "Running PSScriptAnalyzer against {0}" , file . FilePath ) ) ;
301
+ using ( var powerShell = System . Management . Automation . PowerShell . Create ( ) )
302
+ {
303
+ powerShell . Runspace = this . analysisRunspace ;
304
+ Logger . Write (
305
+ LogLevel . Verbose ,
306
+ String . Format ( "Running PSScriptAnalyzer against {0}" , file . FilePath ) ) ;
277
307
278
- powerShell
279
- . AddCommand ( "Invoke-ScriptAnalyzer" )
280
- . AddParameter ( "ScriptDefinition" , file . Contents ) ;
308
+ powerShell
309
+ . AddCommand ( "Invoke-ScriptAnalyzer" )
310
+ . AddParameter ( "ScriptDefinition" , file . Contents ) ;
281
311
282
- // Use a settings file if one is provided, otherwise use the default rule list.
283
- if ( ! string . IsNullOrWhiteSpace ( this . SettingsPath ) )
284
- {
285
- powerShell . AddParameter ( "Settings" , this . SettingsPath ) ;
286
- }
287
- else
288
- {
289
- powerShell . AddParameter ( "IncludeRule" , ActiveRules ) ;
290
- }
312
+ // Use a settings file if one is provided, otherwise use the default rule list.
313
+ if ( ! string . IsNullOrWhiteSpace ( this . SettingsPath ) )
314
+ {
315
+ powerShell . AddParameter ( "Settings" , this . SettingsPath ) ;
316
+ }
317
+ else
318
+ {
319
+ powerShell . AddParameter ( "IncludeRule" , activeRules ) ;
320
+ }
291
321
292
- diagnosticRecords = powerShell . Invoke ( ) ;
322
+ diagnosticRecords = powerShell . Invoke ( ) ;
323
+ }
293
324
}
294
325
}
295
326
0 commit comments