4

I have been reading a lot about this - I feel like I'm very close to the answer. I am simply looking to call a method from within a dll file that I have created.

For example purposes:

My DLL File:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ExampleDLL
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Windows.Forms.MessageBox.Show(args[0]);
        }

        public void myVoid(string foo)
        {
            System.Windows.Forms.MessageBox.Show(foo);
        }
    }
}


My Application:

string filename = @"C:\Test.dll";
    Assembly SampleAssembly;
    SampleAssembly = Assembly.LoadFrom(filename);
    // Obtain a reference to a method known to exist in assembly.
    MethodInfo Method = SampleAssembly.GetTypes()[0].GetMethod("myVoid");
    // Obtain a reference to the parameters collection of the MethodInfo instance.

All credits go to SO user 'woohoo' for the above snippet How to call a Managed DLL File in C#?

Now, though, I would like to be able to not only reference my Dll (and the methods inside it) but properly call the methods inside it (in this case I would like to call method 'myVoid').

Might anyone have any suggestions for me?

Thank you,

Evan

Community
  • 1
  • 1
  • 1
    Why don't you add its reference to your application ? – Saber Amani Jul 31 '11 at 19:31
  • 1
    @SaberAmani: Because the OP might want to only include the DLL if the user has rights to that feature. An added reference *has* to always ship with the app. – erict Feb 10 '13 at 23:30
  • There are cases when you need to separately ship modules of the same application. The initial installation contains basic features while an upgrade pack uses the basic featured dlls to access some kind of data context, without rewriting the same code in the upgrade pack. – Dan Mihalea Mar 23 '22 at 07:19

4 Answers4

6

The question and answer you reference is using reflection to call the method in the managed DLL. This isn't necessary if, as you say you want to do, you simply reference your DLL. Add the reference (via the Add Reference option in Visual Studio), and you can call your method directly like so:

ExampleDLL.Program p = new ExampleDLL.Program(); // get an instance of `Program`
p.myVoid(); // call the method `myVoid`

If you want to go the reflection route (as given by woohoo), you still need an instance of your Program class.

Assembly SampleAssembly = Assembly.LoadFrom(filename);
Type myType = SampleAssembly.GetTypes()[0];
MethodInfo Method = myType.GetMethod("myVoid");
object myInstance = Activator.CreateInstance(myType);
Method.Invoke(myInstance, null);

Now you have an instance of Program and can call myVoid.

  • you need to set Parameters as well – Damith Jul 31 '11 at 19:40
  • @DSW: Read the documentation for MethodInfo.Invoke. –  Jul 31 '11 at 19:46
  • thanks for reminding me to read documentation :) but I wonder how to call _myvoid_ method without giving parameters, it should be _object result = method.Invoke( null, parameters )_; – Damith Jul 31 '11 at 19:58
  • 1
    That would call `myVoid` as a static method with the parameters `parameters`. Probably giving an empty array for the parameters is fine, but I like to stick to the letter of the documentation. –  Jul 31 '11 at 20:05
  • @Matthew Ferreira As somewhat of a follow up to my original question, (you really got me thinking here), would it be possible to encrypt my dll file prior to adding it as a reference to my project; then, loading the dll's data as some object, decrypting this data, and still be able to call the methods inside of it? –  Jul 31 '11 at 20:08
  • @Evan: If your DLL is encrypted, you cannot reference it. You must decrypt it first then load all types via reflection. –  Jul 31 '11 at 20:15
  • Yes, sorry if that was unclear but that is what I was asking. So, I'm assuming then, I could not use your first method to do this? I would have to use your second method instead? –  Jul 31 '11 at 20:16
  • @Evan: That is correct. Visual Studio wouldn't even be able to read an encrypted DLL. You would have to use the second method (or some variation of it). –  Jul 31 '11 at 20:17
  • My idea is to add the dll as an embedded resource, use Assembly to load the contents of this resource, decrypt the resource, then once again use assembly to reference the methods within it. I'll try it out :) –  Jul 31 '11 at 20:19
2
//Assembly1.dll
using System;
using System.Reflection;

namespace TestAssembly
{
    public class Main
    {
        public void Run(string parameters)
        {
            // Do something... 
        }
        public void TestNoParameters()
        {
            // Do something... 
        }
    }
}

//Executing Assembly.exe
public class TestReflection
{
    public void Test(string methodName)
    {
        Assembly assembly = Assembly.LoadFile("...Assembly1.dll");
        Type type = assembly.GetType("TestAssembly.Main");
        if (type != null)
        {
            MethodInfo methodInfo = type.GetMethod(methodName);
            if (methodInfo != null)
            {
                object result = null;
                ParameterInfo[] parameters = methodInfo.GetParameters();
                object classInstance = Activator.CreateInstance(type, null);
                if (parameters.Length == 0)
                {
                    result = methodInfo.Invoke(classInstance, null);
                }
                else
                {
                    object[] parametersArray = new object[] { "Hello" };

                    result = methodInfo.Invoke(classInstance, parametersArray);
                }
            }
        }
    }
}
Damith
  • 62,401
  • 13
  • 102
  • 153
0

Just add this line of code after you obtain reference to your method.

            Method.Invoke(classInstance, new object[] {});

Hope this help.

Saber Amani
  • 6,409
  • 12
  • 53
  • 88
  • This is wrong for two reasons. The method is not defined for the assembly, and you should specify `null` when a method takes no parameters. EDIT: still consider passing `null` as that is what the documentation states. –  Jul 31 '11 at 19:37
  • @Matthew I know that, Maybe I had to explain it in more detail. – Saber Amani Jul 31 '11 at 19:40
0

MethodInfo has a method called Invoke. So simply call Method.Invoke() with an object you created by for example calling System.Activator.CreateInstance()

Sylence
  • 2,975
  • 2
  • 24
  • 31