Monday, May 29, 2017

Basic VS extension to run snippet and render out results (similar to watch)

Leave a Comment

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?

2 Answers

Answers 1

I suggest looking into this:

Answers 2

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 cl.exe to compile a DLL. Handle errors accordingly.
  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...
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment