@@ -26,6 +26,9 @@ public class AnalysisService : IDisposable
2626
2727 private Runspace analysisRunspace ;
2828 private PSModuleInfo scriptAnalyzerModuleInfo ;
29+ private Object runspaceLock ;
30+ private string [ ] activeRules ;
31+ private string settingsPath ;
2932
3033 /// <summary>
3134 /// Defines the list of Script Analyzer rules to include by default if
@@ -54,16 +57,39 @@ public class AnalysisService : IDisposable
5457 /// <summary>
5558 /// Set of PSScriptAnalyzer rules used for analysis
5659 /// </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+ }
5875
5976 /// <summary>
6077 /// Gets or sets the path to a settings file (.psd1)
6178 /// containing PSScriptAnalyzer settings.
6279 /// </summary>
6380 public string SettingsPath
6481 {
65- get ;
66- set ;
82+ get
83+ {
84+ return settingsPath ;
85+ }
86+ set
87+ {
88+ lock ( runspaceLock )
89+ {
90+ settingsPath = value ;
91+ }
92+ }
6793 }
6894
6995 #endregion
@@ -80,6 +106,7 @@ public AnalysisService(IConsoleHost consoleHost, string settingsPath = null)
80106 {
81107 try
82108 {
109+ this . runspaceLock = new Object ( ) ;
83110 this . SettingsPath = settingsPath ;
84111 this . analysisRunspace = RunspaceFactory . CreateRunspace ( InitialSessionState . CreateDefault2 ( ) ) ;
85112 this . analysisRunspace . ThreadOptions = PSThreadOptions . ReuseThread ;
@@ -117,10 +144,10 @@ public ScriptFileMarker[] GetSemanticMarkers(ScriptFile file)
117144 Task . Factory . StartNew < ScriptFileMarker [ ] > (
118145 ( ) =>
119146 {
120- return
121- GetDiagnosticRecords ( file )
122- . Select ( ScriptFileMarker . FromDiagnosticRecord )
123- . ToArray ( ) ;
147+ return
148+ GetDiagnosticRecords ( file )
149+ . Select ( ScriptFileMarker . FromDiagnosticRecord )
150+ . ToArray ( ) ;
124151 } ,
125152 CancellationToken . None ,
126153 TaskCreationOptions . None ,
@@ -143,13 +170,16 @@ public IEnumerable<string> GetPSScriptAnalyzerRules()
143170 List < string > ruleNames = new List < string > ( ) ;
144171 if ( scriptAnalyzerModuleInfo != null )
145172 {
146- using ( var ps = System . Management . Automation . PowerShell . Create ( ) )
173+ lock ( runspaceLock )
147174 {
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 ( ) )
151176 {
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+ }
153183 }
154184 }
155185 }
@@ -175,38 +205,33 @@ public void Dispose()
175205 #region Private Methods
176206 private void FindPSScriptAnalyzer ( )
177207 {
178- using ( var ps = System . Management . Automation . PowerShell . Create ( ) )
208+ lock ( runspaceLock )
179209 {
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 ;
192213
193- var modules = ps . Invoke ( ) ;
214+ var modules = ps . AddCommand ( "Get-Module" )
215+ . AddParameter ( "List" )
216+ . AddParameter ( "Name" , "PSScriptAnalyzer" )
217+ . Invoke ( ) ;
194218
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+ }
210235 }
211236 }
212237 }
@@ -215,25 +240,28 @@ private void ImportPSScriptAnalyzer()
215240 {
216241 if ( scriptAnalyzerModuleInfo != null )
217242 {
218- using ( var ps = System . Management . Automation . PowerShell . Create ( ) )
243+ lock ( runspaceLock )
219244 {
220- ps . Runspace = this . analysisRunspace ;
245+ using ( var ps = System . Management . Automation . PowerShell . Create ( ) )
246+ {
247+ ps . Runspace = this . analysisRunspace ;
221248
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 ( ) ;
226253
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+ }
237265 }
238266 }
239267 }
@@ -268,28 +296,31 @@ private IEnumerable<PSObject> GetDiagnosticRecords(ScriptFile file)
268296
269297 if ( this . scriptAnalyzerModuleInfo != null )
270298 {
271- using ( var powerShell = System . Management . Automation . PowerShell . Create ( ) )
299+ lock ( runspaceLock )
272300 {
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 ) ) ;
277307
278- powerShell
279- . AddCommand ( "Invoke-ScriptAnalyzer" )
280- . AddParameter ( "ScriptDefinition" , file . Contents ) ;
308+ powerShell
309+ . AddCommand ( "Invoke-ScriptAnalyzer" )
310+ . AddParameter ( "ScriptDefinition" , file . Contents ) ;
281311
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+ }
291321
292- diagnosticRecords = powerShell . Invoke ( ) ;
322+ diagnosticRecords = powerShell . Invoke ( ) ;
323+ }
293324 }
294325 }
295326
0 commit comments