You can use reflection (specifically classes in the System.Reflection namespace) to create instances of objects.

Last time (Create and play your own Breakout game ) , I showed a Windows Form application that is a Breakout game.

This time, let’s see if we can create and run that WinForm game (Paddle.Exe) from a C# console application that does not have any direct references to the program. In fact, it has no extra external references at all, including none to WinForms.

When running, the only process that runs is ConsoleApplication1.exe. Paddle.Exe is just used as a Dll containing the type to create and run.

In fact, the layout of a DLL and EXE file are identical: they are both the standard Portable Executable  format.

The code below uses classes from the System.Reflection namespace to load an assembly (the Paddle.Exe), then use reflection on the loaded assembly to find a particular Type (Class). There are 9 types in the assembly, including “Paddle”, “Block” and “Form1”

We want to get the Type “Form1”, then find a method on that form called “ShowDialog”.

We create an instance of “Form1” and then invoke the method “ShowDialog” on that instance.

First, go to the Breakout Game post and create Paddle.Exe.

Start Visual Studio

File->New Project->C#->Console Application .

Replace Program.cs with the C# code below. Be sure that you adjust the path to Paddle.Exe.

When you run the code, the Paddle game starts, but it’s really ConsoleApplication1.exe running (which you can verify in Task Manager).

Now why would anybody do this? I actually did this as a model for the same functionality from C++ native code that is not Managed C++.

These are examples of managed C++: Call managed code from your C++ code and Manipulate managed and native objects in C++ to show the registry in a WPF TreeView

I wanted to show how to run code before the CLR starts, then start the CLR, then run managed code.

So I wrote some pure C++ code that starts the CLR and uses reflection to create an instance and call a method on it. But it’s a lot easier to write reflection code in C# then C++.

Next time, we’ll show the C++ native code doing the same thing. It’s a lot more complex!

See also Host the CLR and Generate IL to call a MessageBox

 

<Code>

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      var asmNameWinform = @"c:\MemSpect\test\csLife.exe";
      //asmNameWinform = @"C:\Users\calvinh\Documents\Visual Studio 2012\Projects\Paddle\Paddle\bin\Debug\Paddle.exe";
      var asmWinForm = Assembly.LoadFrom(asmNameWinform);
      /*
  [0]: {Name = "Form1" FullName = "WindowsFormsApplication1.Form1"}
  [1]: {Name = "PlayMode" FullName = "WindowsFormsApplication1.Form1+PlayMode"}
  [2]: {Name = "BaseObj" FullName = "WindowsFormsApplication1.BaseObj"}
  [3]: {Name = "Ball" FullName = "WindowsFormsApplication1.Ball"}
  [4]: {Name = "Block" FullName = "WindowsFormsApplication1.Block"}
  [5]: {Name = "Paddle" FullName = "WindowsFormsApplication1.Paddle"}
  [6]: {Name = "Program" FullName = "WindowsFormsApplication1.Program"}
  [7]: {Name = "Resources" FullName = "WindowsFormsApplication1.Properties.Resources"}
  [8]: {Name = "Settings" FullName = "WindowsFormsApplication1.Properties.Settings"}

       * * */

      var typeForm1Name = asmWinForm.
        GetTypes().
        Where(
          t => t.Name == "Form1"
        ).
        First().
        FullName;
      
      var x = asmWinForm.CreateInstance(typeForm1Name);
      var props = x.GetType().GetMembers();
      foreach (var prop in props)
      {
        if (prop.Name == "ShowDialog")
        {
          Debug.WriteLine(prop.Name);
          //+		prop	{System.Windows.Forms.DialogResult ShowDialog()}	
          //-		prop	{System.Windows.Forms.DialogResult ShowDialog(System.Windows.Forms.IWin32Window)}	
        }
      }
      // find the first method "ShowDialog" which has no parameters.
      var showDialogMethod = (MethodInfo) props.
        Where(
        m => m.Name == "ShowDialog" 
          && ((MethodInfo)m).GetParameters().Count() == 0
          ).First();
      showDialogMethod.Invoke(x,  parameters: null);
    }
  }
}

</Code>