forked from killswitch1111/powerguivsx
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEngineEvents.cs
More file actions
505 lines (411 loc) · 16.4 KB
/
Copy pathEngineEvents.cs
File metadata and controls
505 lines (411 loc) · 16.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using EnvDTE;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Debugger.Interop;
using Microsoft.VisualStudio.Shell.Interop;
using PowerShellTools.Common.Logging;
namespace PowerShellTools.DebugEngine
{
public interface IEngineEvents
{
/// <summary>
/// Fires the event notifying the SDM that the debug engine has loaded.
/// </summary>
void EngineCreated();
void RunspaceRequest();
void EngineLoaded();
/// <summary>
/// Fires the event notifying the SDM that a program was created
/// </summary>
void ProgramCreated(IDebugProgram2 program);
void ProcessCreated(IDebugProcess2 process);
void ProcessDestroyed();
void DebugEntryPoint();
void ProgramDestroyed(IDebugProgram2 program);
void OutputString(string str);
void Break(ScriptProgramNode program);
void Exception(ScriptProgramNode program, Exception ex);
void Breakpoint(ScriptProgramNode program, ScriptBreakpoint breakpoint);
void BreakpointHit(ScriptBreakpoint breakpoint, ScriptProgramNode node);
void BreakpointEnabled(ScriptBreakpoint breakpoint, int fEnable);
void BreakpointRemoved(ScriptBreakpoint breakpoint);
void BreakpointAdded(ScriptBreakpoint breakpoint);
}
/// <summary>
/// Fires events triggered by the debug engine.
/// </summary>
public class EngineEvents : IEngineEvents
{
#region Fields
private readonly IDebugEngine2 _engine;
private readonly IDebugEventCallback2 _callback;
private static readonly ILog Log = LogManager.GetLogger(typeof (EngineEvents));
private static Object _debuggingStateLock = new Object();
#endregion
#region Constructor
public EngineEvents(IDebugEngine2 engine, IDebugEventCallback2 callback)
{
_engine = engine;
_callback = callback;
}
#endregion
#region Properties
public ScriptDebugger Debugger
{
get
{
return PowerShellToolsPackage.Debugger;
}
}
#endregion
#region Events
/// <summary>
/// Fires the event notifying the SDM that the debug engine has loaded.
/// </summary>
public void EngineCreated()
{
Log.Debug("EngineCreated");
var iid = new Guid(EngineCreateEvent.IID);
_callback.Event(_engine, null, null, null, new EngineCreateEvent(_engine), ref iid, EngineCreateEvent.Attributes);
}
public void RunspaceRequest()
{
Log.Debug("RunspaceRequest");
var iid = new Guid(RunspaceRequestEvent.IID);
_callback.Event(_engine, null, null, null, new RunspaceRequestEvent(_engine), ref iid, RunspaceRequestEvent.Attributes);
}
public void EngineLoaded()
{
Log.Debug("EngineLoaded");
var iid = new Guid(LoadCompleteEvent.IID);
_callback.Event(_engine, null, null, null, new LoadCompleteEvent(), ref iid, LoadCompleteEvent.Attributes);
lock (_debuggingStateLock)
{
if (Debugger != null)
{
Debugger.IsDebugging = true;
}
}
}
/// <summary>
/// Fires the event notifying the SDM that a program was created
/// </summary>
public void ProgramCreated(IDebugProgram2 program)
{
Log.Debug("ProgramCreated");
var iid = new Guid(ProgramCreateEvent.IID);
_callback.Event(_engine, null, program, null, new ProgramCreateEvent(), ref iid, ProgramCreateEvent.Attributes);
}
public void ProcessCreated(IDebugProcess2 process)
{
Log.Debug("ProcessCreated");
var iid = new Guid(ProcessCreatedEvent.IID);
_callback.Event(_engine, process, null, null, new ProcessCreatedEvent(), ref iid, ProcessCreatedEvent.Attributes);
}
public void ProcessDestroyed()
{
Log.Debug("ProcessDestroyed");
var iid = new Guid(ProcessDestroyEvent.IID);
_callback.Event(_engine, null, null, null, new ProcessDestroyEvent(), ref iid, ProcessDestroyEvent.Attributes);
}
public void DebugEntryPoint()
{
Log.Debug("DebugEntryPoint");
var iid = new Guid(DebugEntryPointEvent.IID);
_callback.Event(_engine, null, null, null, new DebugEntryPointEvent(_engine), ref iid, DebugEntryPointEvent.Attributes);
}
public void ProgramDestroyed(IDebugProgram2 program)
{
Log.Debug("ProgramDestroyed");
var iid = new Guid(ProgramDestoryedEvent.IID);
_callback.Event(_engine, null, program, null, new ProgramDestoryedEvent(), ref iid, ProgramDestoryedEvent.Attributes);
lock (_debuggingStateLock)
{
if (Debugger != null)
{
Debugger.IsDebugging = false;
}
}
}
public void OutputString(string str)
{
Log.Debug("OutputString");
var iid = new Guid(OutputStringEvent.IID);
_callback.Event(_engine, null, null, null, new OutputStringEvent(str), ref iid, OutputStringEvent.Attributes);
}
public void Break(ScriptProgramNode program)
{
Log.Debug("Break");
var iid = new Guid(BreakEvent.IID);
_callback.Event(_engine, null, program, program, new BreakEvent(), ref iid, BreakEvent.Attributes);
}
public void Exception(ScriptProgramNode program, Exception ex)
{
Log.Debug("Exception");
var iid = new Guid(ExceptionEvent.IID);
_callback.Event(_engine, null, program, program, new ExceptionEvent(program, ex), ref iid, ExceptionEvent.Attributes);
}
public void Breakpoint(ScriptProgramNode program, ScriptBreakpoint breakpoint)
{
Log.Debug("Breakpoint");
var iid = new Guid(BreakPointEvent.IID);
_callback.Event(_engine, null, program, program, new BreakPointEvent(breakpoint), ref iid, BreakPointEvent.Attributes);
}
public void BreakpointHit(ScriptBreakpoint breakpoint, ScriptProgramNode node)
{
Log.Debug("BreakpointHit");
var iid = new Guid(BreakPointHitEvent.IID);
_callback.Event(_engine, null, node, node, new BreakPointHitEvent(breakpoint), ref iid, BreakPointHitEvent.Attributes);
}
public void BreakpointEnabled(ScriptBreakpoint breakpoint, int fEnable)
{
Log.Debug("BreakpointEnabled");
if (Debugger != null)
{
Debugger.BreakpointManager.EnableBreakpoint(breakpoint, fEnable);
}
}
public void BreakpointRemoved(ScriptBreakpoint breakpoint)
{
Log.Debug("BreakpointRemoved");
if (Debugger != null)
{
Debugger.BreakpointManager.RemoveBreakpoint(breakpoint);
}
}
public void BreakpointAdded(ScriptBreakpoint breakpoint)
{
Log.Debug("BreakpointAdded");
if (Debugger != null)
{
Debugger.BreakpointManager.SetBreakpoint(breakpoint);
}
}
#endregion
}
/// <summary>
/// The debug engine (DE) sends this interface to the session debug manager (SDM) when an instance of the DE is created.
/// </summary>
public sealed class RunspaceRequestEvent : SynchronousEvent, IDebugEngineCreateEvent2, IRunspaceRequest
{
public const string IID = "FE5B734C-759D-4E59-AB04-F103343BDD07";
private IDebugEngine2 m_engine;
public RunspaceRequestEvent(IDebugEngine2 engine)
{
m_engine = engine;
}
public void SetRunspace(Runspace runspace, IEnumerable<PendingBreakpoint> breakpoints)
{
Engine.PendingBreakpoints = breakpoints;
}
public Engine Engine
{
get { return m_engine as Engine; }
}
int IDebugEngineCreateEvent2.GetEngine(out IDebugEngine2 engine)
{
engine = m_engine;
return VSConstants.S_OK;
}
}
public class AsynchronousEvent : IDebugEvent2
{
public const uint Attributes = (uint)enum_EVENTATTRIBUTES.EVENT_ASYNCHRONOUS;
int IDebugEvent2.GetAttributes(out uint eventAttributes)
{
eventAttributes = Attributes;
return VSConstants.S_OK;
}
}
public class SynchronousEvent : IDebugEvent2
{
public const uint Attributes = (uint)enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS;
int IDebugEvent2.GetAttributes(out uint eventAttributes)
{
eventAttributes = Attributes;
return VSConstants.S_OK;
}
}
class SynchronousStoppingEvent : IDebugEvent2
{
public const uint Attributes = (uint)enum_EVENTATTRIBUTES.EVENT_STOPPING | (uint)enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS;
int IDebugEvent2.GetAttributes(out uint eventAttributes)
{
eventAttributes = Attributes;
return VSConstants.S_OK;
}
}
class StoppingEvent : IDebugEvent2
{
public const uint Attributes = (uint)enum_EVENTATTRIBUTES.EVENT_ASYNC_STOP;
int IDebugEvent2.GetAttributes(out uint eventAttributes)
{
eventAttributes = Attributes;
return VSConstants.S_OK;
}
}
/// <summary>
/// The debug engine (DE) sends this interface to the session debug manager (SDM) when an instance of the DE is created.
/// </summary>
public sealed class EngineCreateEvent : AsynchronousEvent, IDebugEngineCreateEvent2
{
public const string IID = "FE5B734C-759D-4E59-AB04-F103343BDD06";
private IDebugEngine2 m_engine;
public EngineCreateEvent(IDebugEngine2 engine)
{
m_engine = engine;
}
public Engine Engine
{
get { return m_engine as Engine; }
}
int IDebugEngineCreateEvent2.GetEngine(out IDebugEngine2 engine)
{
engine = m_engine;
return VSConstants.S_OK;
}
}
// This interface is sent by the debug engine (DE) to the session debug manager (SDM) when a program is attached to.
sealed class ProcessDestroyEvent : AsynchronousEvent, IDebugProcessDestroyEvent2
{
public const string IID = "3e2a0832-17e1-4886-8c0e-204da242995f";
}
// This interface is sent by the debug engine (DE) to the session debug manager (SDM) when a program is attached to.
sealed class ProgramCreateEvent : AsynchronousEvent, IDebugProgramCreateEvent2
{
public const string IID = "96CD11EE-ECD4-4E89-957E-B5D496FC4139";
}
sealed class ProcessCreatedEvent : AsynchronousEvent, IDebugProcessCreateEvent2
{
public const string IID = "BAC3780F-04DA-4726-901C-BA6A4633E1CA";
}
// This interface is sent by the debug engine (DE) to the session debug manager (SDM) when a program is loaded, but before any code is executed.
sealed class LoadCompleteEvent : StoppingEvent, IDebugLoadCompleteEvent2
{
public const string IID = "B1844850-1349-45D4-9F12-495212F5EB0B";
}
sealed class DebugEntryPointEvent : AsynchronousEvent, IDebugEntryPointEvent2
{
public const string IID = "e8414a3e-1642-48ec-829e-5f4040e16da9";
public object Engine { get; set; }
public DebugEntryPointEvent(IDebugEngine2 mEngine)
{
Engine = mEngine;
}
}
sealed class ProgramDestoryedEvent : AsynchronousEvent, IDebugProgramDestroyEvent2
{
public const string IID = "e147e9e3-6440-4073-a7b7-a65592c714b5";
public int GetExitCode(out uint pdwExit)
{
pdwExit = 0;
return VSConstants.S_OK;
}
}
sealed class OutputStringEvent : AsynchronousEvent, IDebugOutputStringEvent2
{
public const string IID = "569c4bb1-7b82-46fc-ae28-4536ddad753e";
private string _outString;
public OutputStringEvent(string outString)
{
_outString = outString;
}
#region Implementation of IDebugOutputStringEvent2
public int GetString(out string pbstrString)
{
pbstrString = _outString;
return VSConstants.S_OK;
}
#endregion
}
sealed class BreakEvent : StoppingEvent, IDebugBreakEvent2
{
public const string IID = "c7405d1d-e24b-44e0-b707-d8a5a4e1641b";
}
sealed class BreakPointEvent : AsynchronousEvent, IDebugBreakpointBoundEvent2
{
public const string IID = "1dddb704-cf99-4b8a-b746-dabb01dd13a0";
private ScriptBreakpoint _breakpoint;
public BreakPointEvent(ScriptBreakpoint breakpoint)
{
_breakpoint = breakpoint;
}
#region Implementation of IDebugBreakpointBoundEvent2
public int GetPendingBreakpoint(out IDebugPendingBreakpoint2 ppPendingBP)
{
ppPendingBP = _breakpoint;
return VSConstants.S_OK;
}
public int EnumBoundBreakpoints(out IEnumDebugBoundBreakpoints2 ppEnum)
{
ppEnum = _breakpoint;
return VSConstants.S_OK;
}
#endregion
}
sealed class BreakPointHitEvent : StoppingEvent, IDebugBreakpointEvent2
{
public const string IID = "501c1e21-c557-48b8-ba30-a1eab0bc4a74";
private ScriptBreakpoint _breakpoint;
public BreakPointHitEvent(ScriptBreakpoint breakpoint)
{
_breakpoint = breakpoint;
}
#region Implementation of IDebugBreakpointEvent2
public int EnumBreakpoints(out IEnumDebugBoundBreakpoints2 ppEnum)
{
Trace.WriteLine("BreakpointEvent: EnumBreakpoints");
ppEnum = _breakpoint;
return VSConstants.S_OK;
}
#endregion
}
sealed class ExceptionEvent : StoppingEvent, IDebugExceptionEvent2
{
public const string IID = "51a94113-8788-4a54-ae15-08b74ff922d0";
private readonly IDebugProgram2 _program;
private readonly Exception _exception;
public ExceptionEvent(IDebugProgram2 program, Exception ex)
{
_program = program;
_exception = ex;
}
#region Implementation of IDebugExceptionEvent2
public int GetException(EXCEPTION_INFO[] pExceptionInfo)
{
pExceptionInfo[0].pProgram = _program;
pExceptionInfo[0].bstrExceptionName = _exception.GetType().ToString();
pExceptionInfo[0].dwState = enum_EXCEPTION_STATE.EXCEPTION_CANNOT_BE_CONTINUED | enum_EXCEPTION_STATE.EXCEPTION_STOP_SECOND_CHANCE;
pExceptionInfo[0].guidType = new Guid(GuidList.PowerShellLanguage);
string name;
_program.GetName(out name);
pExceptionInfo[0].bstrProgramName = name;
return VSConstants.S_OK;
}
public int GetExceptionDescription(out string pbstrDescription)
{
pbstrDescription = _exception.Message;
if (_exception is RuntimeException)
{
var runtimeException = _exception as RuntimeException;
pbstrDescription += Environment.NewLine;
pbstrDescription += runtimeException.ErrorRecord.ScriptStackTrace;
}
return VSConstants.S_OK;
}
public int CanPassToDebuggee()
{
return VSConstants.S_FALSE;
}
public int PassToDebuggee(int fPass)
{
fPass = VSConstants.S_FALSE;
return VSConstants.S_OK;
}
#endregion
}
}