c#反序列化在自动化插件中失败,但在NUnit测试中没有

本文关键字:但在 NUnit 测试 失败 反序列化 自动化 插件 | 更新日期: 2023-09-27 18:03:34

我有一个自动化插件(实现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 . serialize . optionalfieldattribute属性,但它没有帮助。

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

事实上,Excel不能反序列化它自己序列化的东西,这暗示了这是一个转移注意力的问题,因为它显然可以访问所使用的程序集。

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

谢谢。

c#反序列化在自动化插件中失败,但在NUnit测试中没有

我一直在寻找转移注意力的话题,但我认为这是一个版本问题(我已经研究了漏洞和各种各样的问题)。

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

解决方案当然是一个hack,但它让我通过了这个,所以如果其他人像我一样被卡住了,这里有一个hack(s):

在类X内部,这取决于类Y和Z各自的项目dll(名为ProjectForX, ProjectForY和ProjectForZ)

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;
        }
    }

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

几乎肯定有一个明确的方法来做到这一点,问题可能只是由于配置不当和我对微软产品的有限经验,特别是c#。

这不会是一个问题,如果我只是建立一个单一的DLL =)

相关文章: