【问题标题】:Why do I get a SerializationException if I do not copy my .NET dll into the Office application folder?如果我没有将 .NET dll 复制到 Office 应用程序文件夹中,为什么会出现 SerializationException?
【发布时间】:2012-03-29 08:35:58
【问题描述】:

我正在从 Excel VBA 引用一个 C# dll。此 C# dll 连接到 .NET 远程服务。远程服务作为参数传递的一种类型 TSConditionList 包含在 general.dll 中。如果我没有将 general.dll 复制到 Office 应用程序文件夹,则会出现序列化异常,因为 SoapFormatter 没有正确的类型信息。


我的 C# dll 是 TarsanExcelConnector.dll。我使用 REGASM 在固定位置“C:\TarsanExcelConnector”注册此 C# dll。

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Regasm.exe TarsanExcelConnector.dll /codebase /tlb:TarsanExcelConnector.tlb

在“C:\TarsanExcelConnector”目录中,我有许多被 TarsanExcelConnector.dll 引用的 DLL:

  • general.dll
  • TradeSourceParsers.dll
  • TradeSourcePureDataAdapter.dll

所有这三个程序集都已正确定位并加载到 AppDomain 中。

我的VBA代码如下:

Public Function GetTradesDebug(url As String, conditionList() As Variant, contextMap() As Variant) As String
Dim TTSConnection As New TarsanExcelConnector.TarsanExcelConnector
GetTradesDebug = TTSConnection.GetTradesDebug(url, conditionList, contextMap)
End Function

这会失败,但有以下异常:

System.Runtime.Serialization.SerializationException: Invalid method signature 'a1:TSConditionList a2:StringDictionary'.  Server stack trace:     at     System.Runtime.Serialization.Formatters.Soap.SoapHandler.ProcessType(ParseRecord pr, ParseRecord objectPr)    at     System.Runtime.Serialization.Formatters.Soap.SoapHandler.ProcessAttributes(ParseRecord pr, ParseRecord objectPr)       at     System.Runtime.Serialization.Formatters.Soap.SoapHandler.EndElement(String prefix, String name, String urn)       at System.Runtime.Serialization.Formatters.Soap.SoapParser.ParseXml()       at System.Runtime.Serialization.Formatters.Soap.SoapParser.Run()       at     System.Runtime.Serialization.Formatters.Soap.ObjectReader.Deserialize       (HeaderHandler handler, ISerParser serParser)       at System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Deserialize(Stream serializationStream, HeaderHandler handler)       at System.Runtime.Remoting.Channels.CoreChannel.DeserializeSoapResponseMessage(Stream inputStream, IMessage requestMsg, Header[] h, Boolean bStrictBinding)       at System.Runtime.Remoting.Channels.SoapClientFormatterSink.DeserializeMessage(IMethodCallMessage mcm, ITransportHeaders headers, Stream stream)       at System.Runtime.Remoting.Channels.SoapClientFormatterSink.SyncProcessMessage(IMessage msg)     Exception rethrown at [0]:        at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)       at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)       at GFX.Services.ITradeSourceService.GetTrades(TSConditionList conditionList, StringDictionary contextMap)       at GFX.Services.Pure.TradeSourceClient.GetTrades(TSConditionList conditionList, StringDictionary contextMap)       at TTSConnector.TarsanTradeSourceConnector.GetTrades(String tssUrl, Object[,] tssConditionList, Object[,] tssContextMap) in        C:\new_code\TTSConnector\TTSConnector\TarsanTradeSourceConnector.cs:line 99       at TTSConnector.TarsanTradeSourceConnector.GetTradesDebug(String tssUrl, Object[,] tssConditionList, Object[,] tssContextMap) in C:\new_code\TTSConnector\TTSConnector\TarsanTradeSourceConnector.cs:line 66

如果我将 general.dll 复制到 office 应用程序目录中,则不会出现此异常。

对于 Windows 7/Excel 2010,我复制到这里:C:\Program Files (x86)\Microsoft Office\Office14\general.dll

对于 Windows XP/Excel 2003,我复制到这里:C:\Program Files\Microsoft Office\Office11\general.dll

我不明白为什么 SoapFormatter 没有在 'C:\TarsanExcelConnector' 目录中看到 general.dll?如果我检查加载到 AppDomain 中的程序集,我可以看到它肯定是从“C:/TarsanExcelConnector/general.DLL”加载程序集。


当我编写一些测试方法来查找麻烦的类型时,我得到的更有用的 SerializationException 是这样的:“解析错误,没有与 Xml 键 TSConditionList 关联的程序集”。此类型包含在 general.dll 中。

如果运行时从 C:\TarsanExcelConnector 加载程序集,则找不到类型。如果运行时从 Office 目录加载程序集,则序列化成功。为什么?

【问题讨论】:

    标签: .net excel remoting


    【解决方案1】:

    我认为 REGASM 在这种情况下没有帮助。问题是,.net 运行时似乎找不到您的 DLL。

    您应该尝试融合日志查看器: http://msdn.microsoft.com/en-us/library/e74a18c4(v=vs.71).aspx

    此工具可让您查看从您的应用程序加载了哪些 DLL,以及是否有任何故障。

    此外,每当运行时尝试定位 DLL 时,它都会触发 AppDomain.AssemblyResolve 事件,您可以处理该事件来解析 DLL 的路径。

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-03
      • 2014-04-10
      • 2013-10-25
      • 2016-12-05
      • 1970-01-01
      • 1970-01-01
      • 2018-07-28
      相关资源
      最近更新 更多