TypeAccessException:尝试按方法...访问类型...失败

mar*_*ark 11 .net

完整的异常详情如下:

System.TypeAccessException occurred
  Message=Attempt by method 'DynamicClass.(System.Text.StringBuilder, System.Object, Int32)' to access type 'System.Collections.Generic.IEnumerable`1<System.Collections.Generic.KeyValuePair`2<System.Object,NetworkCatcher.Entities.Server.CalculatedFCStateManager+Descriptor>>' failed.
  Source=Anonymously Hosted DynamicMethods Assembly
  TypeName=""
  StackTrace:
       at (StringBuilder , Object , Int32 )
  InnerException: 
Run Code Online (Sandbox Code Playgroud)

方法名称DynamicClass.(System.Text.StringBuilder, System.Object, Int32)对应于此动态生成的方法:

private delegate StringBuilder AppendToStringBuilderDelegate(StringBuilder sb, object obj, int maxItemsToDisplay);

private static AppendToStringBuilderDelegate EmitDelegate(Type type, MethodInfo methodInfo)
{
  var dynamicMethod = new DynamicMethod(string.Empty, typeof(StringBuilder), TypeArray<StringBuilder, object, int>.Value);
  var parameters = methodInfo.GetParameters();

  var il = dynamicMethod.GetILGenerator();
  il.Emit(OpCodes.Ldarg_0);
  il.Emit(OpCodes.Ldarg_1);
  il.Emit(OpCodes.Unbox_Any, parameters[1].ParameterType);
  il.Emit(OpCodes.Ldarg_2);
  il.EmitCall(OpCodes.Call, methodInfo, null);
  il.Emit(OpCodes.Ret);
  return s_methodCache[type] = (AppendToStringBuilderDelegate)dynamicMethod.CreateDelegate(typeof(AppendToStringBuilderDelegate));
}
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪是:

[Lightweight Function]  
Shunra.Common.dll!Shunra.Common.DebugUtils.AppendObject<System.Collections.Generic.IDictionary<object,NetworkCatcher.Entities.Server.CalculatedFCStateManager.Descriptor>>(System.Text.StringBuilder sb, System.Collections.Generic.IDictionary<object,NetworkCatcher.Entities.Server.CalculatedFCStateManager.Descriptor> obj, int maxItemsToDisplay) Line 261 + 0x14 bytes    C#
Shunra.Common.dll!Shunra.Common.DebugUtils.ToString<System.Collections.Generic.IDictionary<object,NetworkCatcher.Entities.Server.CalculatedFCStateManager.Descriptor>>(System.Collections.Generic.IDictionary<object,NetworkCatcher.Entities.Server.CalculatedFCStateManager.Descriptor> obj, int maxItemsToDisplay) Line 435 + 0x4d bytes  C#
NC.Entities.Server.dll!NetworkCatcher.Entities.Server.CalculatedFCStateManager.Populate() Line 98 + 0x2c bytes  C#
NC.Entities.Server.dll!NetworkCatcher.Entities.Server.RunManager.Initialize() Line 500 + 0x1c bytes C#
NC.Entities.Server.dll!NetworkCatcher.Entities.Server.EntryPoint.OnStart() Line 63 + 0x5 bytes  C#
Shunra.Infra.dll!Shunra.Infra.EntryPoint.Start() Line 37 + 0xb bytes    C#
Shunra.Common.dll!Shunra.Common.Wcf.ShunraServiceHost.OnOpening() Line 47 + 0x11 bytes  C#
System.ServiceModel.dll!System.ServiceModel.Channels.CommunicationObject.Open(System.TimeSpan timeout) + 0x113 bytes    
System.ServiceModel.dll!System.ServiceModel.Channels.CommunicationObject.Open() + 0x25 bytes    
NC.Server.Host.exe!NetworkCatcher.Server.Host.NCServerInstance.StartHosts() + 0xef bytes    
Shunra.Common.dll!Shunra.Common.Wcf.ShunraServerInstance<NetworkCatcher.Server.Host.NCServerInstance,NetworkCatcher.Server.Host.ServerHost>.Run() Line 357 + 0xb bytes  C#
NC.Server.Host.exe!NetworkCatcher.Server.Host.Program.Main(string[] args) + 0x84 bytes  
Run Code Online (Sandbox Code Playgroud)

最后,两个程序集--Sunra.Common.dll和NC.Entities.Server.dll属于相同的代码库.NC.Entities.Server.dll从位于根文件夹正下方的私有bin文件夹加载,其中存在Shunra.Common.dll.

一切正常,直到我决定在另一个帐户下运行代码.因此,我创建了一个新帐户,使其成为管理员并在此帐户下打开了一个提升的控制台窗口.该帐户可以访问所有文件.不过,当我运行应用程序时,我收到此错误,我完全迷失了它.

小智 12

我最近遇到了类似的问题,事实证明我所谓的(即MethodInfo.DeclaringType)类型是内部的.将其设置为public后,类型访问成功.

  • 如果在实例化DynamicMethod时使用参数'restrictedSkipVisibility:true',也可以修复此可见性问题.调用程序集和您正在访问的类型之间的信任级别应该是兼容的,但它值得一试. (3认同)

小智 0

您可能会通过运行fuslogvw(Fusion Log Viewer)了解有关所发生情况的更多信息。如果您对此不熟悉,它使您能够记录所有绑定和尝试绑定到 .NET 程序集 - 它会告诉您为查找程序集而探测的所有路径,并可能为您提供绑定失败的更多原因。如果你熟悉的话,你可以忽略我要说的其余内容!

如果不是绑定失败,至少您已经消除了一种可能性。

要运行查看器,请在 Visual Studio 命令提示符下使用 fuslogvw,并将设置从“禁用日志”更改为“将绑定失败记录到磁盘”或“将所有绑定记录到磁盘”(根据首选项)。再次运行您的代码并单击刷新。双击条目可查看详细信息。

确保完成后禁用日志 - fuslogvw 正在监视所有进程的绑定,如果让它继续运行,您的计算机将 1) 变慢,2) 充满日志。