Friday 9 November 2012

Viewing 'Console Out' messages created inside UserControls (when rendered by VisualStudio's Form Designer)

Now that we have the ability to Add 'Console Out' to VisualStudio IDE as a native Window the question is: "Where can we use Console.WriteLine inside VisualStudio?",  in a way that the written lines/chars show in that Console Out window:

The key to understand the question is to visualize this:

  • The Console Out window is running inside VisualStudio (i.e. in the same process)
  • The Console Out window script captured the VisualStudio process' Console Out (of which there is only one, and the reason why if you open multiple Console Out windows (as shown above) only the last one opened will capture the output
  • To send a message to Console Out window the sender (i.e. the code executed) must be inside the same VisualStudio Process
  • This means that (based on quick tests) VisualStudio scripting engines (like the Immediate Window or the F# interpreter) will not work (since they are running outside the VisualStudio process)
One easy way to trigger an Console.WriteLine is to write it in one of the C# REPL script GUIs (from the O2 VisualStudio Extension) :)

But what would be really useful would be to trigger Console.WriteLine debug messages during normal VisualStudio development, for example when programming WinForms Controls :)

To show how that is possible, lets start with an empty WinForms Application project:

Which comes with default WinForms Form:

Next add a UserControl with a Label:

And add that UserControl to the Form:

The interesting part of what just happened, is that VisualStudio invokes the constructor of the UserControl1.cs (in order to create a live instance of that Control) before adding it to the Form1.cs object.

And that (the UserControl1.cs constructor) is where we can trigger the Console.WriteLine calls.

Open the Code Behind file for the UserControl1.cs file:

Write a Console.Write message and build the project (note the message shown in the Console Out window)

The reason that happened, is because (after a successful build) VisualStudio needs to refresh the controls currently shown in the Form's Designer (for example to take into account any visual changes in those controls)

Here is another way to trigger the Console.WriteLine call (i.e. to trigger the UserControl.cs constructor).

Close Form1.cs from the Form Designer:

And the open it again:

Yet another option is to delete the UserControl1.cs from the Form1.cs:

And add it back again:

Basically, the UserControl1.cs constructor will be invoked every time that control is added (or shown), like in the image below, where another instance of UserControl1.cs was dragged into the Form1.cs:

Interestingly enough, this as a number of security implications, since a security payload/exploit can be triggered just by adding/viewing a UserControl inside the Form Designer. The problem is that the payload will run with the same privileges given to VisualStudio (not the privileges used to run the application)