【发布时间】: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 目录加载程序集,则序列化成功。为什么?
【问题讨论】: