sta*_*ica 23 .net c# system.reflection entry-point
我需要找到托管代码执行开始的程序集.
// using System.Reflection;
Assembly entryAssembly = Assembly.GetEntryAssembly();
Run Code Online (Sandbox Code Playgroud)
这似乎是要走的路,但MSDN参考页面Assembly.GetEntryAssembly说明这个方法"[c]从非托管代码调用时返回null."
在这种情况下,我想知道哪个程序集是由非托管代码调用的.
有没有可靠的方法来做到这一点,即总是返回非空Assembly引用?
sta*_*ica 18
到目前为止我能想到的最好的是以下内容,它应该在单线程场景中工作:
// using System.Diagnostics;
// using System.Linq;
Assembly entryAssembly = new StackTrace().GetFrames().Last().GetMethod().Module.Assembly;
Run Code Online (Sandbox Code Playgroud)
(上面的代码片段经过优化,易于理解,而不是执行速度或内存效率.)
Eri*_*dil 10
我尝试了两种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.Last();
Assembly entryAssembly = entryMethod.Module.Assembly;
Run Code Online (Sandbox Code Playgroud)
基本上,我走了堆栈,直到找到一个名为"Main" 的传统方法void或int返回类型.如果没有找到这样的方法,我会寻找通过反射调用的方法.例如,NUnit使用该调用来加载单元测试.
当然,我只会在Assembly.GetEntryAssembly()返回时这样做null.
| 归档时间: |
|
| 查看次数: |
13248 次 |
| 最近记录: |