为什么 GetEntryAssembly returns 为空?

Why GetEntryAssembly returns null?

GetEntryAssembly在C#中的底层实现是什么?为什么从非托管应用程序加载 dll 时 return null?

MSDN 文档说:

The GetEntryAssembly method can return null when a managed assembly has been loaded from an unmanaged application. For example, if an unmanaged application creates an instance of a COM component written in C#, a call to the GetEntryAssembly method from the C# component returns null, because the entry point for the process was unmanaged code rather than a managed assembly.

我有以下设置:

Native executable (C++) -> Mixed mode assembly (C++/cli) -> Managed assembly (C#)

托管程序集是可选的,在混合模式程序集中,可以调用 GetEntryAssembly 并获取 null。

在调试时我们在 C# 中跟踪到这个调用 source code:

[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void GetEntryAssembly(ObjectHandleOnStack retAssembly);

我们可以看到入口程序集应该是本机可执行文件。但是它没有被检索到。请问这是什么原因呢?原生到托管的过渡不应该解决这个问题吗?

编辑

GetEntryAssembly 由 .NET 内部使用。我们只是在 returns null 时遇到副作用。 可在托管程序集中用一行重现:

System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForDomain ();

这将引发以下异常:System.IO.IsolatedStorage.IsolatedStorageException: Unable to determine the identity of domain.此异常的根本原因似乎是入口程序集为空。

程序集是特定于 .NET 的 class。正如您提到的,您从非托管代码调用托管方法,并且 GetEntryAssembly 将 return null 因为根本没有理由 return 任何东西!

程序集中的所有方法都绑定到 .NET 体系结构,C++、Java 或任何其他外部编译源都没有可能的实现。

如果你还是不明白 - 试着想象使用这种'Assembly'的反射:获取一些核心优化的 c++ 方法名称,或者获取变量类型......还有这个仅针对C++,其他语言更不用说

在我的例子中,GetEntryAssembly() 在被单元测试框架调用时返回了 null。对我来说,切换到 GetCallingAssembly() 就足够了。可能不会在所有情况下都有效,但对某些情况会有效。

F# 示例:

let getEntryAssembly() =
    match Assembly.GetEntryAssembly() with
    | null -> Assembly.GetCallingAssembly()
    | entryAsm -> entryAsm