二进制格式化程序在C#反序列化时找不到“程序集”

5
我有一个序列化和反序列化调用的程序,当我尝试将我的DLL附加到另一个程序时,它会显示:无法找到程序集“ASCOM.BHOProxy.Connector,版本=1.0.0.0,Culture=neutral,PublicKeyToken=74643865492aa2e6”。 我能理解如果这是一个引用问题或其他什么问题,但问题在于抛出异常的代码是在ASCOM.BHOProxy.Connector内部。我想过使用某种第三方序列化程序,但不确定要使用什么。该程序集由应用程序加载的另一个DLL加载。
序列化数据通过TCP连接传输到相同的连接器(通常是由另一个程序加载的同一文件),在那里进行反序列化。只有在从外部程序调用时才会抛出异常,而且在Visual Studio中调试时正常工作。
Their Program --(late binding)--> My Main DLL --(.NET Project Reference)--> My Connector DLL

堆栈跟踪:

   at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
   at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
   at Connector.PortComProxy.DecodeMessage(List`1 buff) in c:\Users\Arlen\Documents\Visual Studio 2012\Projects\DriverProxy\PortComClient\PortComProxy.cs:line 259

2
这通常是由DLL加载方式引起的问题。一个非常常见的错误是使用Assembly.LoadFile(),这将产生此异常。请始终使用LoadFrom()。 - Hans Passant
你有了解过AssemblyResolvers吗?http://msdn.microsoft.com/en-us/library/microsoft.practices.composite.modularity.assemblyresolver.aspx 我并不完全理解这个问题,但在反序列化时我发现这个很有用。你可以设置一个处理程序并进行调试,可能会有所帮助。 - PeteH
我在一个由COM加载的程序集中遇到了问题(类型具有[ComVisible(true)])。第二次(但不是第一次!)尝试反序列化其自身程序集中驻留的特定类型时,我会收到相同的“无法找到程序集'(运行此代码的程序集名称!)”异常。令人发狂。被接受的答案对我也有效,但我不喜欢不理解发生了什么。 - dlf
2个回答

5
非常感谢您,Ken。这就是我为其他可能需要的人所做的事情。我不知道解析器是否是静态的,是否有任何区别。
using System.Reflection;
...
public class MyClass{
    public MyClass()
    { 
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
    }
    private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
    {
        return typeof(MyClass).Assembly;
    }
}

5
我不知道为什么有时会找不到程序集。然而,我使用了AppDomain.AssemblyResolve事件来加载无法通过.NET提供的正常程序集加载解析找到的程序集。在我的情况下,是因为我需要从注册表项中查找程序集,使用这个事件,我能够找到并加载程序集,防止出现程序集未找到异常。
至少使用此事件可以让您验证BinaryFormatter尝试解析的类型。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接