6

dll を動的に取得します。メソッドを呼び出すには、dll をロードし、名前空間、クラス名を取得する必要があります (メソッド名は静的であり、常に「OnStart()」になります)。基本的に、dll をロードしてメソッドを実行する必要があります。誰か助けてくれませんか!!!.

4

4 に答える 4

14

アセンブリをロードするには、次のようにします。

Assembly assembly = Assembly.LoadFile(@"test.dll");

これは、アセンブリがファイルとしてディスク上にあることを前提としています。データベースからバイト配列として取得する場合など、そうでない場合は、Assembly オブジェクトを読み込んだ後に Assembly オブジェクトを提供するのに役立つ他のメソッドがAssemblyにあります。

アセンブリ内のすべてのクラスを反復処理するには、次のようにします。

Assembly assembly = Assembly.LoadFile(@"test.dll");
foreach (Type type in assembly.GetTypes())
{
    if (type.IsClass)
    {
        ...
    }
}

OnStart 静的メソッドを見つけるには、次のようにします。

Assembly assembly = Assembly.LoadFile(@"test.dll");
foreach (Type type in assembly.GetTypes())
{
    if (type.IsClass)
    {
        MethodInfo method = type.GetMethod("OnStart",
            BindingFlags.Static | BindingFlags.Public);
        if (method != null)
        {
            ...
        }
    }
}

メソッドを呼び出すには、次のようにします。

Assembly assembly = Assembly.LoadFile(@"test.dll");
foreach (Type type in assembly.GetTypes())
{
    if (type.IsClass)
    {
        MethodInfo method = type.GetMethod("OnStart",
            BindingFlags.Static | BindingFlags.Public);
        if (method != null)
        {
            method.Invoke(null, new Object[0]); // assumes no parameters
            break; // no need to look for more methods, unless you got multiple?
        }
    }
}

メソッドに引数を渡す必要がある場合は、それらをオブジェクト配列に入れます。

Object[] arguments = new Object[] { arg1, arg2, arg3 ... };
method.Invoke(null, arguments);

上記のコードは、Linq を使用してメソッドを見つけることにより、次のように折りたたむことができます。

Assembly assembly = Assembly.LoadFile(@"test.dll");
var method = (from type in assembly.GetTypes()
              where type.IsClass
              let onStartMethod = type.GetMethod("OnStart",
                  BindingFlags.Static | BindingFlags.Public)
              where onStartMethod != null
              select onStartMethod).FirstOrDefault();
if (method != null)
{
    method.Invoke(null, new Object[0]); // assumes no parameters
}
于 2009-10-20T09:49:47.147 に答える
1
       object result = null;

        using (StreamReader reader = new StreamReader(ASSEMBLYPATH, Encoding.GetEncoding(1252), false))
        {
            byte[] b = new byte[reader.BaseStream.Length];
            reader.BaseStream.Read(b, 0, Convert.ToInt32(reader.BaseStream.Length));
            reader.Close();

            Assembly asm = AppDomain.CurrentDomain.Load(b);
            Type typeClass = asm.GetType(CLASSFULLNAME); // including namespace
            MethodInfo mi = typeClass.GetMethod("OnStart");
            ConstructorInfo ci = typeClass.GetConstructor(Type.EmptyTypes);
            object responder = ci.Invoke(null);

            // set parameters
            object[] parameters = new object[1];
            parameters[0] = null;  // no params


            result = mi.Invoke(responder, parameters);
        }

このコードを使用する利点は、アセンブリが使用後にアンロードされるため、メソッドの呼び出し後に dll を安全に削除できることです。

于 2009-10-20T09:49:29.750 に答える
0

ここをチェックしてください:http://dotnetguts.blogspot.com/2008/12/reflection-in-c-list-of-class-name.html

そして、ここでメソッドを呼び出します: http://www.csharphelp.com/archives/archive200.html

これらのリンクの用語をさらに検索すると、さらに多くの情報が見つかります。

于 2009-10-20T09:44:01.783 に答える
0

実行時に、名前空間は単に型名の一部になります。

したがって、次のことが必要です。

  1. アセンブリをロードする
  2. 必要な型の Type インスタンスを取得します。
  3. MethodInfo呼び出したいメソッドの を取得します。
  4. メソッドを呼び出します。

これらのうち、2 ~ 4 は簡単です。1は、アセンブリがどこにあるによって、簡単な場合とそうでない場合があります。通常のアセンブリ ロード (「プローブ」) を介してアセンブリを見つけることができると仮定します。これは、引数を取らないが戻り値を持つ型の public static メソッドを呼び出します。

var asm = Assembly.Load(assemblyName);
var t = asm.GetType(typeName);
// Pass array of parameter types to resolve between overloads (here no arguments).
var m = t.GetMathod(methodName, BindingFlags.Static, null, new Type[] {}, null);
// Pass no "this" or arguments.
var res = (resultType) m.Invoke(null, null);

ここでの詳細の多くは、呼び出すアセンブリ、型、およびメソッドの詳細によって異なります。

于 2009-10-20T09:49:12.793 に答える