Почему я получаю исключение SerializationException, если я не копирую свою библиотеку .NET в папку приложения Office? - PullRequest
1 голос
/ 29 марта 2012

Я ссылаюсь на C # dll из Excel VBA. Эта C # dll подключается к .NET Remote Service. Один из типов, которые удаленная служба передает в качестве параметра, TSConditionList, содержится в general.dll. Если я не копирую файл general.dll в папку приложения Office, я получаю исключение сериализации, поскольку SoapFormatter не имеет правильной информации о типе.


Моя C # dll - это TarsanExcelConnector.dll. Я использую REGASM для регистрации этой C # dll в фиксированном месте 'C: \ TarsanExcelConnector'.

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

В каталоге 'C: \ TarsanExcelConnector' у меня есть несколько библиотек DLL, на которые ссылается TarsanExcelConnector.dll:

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

Все три из этих сборок правильно расположены и загружены в домен приложений.

Мой код 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 не видит файл general.dll в каталоге 'C: \ TarsanExcelConnector' ?? Если я проверяю сборки, загруженные в домен приложений, я вижу, что он определенно загружает сборку из 'C: /TarsanExcelConnector/general.DLL'.


Когда я написал несколько тестовых методов для поиска проблемного типа, гораздо более полезное исключение SerializationException, которое я получил, было примерно таким: Этот тип содержится в general.dll.

Если среда выполнения загружает сборку из C: \ TarsanExcelConnector, то она не может найти тип. Если среда выполнения загружает сборку из каталога Office, то сериализация завершается успешно. ПОЧЕМУ?

1 Ответ

0 голосов
/ 30 марта 2012

Я думаю, что REGASM не помогает в этом случае. Проблема в том, что среда выполнения .net не находит вашу DLL.

Вы должны попробовать программу просмотра журнала Fusion: http://msdn.microsoft.com/en-us/library/e74a18c4(v=vs.71).aspx

Этот инструмент позволяет увидеть, какие библиотеки DLL загружены из вашего приложения и есть ли сбои.

Кроме того, всякий раз, когда среда выполнения пытается найти DLL, она запускает событие AppDomain.AssemblyResolve , которое можно обработать, чтобы определить путь к вашей DLL.

Надеюсь, это поможет!

...