@@ -228,5 +228,65 @@ public async Task CanSetBreakpointsAsync()
228
228
( i ) => Assert . Equal ( "at breakpoint" , i ) ,
229
229
( i ) => Assert . Equal ( "after breakpoint" , i ) ) ;
230
230
}
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
+ // This has a timeout because the regression is a hang. When patched, it should pass.
281
+ var variablesResponse = await PsesDebugAdapterClient . RequestVariables (
282
+ new VariablesArguments
283
+ {
284
+ VariablesReference = 1
285
+ } , new CancellationTokenSource ( 2000 ) . Token ) . ConfigureAwait ( false ) ;
286
+
287
+ var form = variablesResponse . Variables . FirstOrDefault ( v => v . Name == "$form" ) ;
288
+ Assert . NotNull ( form ) ;
289
+ Assert . Equal ( "System.Windows.Forms.Form, Text: " , form . Value ) ;
290
+ }
231
291
}
232
292
}
0 commit comments