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:
- Aspect-oriented programming
- Castle DynamicProxy
- And perhaps
CSharpScript.EvaluateAsync
to evaluate code snippets in runtime
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:
- 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 .
- 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,
- Use cl.exe to compile a DLL. Handle errors accordingly.
- 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 }
- Improve on this... the most useful thing here would be to grab the top stack frame from the debugger and pass the
this
object asvalue
to the method... I haven't looked into how to do that; it should be available in the API somewhere though...
0 comments:
Post a Comment