如何从我的资源中的DLL调用函数?

时间:2017-04-27 12:34:22

标签: c# dll .net-assembly messagebox loader

所以我有这个DLL和其他我认为被称为注入器/加载器的东西?它基本上将我的DLL加载到自身的进程中,所以它需要我的DLL并将其加载到“Injector.exe”的过程中 在下面的示例中,它不会从资源加载它,而是从桌面加载,这同样适用于此。

现在sicne正在加载它并没有真正调用任何函数,这就是我的问题所在。

我想在加载DLL时调用一些Messagebox函数。

据我所知,最合乎逻辑的方法是在using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace AssemblyLoader { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnBrowse_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); if(ofd.ShowDialog() == DialogResult.OK) { tbAssemblyLocation.Text = ofd.FileName; } } private void btnAssemblyLoad_Click(object sender, EventArgs e) { AssemblyName an = AssemblyName.GetAssemblyName(tbAssemblyLocation.Text); Assembly.Load(an); } } } 事件中执行此操作,因此当事件发生时,它会调用DLL中的函数。 问题是我不知道这会被称为什么,我读了一些关于“反思”但我不确定这是我需要的东西。

我该如何继续这个?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MSgBOxDllCS
{
    public class Funcs
    {
        public void CallMessageBox()
        {
            MessageBox.Show("Hello");

        }
    }
}

DLL

window.plugins.googleplus.login(
    {
      'scopes': '... ', // optional, space-separated list of scopes, If not included or empty, defaults to `profile` and `email`.
      'webClientId': 'client id of the web app/server side', // optional clientId of your Web application from Credentials settings of your project - On Android, this MUST be included to get an idToken. On iOS, it is not required.
      'offline': true, // optional, but requires the webClientId - if set to true the plugin will also return a serverAuthCode, which can be used to grant offline access to a non-Google server
    },
    function (obj) {
      alert(JSON.stringify(obj)); // do something useful instead of alerting
    },
    function (msg) {
      alert('error: ' + msg);
    }
);

2 个答案:

答案 0 :(得分:2)

您需要调用非静态类的实例方法,请参阅下文。

// Step 1: load assembly to memory
var an = AssemblyName.GetAssemblyName(tbAssemblyLocation.Text);
var assembly = Assembly.Load(an);

// Step 2: get type from the assembly by name
var type = assembly.GetType("MSgBOxDllCS.Funcs");

// Step 3: get method of the type
var method = type.GetMethod("CallMessageBox");

// Step 4: create instance of the type
var funcs = Activator.CreateInstance(type);

// Step 5: invoke the instance method
method.Invoke(funcs, null);

一般来说,您正在构建的内容称为插件框架,互联网上有很多关于如何完成的示例,您也可以根据自己的要求利用现有框架。

答案 1 :(得分:2)

有几种方法可以实现这一目标。

  1. 加载程序集,创建类的实例,使用Reflection查找所需的方法并调用它。
  2. var assembly = Assembly.LoadFrom(DllFilePath);
    var funcs = assembly.CreateInstance("MSgBOxDllCS.Funcs");
    var method = funcs.GetType().GetMethod("CallMessageBox");
    method.Invoke(funcs, null);
    
    1. 同样但使用动态对象,对反射成员的控制较少,但看起来更好:
    2. var assembly = Assembly.LoadFrom(DllFilePath);
      dynamic funcs = assembly.CreateInstance("MSgBOxDllCS.Funcs");
      funcs.CallMessageBox();
      
      1. 最后但并非最不重要的是,提取一个接口并将其放在一个单独的共享DLL中。这种方法有助于摆脱反射调用,而且它的性质是最可靠的:
      2. 通用共享DLL:

        namespace Shared
        {
           public interface IFuncs
           {
              void CallMessageBox();
           }
        }
        

        要加载的DLL:

        namespace MSgBOxDllCS
        {
            public class Funcs : Shared.IFuncs
            {
                public void CallMessageBox()
                {
                    MessageBox.Show("Hello");
                }
            }
        }
        

        装载机:

        var assembly = Assembly.LoadFrom(DllFilePath);
        var funcs = (Shared.IFuncs)assembly.CreateInstance("MSgBOxDllCS.Funcs");
        funcs.CallMessageBox();