Пакетная обработка чертежей

Автор Тема: Пакетная обработка чертежей  (Прочитано 7663 раз)

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

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

  • ADN OPEN
  • Сообщений: 7
  • Карма: 0
Пишу программу пакетной обработки автокадовских файлов (в основном извлечение из них некоторой информации) для Autocad 2014. При работе с базой данных чертежа без его открытия в окне Autocad проблем нет. Но иногда все же нужно взаимодействие с пользователем (если не удалось найти нужную информацию автоматически). И вот тут получаю постоянные ошибки вида:
Цитировать
FatalExecutionEngineError was detected
Message: В среде выполнения обнаружена критическая ошибка. Ошибка произошла по адресу 0xe62225c0 в потоке 0xacc. Код ошибки 0xc0000005. Она может быть вызвана ошибкой в CLR или в небезопасных либо не поддающихся проверке фрагментах пользовательского кода. Обычно источниками таких ошибок бывают ошибки упаковки, допускаемые пользователями при COM-взаимодействии, либо PInvoke, повредивший стек.
Ниже упрощенный вариант программы:
Код - C# [Выбрать]
  1. // тест пакетной обработки
  2.         [CommandMethod("BTest", CommandFlags.Session)]
  3.         public void BTest()
  4.         {
  5.             System.IO.FileInfo[] files = null;
  6.             System.IO.DirectoryInfo rootDir = new System.IO.DirectoryInfo(@"d:\BTest");
  7.             files = rootDir.GetFiles("*.dwg");
  8.  
  9.             if (files.Length == 0) return;
  10.             foreach (System.IO.FileInfo file in files)
  11.             {
  12.                 // Работа с БД dwg-файла без открытия файла в окне автокада
  13.                 using (Database dwgDB = new Database(false, true))
  14.                 {
  15.                     dwgDB.ReadDwgFile(file.FullName, System.IO.FileShare.ReadWrite, false, "");
  16.                     //Далее манипуляции с базой данных чертежа
  17.                 }
  18.  
  19.                 //Если файл все же понадобилось открыть
  20.                 if (true)
  21.                 {
  22.                     Document activeDoc = Application.DocumentManager.MdiActiveDocument;
  23.                     //Активный файл не должен быть безымянным
  24.                     if (Convert.ToInt32(Application.GetSystemVariable("dwgtitled")) == 0) return;
  25.                     Document dwgFile = Application.DocumentManager.Open(file.FullName, false);
  26.                     Application.DocumentManager.MdiActiveDocument = dwgFile;
  27.                     if (Application.DocumentManager.MdiActiveDocument != dwgFile) return;
  28.  
  29.                     //Далее запросы пользователю и т.п. в активном документе
  30.                     using (Database dwgDB2 = Application.DocumentManager.MdiActiveDocument.Database)
  31.                     {
  32.                         Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  33.                         PromptEntityOptions options = new PromptEntityOptions("\nВыберите однострочный текст ");
  34.                         options.SetRejectMessage("\nОшибочный выбор. Это не однострочный текст");
  35.                         options.AddAllowedClass(typeof(DBText), true);
  36.                         PromptEntityResult pEResult = ed.GetEntity(options);
  37.                     }
  38.  
  39.                     Application.DocumentManager.MdiActiveDocument = activeDoc;
  40.                     dwgFile.CloseAndDiscard();
  41.                 }
  42.  
  43.             }
  44.  
  45.         }
« Последнее редактирование: 20-06-2014, 14:24:33 от Александр Ривилис »

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Пакетная обработка чертежей
« Ответ #1 : 20-06-2014, 13:39:02 »
А это зачем:
Код - C# [Выбрать]
  1. using (Database dwgDB2 = Application.DocumentManager.MdiActiveDocument.Database)
???
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Пакетная обработка чертежей
« Ответ #2 : 20-06-2014, 13:50:38 »
Цитировать
В AutoCAD класс DBObject реализовывает интерфейс IDisposable. Соответственно, указанный интерфейс реализуется и всеми классами, унаследованными от DBObject. Этот же интерфейс реализован и классами Document и Database, однако для Document  вызывать Dispose() никогда не следует (это делает сам AutoCAD), а так же нельзя вызывать Dispose() для объекта, хранящегося в свойстве Document.Database.
тынц.

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

  • ADN OPEN
  • Сообщений: 7
  • Карма: 0
Re: Пакетная обработка чертежей
« Ответ #3 : 20-06-2014, 18:13:15 »
Database для теста пожалуй что и совсем ни к чему. Тем более в конструкции using.
Андрей, спасибо, что ткнули носом в статью. Оба Ваших сайта читал с интересом и ее вроде просматривал, но вот не отложилось. Тогда про IDisposable не задумывался.
Только вот все равно что-то не так. Я уж разные варианты пробовал. С using - это уж изголяться начал. И, как оказалось, наоборот усугубил.
Ну вот меняю например фрагмент с открытием файла на такой:
Код - C# [Выбрать]
  1. //Если файл все же понадобилось открыть
  2.                 if (true)
  3.                 {
  4.                     Document activeDoc = Application.DocumentManager.MdiActiveDocument;
  5.                     //Активный файл не должен быть безымянным
  6.                     if (Convert.ToInt32(Application.GetSystemVariable("dwgtitled")) == 0) return;
  7.                     Document dwgFile = Application.DocumentManager.Open(file.FullName, false);
  8.                     Application.DocumentManager.MdiActiveDocument = dwgFile;
  9.                     if (Application.DocumentManager.MdiActiveDocument != dwgFile) return;
  10.  
  11.                     //Далее запросы пользователю и т.п. в активном документе
  12.                     Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  13.                     PromptEntityOptions options = new PromptEntityOptions("\nВыберите однострочный текст ");
  14.                     options.SetRejectMessage("\nОшибочный выбор. Это не однострочный текст");
  15.                     options.AddAllowedClass(typeof(DBText), true);
  16.                     PromptEntityResult pEResult = ed.GetEntity(options);
  17.  
  18.                     Application.DocumentManager.MdiActiveDocument = activeDoc;
  19.                     dwgFile.CloseAndDiscard();
  20.                 }
И на втором-третьем файле опять получаю:
Цитировать
FatalExecutionEngineError was detected
Message: В среде выполнения обнаружена критическая ошибка. Ошибка произошла по адресу 0xe6e7175e в потоке 0x217c. Код ошибки 0xc0000005. Она может быть вызвана ошибкой в CLR или в небезопасных либо не поддающихся проверке фрагментах пользовательского кода. Обычно источниками таких ошибок бывают ошибки упаковки, допускаемые пользователями при COM-взаимодействии, либо PInvoke, повредивший стек.
Вроде как в строке:
Код - C# [Выбрать]
  1. PromptEntityResult pEResult = ed.GetEntity(options);
Даже ткнуть в текст не успеваю. Запрос, потом ошибка.
С другой стороны, если без отладки запускать, то вроде работает.
« Последнее редактирование: 20-06-2014, 18:23:56 от NomadV »

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Пакетная обработка чертежей
« Ответ #4 : 20-06-2014, 18:24:31 »
Давай, чтобы можно было проверить не кусок кода, а полностью тестовый пример.
P.S.: И используй пожалуйста для кода на C# тэги [code=csharp]...код программы...[/code]- я уже не первый раз исправляю, чтобы читать было легче.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Пакетная обработка чертежей
« Ответ #5 : 20-06-2014, 18:26:19 »
P.S.S.: Стесняюсь спросить какое значение системной переменной FIBERWORLD?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 7
  • Карма: 0
Re: Пакетная обработка чертежей
« Ответ #6 : 20-06-2014, 19:01:04 »
Про теги на будущее учту.
Программа целиком:
Код - C# [Выбрать]
  1. // тест пакетной обработки
  2.         [CommandMethod("BTest", CommandFlags.Session)]
  3.         public void BTest()
  4.         {
  5.             System.IO.FileInfo[] files = null;
  6.             System.IO.DirectoryInfo rootDir = new System.IO.DirectoryInfo(@"d:\BTest");
  7.             files = rootDir.GetFiles("*.dwg");
  8.  
  9.             if (files.Length == 0) return;
  10.             foreach (System.IO.FileInfo file in files)
  11.             {
  12.                 // Работа с БД dwg-файла без открытия файла в окне автокада
  13.                 using (Database dwgDB = new Database(false, true))
  14.                 {
  15.                     dwgDB.ReadDwgFile(file.FullName, System.IO.FileShare.ReadWrite, false, "");
  16.                     //Далее манипуляции с базой данных чертежа
  17.                 }
  18.  
  19.                 //Если файл все же понадобилось открыть
  20.                 if (true)
  21.                 {
  22.                     Document activeDoc = Application.DocumentManager.MdiActiveDocument;
  23.                     //Активный файл не должен быть безымянным
  24.                     if (Convert.ToInt32(Application.GetSystemVariable("dwgtitled")) == 0) return;
  25.                     Document dwgFile = Application.DocumentManager.Open(file.FullName, false);
  26.                     Application.DocumentManager.MdiActiveDocument = dwgFile;
  27.                     if (Application.DocumentManager.MdiActiveDocument != dwgFile) return;
  28.  
  29.                     //Далее запросы пользователю и т.п. в активном документе
  30.                     Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  31.                     PromptEntityOptions options = new PromptEntityOptions("\nВыберите однострочный текст ");
  32.                     options.SetRejectMessage("\nОшибочный выбор. Это не однострочный текст");
  33.                     options.AddAllowedClass(typeof(DBText), true);
  34.                     PromptEntityResult pEResult = ed.GetEntity(options);
  35.  
  36.                     Application.DocumentManager.MdiActiveDocument = activeDoc;
  37.                     dwgFile.CloseAndDiscard();
  38.                 }
  39.  
  40.             }
  41.  
  42.         }

FIBERWORLD=1. А надо 0? Я думал от этого только с пользовательскими формами проблемы могут быть. Честно говоря, вообще не знаю ничего про эту технологию, но обязательно почитаю.
Поставил NEXTFIBERWORLD=0 и после открытия первого же файла ничего больше не происходит. Я опять туплю?)

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Пакетная обработка чертежей
« Ответ #7 : 20-06-2014, 19:28:02 »
FIBERWORLD=1. А надо 0?
Для нормальной работы должна быть 1, для отладки форм и не только - 0. Но это может приводить к тому что вообще не будут открываться dwg-файлы через Application.DocumentManager.Open
Так что тут нужно экспериментировать.
P.S.: Проверил - похоже это проблема отладчика, так как без отладки всё работает нормально. Единственно что обратил внимание, что ты не выполняешь блокировку документа, что неправильно даже если ты его явно не меняешь.
Так что код должен выглядеть так:
Код - C# [Выбрать]
  1.     [CommandMethod("BTest", CommandFlags.Session)]
  2.     public void BTest()
  3.     {
  4.       System.IO.FileInfo[] files = null;
  5.       System.IO.DirectoryInfo rootDir = new System.IO.DirectoryInfo(@"d:\BTest");
  6.       files = rootDir.GetFiles("*.dwg");
  7.  
  8.       if (files.Length == 0) return;
  9.       foreach (System.IO.FileInfo file in files) {
  10.         // Работа с БД dwg-файла без открытия файла в окне автокада
  11.         using (Database dwgDB = new Database(false, true)) {
  12.           dwgDB.ReadDwgFile(file.FullName, System.IO.FileShare.ReadWrite, false, "");
  13.           //Далее манипуляции с базой данных чертежа
  14.         }
  15.  
  16.         // Если файл все же понадобилось открыть
  17.         if (true) {
  18.           Document activeDoc = Application.DocumentManager.MdiActiveDocument;
  19.           //Активный файл не должен быть безымянным
  20.           if (Convert.ToInt32(Application.GetSystemVariable("dwgtitled")) == 0) return;
  21.           Document dwgFile = Application.DocumentManager.Open(file.FullName, false);
  22.           Application.DocumentManager.MdiActiveDocument = dwgFile;
  23.           if (Application.DocumentManager.MdiActiveDocument != dwgFile) return;
  24.           using (DocumentLock doclock = dwgFile.LockDocument()) {
  25.             //Далее запросы пользователю и т.п. в активном документе
  26.             Editor ed = dwgFile.Editor;
  27.             PromptEntityOptions options = new PromptEntityOptions("\nВыберите однострочный текст ");
  28.             options.SetRejectMessage("\nОшибочный выбор. Это не однострочный текст");
  29.             options.AddAllowedClass(typeof(DBText), true);
  30.             PromptEntityResult pEResult = ed.GetEntity(options);
  31.             if (pEResult.Status == PromptStatus.OK) {
  32.               ed.WriteMessage("\nOK!");
  33.             }
  34.           }
  35.           Application.DocumentManager.MdiActiveDocument = activeDoc;
  36.           dwgFile.CloseAndDiscard();
  37.         }
  38.       }
  39.     }
  40.  
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Пакетная обработка чертежей
« Ответ #8 : 20-06-2014, 21:32:22 »
Александр Ривилис,
Раз уж Session, то не плохо было бы блокировать документ при работе с ним.

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Пакетная обработка чертежей
« Ответ #9 : 20-06-2014, 21:34:54 »
Александр Ривилис,
Раз уж Session, то не плохо было бы блокировать документ при работе с ним.
Андрей. Посмотри (внимательно) мой код и комментарий.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Пакетная обработка чертежей
« Ответ #10 : 20-06-2014, 21:38:58 »
Александр Ривилис,
Раз уж Session, то не плохо было бы блокировать документ при работе с ним.
Андрей. Посмотри (внимательно) мой код и комментарий.

Да, проморгал 24-ю строчку :)

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

  • ADN OPEN
  • Сообщений: 7
  • Карма: 0
Re: Пакетная обработка чертежей
« Ответ #11 : 25-06-2014, 12:48:30 »
Кстати, похоже CommandFlags.Session тут имеет принципиальное значение, да? Если ставлю Modal, то открывается первый файл и на этом все заканчивается.

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Пакетная обработка чертежей
« Ответ #12 : 25-06-2014, 13:00:36 »
Кстати, похоже CommandFlags.Session тут имеет принципиальное значение, да? Если ставлю Modal, то открывается первый файл и на этом все заканчивается.
Конечно. И именно так и должно быть. В этом случае не работают операции переключения между документами. Точнее операция переключения дожидается завершения конца модальной команды.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение