@@ -228,5 +228,64 @@ public async Task CanSetBreakpointsAsync()
228228 ( i ) => Assert . Equal ( "at breakpoint" , i ) ,
229229 ( i ) => Assert . Equal ( "after breakpoint" , i ) ) ;
230230 }
231+
232+ // This is a regression test for a bug where user code causes a new synchronization context
233+ // to be created, breaking the extension. It's most evident when debugging PowerShell
234+ // scripts that use System.Windows.Forms. It required fixing both Editor Services and
235+ // OmniSharp.
236+ //
237+ // This test depends on PowerShell being able to load System.Windows.Forms, which only works
238+ // reliably with Windows PowerShell. It works with PowerShell Core in the real-world;
239+ // however, our host executable is xUnit, not PowerShell. So by restricting to Windows
240+ // PowerShell, we avoid all issues with our test project (and the xUnit executable) not
241+ // having System.Windows.Forms deployed, and can instead rely on the Windows Global Assembly
242+ // Cache (GAC) to find it.
243+ [ Trait ( "Category" , "DAP" ) ]
244+ [ SkippableFact ]
245+ public async Task CanStepPastSystemWindowsForms ( )
246+ {
247+ Skip . IfNot ( PsesStdioProcess . IsWindowsPowerShell ) ;
248+ Skip . If ( PsesStdioProcess . RunningInConstainedLanguageMode ) ;
249+
250+ string filePath = NewTestFile ( string . Join ( Environment . NewLine , new [ ]
251+ {
252+ "Add-Type -AssemblyName System.Windows.Forms" ,
253+ "$form = New-Object System.Windows.Forms.Form" ,
254+ "Write-Host $form"
255+ } ) ) ;
256+
257+ await PsesDebugAdapterClient . LaunchScript ( filePath , Started ) . ConfigureAwait ( false ) ;
258+
259+ var setBreakpointsResponse = await PsesDebugAdapterClient . SetFunctionBreakpoints (
260+ new SetFunctionBreakpointsArguments
261+ {
262+ Breakpoints = new FunctionBreakpoint [ ]
263+ {
264+ new FunctionBreakpoint
265+ {
266+ Name = "Write-Host" ,
267+ }
268+ }
269+ } ) . ConfigureAwait ( false ) ;
270+
271+ var breakpoint = setBreakpointsResponse . Breakpoints . First ( ) ;
272+ Assert . True ( breakpoint . Verified ) ;
273+
274+ ConfigurationDoneResponse configDoneResponse = await PsesDebugAdapterClient . RequestConfigurationDone ( new ConfigurationDoneArguments ( ) ) . ConfigureAwait ( false ) ;
275+ Assert . NotNull ( configDoneResponse ) ;
276+
277+ // At this point the script should be running so lets give it time
278+ await Task . Delay ( 2000 ) . ConfigureAwait ( false ) ;
279+
280+ var variablesResponse = await PsesDebugAdapterClient . RequestVariables (
281+ new VariablesArguments
282+ {
283+ VariablesReference = 1
284+ } ) . ConfigureAwait ( false ) ;
285+
286+ var form = variablesResponse . Variables . FirstOrDefault ( v => v . Name == "$form" ) ;
287+ Assert . NotNull ( form ) ;
288+ Assert . Equal ( "System.Windows.Forms.Form, Text: " , form . Value ) ;
289+ }
231290 }
232291}
0 commit comments