5

I'd like to develop an extension for Visual Studio that runs a small snippet of code during runtime once a breakpoint's been hit.

To add some clarity, I pretty much want to call some code just as I would by manually writing it in the immediate window and render the results nicely (preferably a tree view).

I was reluctant to post this question since it seems pretty broad at first glance, but I'm fairly certain there aren't many different ways to achieve this.

I did originally look into Roslyn, but I believe that's for compile-time only if I'm not mistaken?

I have the code to do this already, and it runs perfectly in the immediate window, but I want to box it up as a feature since it's a bit cumbersome to manually enter it, and navigating it isn't easy either. what I need is somewhere between a 'watch' and an 'immediate' feature.

Question

Which platform/technology allows me to extend Visual Studio in a way I can run snippets of code 'ad hoc' during runtime and display the results nicely?

  • what kind of language you want to compile runtime, Does it render as a QuickInfo Tooltips. https://msdn.microsoft.com/en-us/library/ee197646.aspx – Zhanglong Wu - MSFT May 22 '17 at 02:23
  • Nothing renders, I haven't started it yet. I'm writing in C#. –  May 22 '17 at 12:07
  • I don't think you need an extension for that. Can't you just use the existing breakpoint features (right click on a breakpoint -> Actions)? – Manfred Radlwimmer May 22 '17 at 13:16
  • The section ["Breakpoint Actions and Tracepoints"](https://msdn.microsoft.com/en-us/library/5557y8b4.aspx#Breakpoint%20Actions%20and%20Tracepoints) on MSDN might be helpful. – Manfred Radlwimmer May 22 '17 at 13:22
  • There are some options for you 1) Use T4 templating to generate new code, then it would need to be compiled and instanciated from code. 2) You could use LINQ Expressions as they allow you runtime like flexibility in creating Lambda statements etc. and finally, welcome to a glaring hole in C# (until Rosalyn) where you can't find an interpreter to run a string of code as code. Rosalyn in my onion is just a monster. – JWP May 23 '17 at 23:19

2 Answers2

0

I suggest looking into this:

Andreas Zita
  • 7,232
  • 6
  • 54
  • 115
0

Q: Which platform/technology allows me to extend Visual Studio in a way I can run snippets of code 'ad hoc' during runtime and display the results nicely?

I would approach this as follows:

  1. Create a visual studio extension with your new window. This involves installing the Visual Studio SDK (it's shipped with VS nowadays) and then creating a window the usual way. As an example, you can check my project https://github.com/atlaste/CPPCoverage -> CoverageExt which has some code for that. There's also a lot of examples on https://github.com/Microsoft/VSSDK-Extensibility-Samples .
  2. To do that, first create a tiny C# file in a temp folder.

Basically you create a function as follows:

// Add some convenient using's.

public class EvaluationClass {
  public static object Evaluate() { 
    return /* paste the evaluated expression here */;
  }
}

The good thing about this method is that results are automatically boxed/casted to object, which is fine. The only issue here is that you might want to make a second compile run for the void case, which will fail because it cannot be boxed/casted to object.

Next,

  1. Use csc.exe to compile a DLL. Handle errors accordingly. CSC is located in your .NET framework folder (c:\windows\microsoft.net\framework[x]\...)
  2. Use reflection to load the DLL and execute the method in the extension.

The basic trick is as follows:

try {
  var assembly = Assembly.Load(tempDllName);
  // TODO: check if assembly is null --> compilation error

  var eval = assembly.GetType("EvaluationClass").GetMethod("Evaluate");
  // TODO: check if eval is null --> compilation error

  var result = eval.Invoke();

  // Draw result on window
}
catch (Exception ex) {

  // Handle exception appropriately
}
  1. Improve on this... the most useful thing here would be to grab the top stack frame from the debugger and pass the this object as value to the method... I haven't looked into how to do that; it should be available in the API somewhere though...
atlaste
  • 30,418
  • 3
  • 57
  • 87