【发布时间】:2017-03-06 03:49:59
【问题描述】:
GetEntryAssembly 在 C# 中的底层实现是什么?为什么从非托管应用程序加载 dll 时返回 null?
MSDN 文档说:
从非托管应用程序加载托管程序集时,GetEntryAssembly 方法可以返回 null。例如,如果非托管应用程序创建用 C# 编写的 COM 组件的实例,则从 C# 组件调用 GetEntryAssembly 方法将返回 null,因为进程的入口点是非托管代码而不是托管程序集。
我有以下设置:
本机可执行文件 (C++) -> 混合模式程序集 (C++/cli) -> 托管 程序集 (C#)
托管程序集是可选的,在混合模式程序集下,可以调用 GetEntryAssembly 并获取 null。
在调试时,我们在 C# source code 中跟踪到此调用:
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void GetEntryAssembly(ObjectHandleOnStack retAssembly);
我们可以看到入口程序集应该是本机可执行文件。但是,它不会被检索。我想知道这是什么原因?本机到托管转换不应该解决这个问题吗?
编辑
GetEntryAssembly 在 .NET 内部使用。当它返回null 时,我们只是遇到了副作用。
可在托管程序集中用一行重现:
System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForDomain ();
这将引发以下异常:System.IO.IsolatedStorage.IsolatedStorageException: Unable to determine the identity of domain. 此异常的根本原因似乎是条目程序集为空。
【问题讨论】:
-
在CLR中实现。当然,同样的情况,它不能返回一个程序集对象引用,您的本机 C++ 可执行文件不是程序集。考虑改用 Process.GetCurrentProcess()。
-
我没有在我的代码中直接使用 GetEntryAssembly。这在 C# 内部使用。并且由于它返回 null,因此其他一些代码行为不端。例如。如果有人调用
System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForDomain将得到System.IO.IsolatedStorage.IsolatedStorageException: Unable to determine the identity of domain. -
您当然必须修复“其他代码”,它不能依赖独立存储工作。顺便说一句,从您的问题中隐藏此信息毫无意义,它无助于我们帮助您。
-
我想提出一个一般性问题,抱歉。为了提供完整的图片,我们正在使用 Open XML SDK,对于大文件,它开始使用独立存储而不是主内存。并且由于上述异常而无法执行操作。因此,关于入口组件的问题。