为什么我得到SerializationException如果我不把我的.NET DLL复制到Office应用程序文件夹?

我从Excel VBA引用C#DLL。 这个C#DLL连接到一个.NET远程服务。 RemoteService作为parameter passing的types之一TSConditionList包含在general.dll中。 如果我不复制general.dll到Office应用程序文件夹然后我得到序列化exception,因为SoapFormatter没有正确的types信息。


我的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到办公室应用程序目录,那么我不会得到这个例外。

对于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”加载程序集。


当我编写一些testing方法来find麻烦的types时,我得到的更有用的SerializationException就像这样:'Parse Error,没有与Xml关键字TSConditionList关联的程序集'。 这个types包含在general.dll中。

如果运行时从C:\ TarsanExcelConnector加载程序集,则无法findtypes。 如果运行时从Office目录加载程序集,则序列化成功。 为什么?

我认为在这种情况下,REGASM不起作用。 问题是,.net运行时似乎没有find你的DLL。

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

这个工具可以让你看到你的应用程序加载了哪些DLL,以及是否有任何失败。

此外,无论何时运行时试图find一个DLL它触发AppDomain.AssemblyResolve事件,您可以处理,以解决您的DLL的path。

希望能帮助到你!