【问题标题】:Allowing people to mod a program允许人们修改程序
【发布时间】:2012-05-19 12:26:49
【问题描述】:

假设某个程序员递给我一个编译程序,没有源代码,它做了一些事情,但没有图形表示它的作用。然而,它确实提供了轻松添加它的能力。但是程序员如何让人们在编译好的程序中与事物进行交互呢?

这个演示程序只是简单地生成一个随机数,有一个最大值,然后触发一个事件,该事件应该向那些想要在他们自己的程序中使用这些数据的人公开发生的事情。

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);
    }
}

当然还有一个带有调用dowork()按钮的表单

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

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

所以现在我要做的就是创建一个向我展示发生了什么的 mod,创建一个带有进度条的新表单并处理 MakeRandom 类触发的事件。

形式:

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;
    }
}

以及事件处理:

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);
    }
}

但是如何将这段代码添加到我提供的程序中?我没有源代码,所以我不能添加它然后重新编译。我见过几个似乎可以即时编译 .cs 文件的程序,而这些 .cs 文件似乎与主程序交互。我该怎么做?

我可能必须在主表单中添加另一个按钮才能真正打开我的“Form_Mod”表单。所以把主程序交给我的程序员必须提供一种方法来做到这一点,对吧?还是有别的办法?

private void button2_Click(object sender, EventArgs e)
{
    Form_Mod frm = new Form_Mod();
    Mod_HandleEvents.attach();
    frm.Show();
}

【问题讨论】:

  • 从编程的角度来看,您要查找的词是“插件”。查看 MEF 以了解编写插件的一种方法。

标签: c#


【解决方案1】:

您可以创建一个插件。实现一个接口(所有插件通用),描述插件预期提供的所有方法和功能。然后你可以像这样动态加载插件(在运行时):Assembly.LoadFrom("plugin.dll") - 见http://msdn.microsoft.com/en-us/library/1009fa28.aspx

更详细描述此方法的文章:http://www.codeproject.com/Articles/4691/Plugin-Architecture-using-C

另一个:http://www.c-sharpcorner.com/UploadFile/rmcochran/plug_in_architecture09092007111353AM/plug_in_architecture.aspx

【讨论】:

    【解决方案2】:

    此外,我会将插件加载到新的应用程序域中,以防止它做任何恶意的事情,但这有点高级......请参阅Writing C# Plugin System

    【讨论】:

      【解决方案3】:

      最好的方法是将编译后的代码作为参考导入到您自己的项目中。 IE。像使用类库一样使用它,就像所有标准的 .NET 引用一样。然后,您可以在自己的应用程序中使用它的类,而无需担心外部库背后的源代码。

      为此,在您的项目下有一个 References 文件夹,右键单击它,添加引用,然后浏览到已编译的 .dll 或 .exe。添加后,您可以在代码中使用 MakeRandom 类(请记住包含适当的 using 或使用其命名空间限定名称)。

      【讨论】:

      • 这不是我真正想要的。以天际之类的游戏为例;有人创建了一个Mod,将其添加到Mod目录中,启用该Mod,就完成了。这就是我正在寻找的东西。
      • 我认为你所描述的只有在原始程序以模块化方式构建的情况下才能工作,这样你就可以替换某个部分而不影响应用程序的其余部分。在像天际这样的游戏中,这是有意完成的,并且暴露了一个简单的 mod 界面。在其他应用程序中,虽然不是故意暴露的,但可以很容易地看到可以替换哪些模块。我不认为通常单个编译的 .NET DLL/EXE 几乎如此灵活。一种可能的解决方案是使用 ILSpy 或类似的东西来反编译代码。
      • 我想我可能在我的问题中使用了错误的措辞,因为您所描述的(故意使程序可修改)正是我想要的。 想制作模块化应用程序。我不是想改变别人。
      • 哦,现在我明白了。看起来其他答案更准确地解决了这个问题。
      【解决方案4】:

      查看此link。您所指的通常也称为插件。它基本上是一个类库(dll),它从您的一个 DLL 中实现一个接口,它定义了您期望插件的外观。现在您只需扫描文件夹以查找其他 DLL 并使用反射来找到实现插件接口的类,当您拥有该类并加载程序集时,您可以创建该类型的实例并使用它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-13
        • 2017-03-07
        • 1970-01-01
        • 2013-06-20
        • 1970-01-01
        • 2011-08-15
        相关资源
        最近更新 更多