Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#反序列化在自动化加载项中失败,但在NUnit测试中失败_C#_Excel_Serialization_Deserialization - Fatal编程技术网

C#反序列化在自动化加载项中失败,但在NUnit测试中失败

C#反序列化在自动化加载项中失败,但在NUnit测试中失败,c#,excel,serialization,deserialization,C#,Excel,Serialization,Deserialization,我有一个自动化插件(实现Extensibility.IDTExtensibility2),是用C#4编写的,我试图在其中加载一些(二进制)序列化数据。它在单元测试中运行良好,但在Excel中运行时失败: Unable to find assembly 'XXX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. at System.Runtime.Serialization.Formatters.Binary.BinaryAss

我有一个自动化插件(实现Extensibility.IDTExtensibility2),是用C#4编写的,我试图在其中加载一些(二进制)序列化数据。它在单元测试中运行良好,但在Excel中运行时失败:

Unable to find assembly 'XXX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
   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 
在BinaryFormatter上,我将AssemblyFormat(用于序列化和反序列化)设置如下:

serializationCodec.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
我认为这会忽略根据的版本

然后我认为这可能是由于Excel的“可信位置”概念,所以我添加了项目的目录并检查了所有子目录,但错误仍然存在

我尝试添加System.Runtime.Serialization.OptionalFieldAttribute属性,但没有效果

单元测试可以加载自己生成的序列化文件或在Excel中执行的相同代码,但Excel无法加载序列化数据,无论它是否执行了实际序列化

Excel无法反序列化它自己序列化的内容,这一事实暗示这是一种误导,因为它显然可以访问所使用的程序集

所以问题是为什么Excel反序列化与我的单元测试不同?(或者更重要的是,如何在Excel中实现反序列化?)

谢谢。

我一直在寻衅滋事,但由于假设这是一个版本控制问题,所以毫无进展(我已经研究了垫片和各种各样的东西)

事实上,这是由于奇怪的程序集绑定;尽管自动化加载项的DLL可以查看和加载它所依赖的DLL中的类,但当它可以进行反序列化时,它无法找到必要的程序集-即使反序列化调用来自它声称找不到的DLL所属的类

解决方案当然是一个黑客,但它让我克服了这一点,因此,如果其他人像我一样陷入困境,以下是黑客:

在类X中,依赖于各自项目DLL中的类Y和Z(名为ProjectForX、ProjectForY和ProjectForZ)

基本上,它只是挂接到resolve事件中,并根据请求的类型名提供正确的程序集-这不是特别安全(我在程序集描述符中使用逗号以尽量减少冲突)

几乎可以肯定,有一种明确的方法可以做到这一点,而问题可能只是由于配置不当以及我对MS产品,尤其是C#的经验有限


如果我只是构建了一个单片DLL=)

UPDATE:删除AssemblyFormat设置并不能解决这个问题。出现这种情况的唯一原因是为了帮助单元测试(我只是加载以前的序列化数据),我相当确定这是由于[ClassInterface(ClassInterfaceType.AutoDual)]产生警告“…使用ClassInterface(ClassInterfaceType.AutoDual),可能版本不正确…”代码:CA1408。因此,现在我需要找到一种删除这个ClassInterface的方法,它仍然允许自动化加载项注册UDF,并实现IDTExtensibility2来获取Excel.Application的句柄
private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
    {
        if(args.Name.StartsWith("ProjectForX,")) {
            return typeof(X).Assembly;
        } else if(args.Name.StartsWith("ProjectForY,")) {
            return typeof(Y).Assembly;
        } else if(args.Name.StartsWith("ProjectForZ,")) {
            return typeof(Z).Assembly;
        }
        return null;
    }


    public static X LoadX(string filename)
    {
        AppDomain currentDomain = AppDomain.CurrentDomain;
        ResolveEventHandler handler = new ResolveEventHandler(MyResolveEventHandler);
        currentDomain.AssemblyResolve += handler;
        try {
            Stream stream = new FileStream(@filename, FileMode.Open);
            try {
                BinaryFormatter deserializer = createBinaryFormatter();
                X model = (X)deserializer.Deserialize(stream);
                return model;
            } finally {
                stream.Close();
            }
        } finally {
            currentDomain.AssemblyResolve -= handler;
        }
    }