Ошибка при десериализации файла в AutoCAD

Автор Тема: Ошибка при десериализации файла в AutoCAD  (Прочитано 13386 раз)

0 Пользователей и 3 Гостей просматривают эту тему.

Оффлайн EvgivachevАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
Добрый день! Столкнулся с такой проблемой, что при запуске команды в AutoCAD, которая десериализует текстовый файл, выпадает ошибка
Цитировать
Не удалось загрузить тип System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[GraphAssembly.Node, GraphAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], необходимый для десериализации.
Странно, что код десериализации файла работает, если запустить его в новом, например, консольном проекте.
Подскажите, пожалуйста, с чем это может быть связано, как исправить?
Код - C# [Выбрать]
  1.  var res = new GraphAssembly.Graph();
  2.                             using (var s = File.Open(pathTofileGraph, FileMode.Open))
  3.                             {
  4.                                 var bFormatter = new BinaryFormatter();
  5.                                 bFormatter.AssemblyFormat =
  6.                                     System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
  7.                                 bFormatter.Binder = new MyBinder(); // MyBinder class code given below
  8.                                 try
  9.                                 {
  10.                                     res = (Graph)bFormatter.Deserialize(s);
  11.                                     var print = res.Print();
  12.                                 }
  13.                                 catch (SerializationException se)
  14.                                 {
  15.                                     Debug.WriteLine(se.Message);
  16.                                 }
  17.                             }
Код - C# [Выбрать]
  1.  internal sealed class MyBinder : SerializationBinder
  2.     {
  3.         public override Type BindToType(string assemblyName, string typeName)
  4.         {
  5.             Type ttd = null;
  6.             try
  7.             {
  8.                 string toassname = assemblyName.Split(',')[0];
  9.                 Assembly[] asmblies = AppDomain.CurrentDomain.GetAssemblies();
  10.                 foreach (Assembly ass in asmblies)
  11.                 {
  12.                     if (ass.FullName.Split(',')[0] == toassname)
  13.                     {
  14.                         ttd = ass.GetType(typeName, false, true);
  15.                         if (ttd is null)
  16.                         {
  17.                             Debug.WriteLine($"Не найден тип \"{typeName}\" в сборке {toassname}");
  18.                         }
  19.                         else break;
  20.                     }
  21.                 }
  22.             }
  23.             catch (System.Exception e)
  24.             {
  25.                 Debug.WriteLine(e.Message);
  26.             }
  27.             return ttd;
  28.         }
  29.     }

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Evgivachev,
Начни с чтения правила о форматировании кода на нашем форуме и исправь код у себя в сообщении.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Код - C# [Выбрать]
  1. internal sealed class MyBinder : SerializationBinder
  2.     {
  3.         public override Type BindToType(string assemblyName, string typeName)
  4.         {
  5.             Type ttd = null;
  6.             try
  7.             {
  8.                 string toassname = assemblyName.Split(',')[0];
  9.                 Assembly[] asmblies = AppDomain.CurrentDomain.GetAssemblies();
  10.                 foreach (Assembly ass in asmblies)
  11.                 {
  12.                     if (ass.FullName.Split(',')[0] == toassname)
  13.                     {
  14.                         ttd = ass.GetType(typeName, false, true);
  15.                         if (ttd is null)
  16.                         {
  17.                             Debug.WriteLine($"Не найден тип \"{typeName}\" в сборке {toassname}");
  18.                         }
  19.                         else break;
  20.                     }
  21.                 }
  22.             }
  23.             catch (System.Exception e)
  24.             {
  25.                 Debug.WriteLine(e.Message);
  26.             }
  27.             return ttd;
  28.         }
  29.     }
Зачем это все? Почему просто не взять Assembly.GetExecutingAssembly()?

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Пример с MSDN
Код - C# [Выбрать]
  1. sealed class Version1ToVersion2DeserializationBinder : SerializationBinder
  2. {
  3.     public override Type BindToType(string assemblyName, string typeName)
  4.     {
  5.         Type typeToDeserialize = null;
  6.  
  7.         // For each assemblyName/typeName that you want to deserialize to
  8.         // a different type, set typeToDeserialize to the desired type.
  9.         String assemVer1 = Assembly.GetExecutingAssembly().FullName;
  10.         String typeVer1 = "Version1Type";
  11.  
  12.         if (assemblyName == assemVer1 && typeName == typeVer1)
  13.         {
  14.             // To use a type from a different assembly version,
  15.             // change the version number.
  16.             // To do this, uncomment the following line of code.
  17.             // assemblyName = assemblyName.Replace("1.0.0.0", "2.0.0.0");
  18.  
  19.             // To use a different type from the same assembly,
  20.             // change the type name.
  21.             typeName = "Version2Type";
  22.         }
  23.  
  24.         // The following line of code returns the type.
  25.         typeToDeserialize = Type.GetType(String.Format("{0}, {1}",
  26.             typeName, assemblyName));
  27.  
  28.         return typeToDeserialize;
  29.     }
  30. }

Оффлайн EvgivachevАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
Assembly.GetExecutingAssembly() не использую потому, что десериализуемый тип "GraphAssembly.Graph" определён во внешней сборке

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Assembly.GetExecutingAssembly() не использую потому, что десериализуемый тип "GraphAssembly.Graph" определён во внешней сборке
Метод AppDomain.CurrentDomain.GetAssemblies() возвращает только сборки, которые УЖЕ загружены. Могу предположить, что при вызове вашей команды в автокаде не происходит загрузка этой самой внешней сборки.
Просто в начале команды вызовите метод Assembly.LoadFrom() с указанием этой самой сборки

Оффлайн EvgivachevАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
стр. 17 в классе MyBinder выводит
Цитировать
Не найден тип "System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[GraphAssembly.Node, GraphAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]" в сборке mscorlib
Не найден тип "System.Collections.Generic.List`1[[GraphAssembly.Section, GraphAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]" в сборке mscorlib
Поэтому предполагаю, что типы из "GraphAssembly" загрузить удалось

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
стр. 17 в классе MyBinder выводит
Цитировать
Не найден тип "System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[GraphAssembly.Node, GraphAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]" в сборке mscorlib
Не найден тип "System.Collections.Generic.List`1[[GraphAssembly.Section, GraphAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]" в сборке mscorlib
Поэтому предполагаю, что типы из "GraphAssembly" загрузить удалось
Вам лень попробовать мое предположение, добавив всего одну строчку?

Оффлайн EvgivachevАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
Ни в коем случае, дело в том, я пробовал уже этот метод, но сейчас ещё раз попробовал - результат тот же.
Ещё так попробовал:
Код - C# [Выбрать]
  1.  if (File.Exists(pathTofileGraph))
  2.                         {
  3.                             var myAssembly = Assembly.LoadFrom(
  4.                                 "R:\\04_Надстройки\\ЭОМ\\Схемы_Схема ВРУ Revit\\Рабочая\\InputDeviceAutoCAD\\InputDeviceAutoCAD\\bin\\Debug\\GraphAssembly.dll");
  5.                             var myAssName = myAssembly.FullName;
  6.                             var res = new GraphAssembly.Graph();
  7.                             using (var s = File.Open(pathTofileGraph, FileMode.Open))
  8.                             {
  9.                                 var bFormatter = new BinaryFormatter();
  10.                                 bFormatter.AssemblyFormat =
  11.                                     System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
  12.  
  13.                                 //bFormatter.Binder = new MyBinder(); // MyBinder class code given below
  14.  
  15.                                 try
  16.                                 {
  17.                                     res = (Graph)bFormatter.Deserialize(s);
  18.                                     var print = res.Print();
  19.                                 }
  20.                                 catch (SerializationException se)
  21.                                 {
  22.                                     Debug.WriteLine(se.Message);
  23.                                 }
  24.                             }
  25.                         }

Цитировать
Вызвано исключение: "System.Runtime.Serialization.SerializationException" в mscorlib.dll
Не удалось найти сборку "GraphAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null".

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Попробуйте Solution 1 отсюда - https://www.codeproject.com/Questions/181389/AppDomain-refuses-to-load-an-assembly
А также проверьте версии этой сборки

Оффлайн EvgivachevАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
Результат всё тот же. Версия сборки не менялась

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Результат всё тот же. Версия сборки не менялась
Попробуйте Assembly.LoadFile() вместо Assembly.LoadFrom()

Оффлайн EvgivachevАвтор темы

  • ADN OPEN
  • Сообщений: 16
  • Карма: 0
Всё так же

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Что-то вы недоговариваете =)) Придется, видимо, прикладывать нам тестовый проект. Идеи закончились

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Evgivachev,
Версия AutoCAD? Пытаетесь загрузить сборку GraphAssembly.dll с сетевого устройства?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение