1

Let's say some programmer hands me a compiled program, without source code, that does some stuff, but has no graphical representation of what it does. It does however provide the ability to easily add that. But how will the programmer let people interact with things in a compiled program?

This demo program simply makes a random number, with a maximum, and then fires an event that is supposed to expose what happened to people who want to use this data in their own mods for the program.

public delegate void MadeRandomEventHandler(int previous,int current,int max);

class MakeRandom
{
    private static int current = 350;
    private static int max = 350;

    public static event MadeRandomEventHandler MadeRandomEvent;
    public static void dowork()
    {
        int curCopy = current;
        Random random = new Random();
        current = random.Next(0, max+1);
        fireMadeRandomEvent(curCopy,current,max);
    }

    private static void fireMadeRandomEvent(int previous, int current, int max)
    {
        if (MadeRandomEvent != null)
            MadeRandomEvent(previous,current,max);
    }
}

And of course a Form with a button to call dowork()

public partial class Form_Main : Form
{
    public Form_Main()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        MakeRandom.dowork();
    }
}

So now all I would have to do to create a mod that shows me what happened, is create a new form with a progressbar and handle the event the MakeRandom class fires.

The form:

public partial class Form_Mod : Form
{
    public static Form_Mod frm;

    public Form_Mod()
    {
        InitializeComponent();
    }

    private void Form_Mod_Load(object sender, EventArgs e)
    {
        frm = this;
        progressBar1.Minimum = 0;
        progressBar1.Maximum = 100;
    }

    public void updateProgress(int percent)
    {
        progressBar1.Value = percent;
    }
}

And the event handling:

class Mod_HandleEvents
{
    public static void attach()
    {
        MakeRandom.MadeRandomEvent += new MadeRandomEventHandler(RandomChange);
    }
    public static void detach()
    {
        MakeRandom.MadeRandomEvent -= new MadeRandomEventHandler(RandomChange);
    }

    private static void RandomChange(int previous, int current, int max)
    {
        float percent1 = (float)current / (float)max;
        int percent = (int)(percent1 * 100);

        Form_Mod frm = Form_Mod.frm;
        frm.updateProgress(percent);
    }
}

But how do I add this code the the program I was provided? I do not have the source code, so I cannot add it & then recompile. I have seen several programs that seem to compile .cs files on the fly, and those .cs files seem to interract with the main program. How do I do this?

And I would probably have to add another button to the main form to actually be able to open my "Form_Mod" form. So the programmer who handed me the main program would have to provide a way to do that, right? Or is there another way?

private void button2_Click(object sender, EventArgs e)
{
    Form_Mod frm = new Form_Mod();
    Mod_HandleEvents.attach();
    frm.Show();
}
natli
  • 3,782
  • 11
  • 51
  • 82

4 Answers4

2

You can create a plugin. Implement an interface (common for all plugins), describing all the methods and functions the plugin is expected to offer. Then you could load the plugin dynamically (in run-time) like so: Assembly.LoadFrom("plugin.dll") - see http://msdn.microsoft.com/en-us/library/1009fa28.aspx

An article describing this method in more detail: http://www.codeproject.com/Articles/4691/Plugin-Architecture-using-C

Another one: http://www.c-sharpcorner.com/UploadFile/rmcochran/plug_in_architecture09092007111353AM/plug_in_architecture.aspx

Konrad Morawski
  • 8,307
  • 7
  • 53
  • 91
2

Additionally I would load the plugin in a new application domain to prevent it from doing anything malicious but that is a bit advanced ... see Writing C# Plugin System

Community
  • 1
  • 1
Jay
  • 3,276
  • 1
  • 28
  • 38
0

The best way to do this is to import the compiled code as a Reference in your own project. I.e. use it like a class library, just like all the standard .NET references. Then you can make use of its classes in your own application, without needing to worry about having the source code behind that external library.

To do this, under your project there's a References folder, right click this, Add Reference, then browse to the compiled .dll or .exe. Once you add it, you can use the MakeRandom class in your code (remember to include the appropriate using or use its namespace-qualified name).

Tim S.
  • 55,448
  • 7
  • 96
  • 122
  • It's not really what I want. Take a game like Skyrim as an example; someone creates a Mod, adds it in the Mod directory, enables the Mod, and it's done. That the sort of thing I am looking for. – natli May 19 '12 at 12:33
  • I think what you describe can only work if the original program was built in a modular way, so that you can replace a certain part without affecting the rest of the app. In games like Skyrim, this is done intentionally and an easy interface to mod is exposed. In other apps, though not intentionally exposed, it can be easy to see what modules can be replaced. I don't think that in general a single compiled .NET DLL/EXE is nearly so flexible. One potential solution would be to use ILSpy or something similar to decompile the code. – Tim S. May 19 '12 at 12:37
  • I think I may have used bad wording in my question, because what you are describing (intentionally making a program moddable) is exactly what I want. **I** want to make modular applications. I am not trying to alter somebody elses. – natli May 19 '12 at 12:41
  • Oh, now I understand. It looks like the other answers are addressing this more accurately. – Tim S. May 19 '12 at 12:45
0

Checkout this link. What you are refering too is usually called a Plugin. Its basically a Class Libary(dll) that implements an interface from one of your DLLs, which defines how you expect how the plugin looks. Now you just scan a folder for additional DLLs and use reflection to find a class that implements your plugin interface, when you have the class and loaded the assembly you can create an instance of that type and use it.

dowhilefor
  • 10,971
  • 3
  • 28
  • 45