stakxの両方の方法を試しました。
MainModule に基づくメソッドは、一部の特殊なケース (動的アセンブリなど) では機能しません。
StackTrace に基づくメソッドは、mscorlib のように、階層内で高すぎる (または低すぎる) アセンブリを返す可能性があります。
私のユースケースでうまく機能する小さなバリアントを作成しました:
// using System.Diagnostics;
// using System.Linq;
var methodFrames = new StackTrace().GetFrames().Select(t => t?.GetMethod()).ToArray();
MethodBase entryMethod = null;
int firstInvokeMethod = 0;
for (int i = 0; i < methodFrames.Length; i++)
{
var method = methodFrames[i] as MethodInfo;
if (method == null)
continue;
if (method.IsStatic &&
method.Name == "Main" &&
(
method.ReturnType == typeof(void) ||
method.ReturnType == typeof(int) ||
method.ReturnType == typeof(Task) ||
method.ReturnType == typeof(Task<int>)
))
{
entryMethod = method;
}
else if (firstInvokeMethod == 0 &&
method.IsStatic &&
method.Name == "InvokeMethod" &&
method.DeclaringType == typeof(RuntimeMethodHandle))
{
firstInvokeMethod = i;
}
}
if (entryMethod == null)
entryMethod = firstInvokeMethod != 0 ? methodFrames[firstInvokeMethod - 1] : methodFrames.LastOrDefault();
Assembly entryAssembly = entryMethod?.Module?.Assembly;
基本的に、または戻り型を持つ「Main」という名前の従来のメソッドが見つかるまで、スタックを上に移動します。そのようなメソッドが見つからない場合は、リフレクションを介して呼び出されるメソッドを探します。たとえば、NUnit はその呼び出しを使用して単体テストをロードします。void
int
もちろん、 がAssembly.GetEntryAssembly()
返された場合にのみ行いますnull
。