Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Doublefish от 13-08-2015, 08:23:11

Название: Фатал при сохранении если открыт один dwg
Отправлено: Doublefish от 13-08-2015, 08:23:11
Добрый день

Есть простой код сохранения dwg, если открыто несколько чертежей, то всё нормально сохраняется (и 1.dwg и 2.dwg) , а если остался открыт только один чертеж (1.dwg) и выполнить команду в примере - возникает фатал и autocad вылетает (AutoCAD 2014 в составе С3D), если выполнить эту же команду с другим dwg (2.dwg - открыт только он), то автокад не вылетает.

Подскажите пожалуйста почему вылетает только на 1.dwg и только когда он один открыт (когда открыт только 2.dwg ошибки то нету)?
Код - C# [Выбрать]
  1. [CommandMethod("testsavedwg", CommandFlags.Session)]
  2. public void testsavedwg()
  3. {
  4.    Document acDoc = Application.DocumentManager.MdiActiveDocument;
  5.    acDoc.CloseAndDiscard();
  6.    Database tempDb = new Database(false, true);
  7.    tempDb.ReadDwgFile(@"c:\Тест\1.dwg", FileShare.ReadWrite, false, "");
  8.    tempDb.SaveAs(@"c:\Тест\1_1.dwg", DwgVersion.Current);
  9. }
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Александр Ривилис от 13-08-2015, 08:26:28
Я не рассматривал специфику приложенных чертежей, но зачем ты закрываешь активный текущий чертеж?
И что это за двойное создание базы???
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Doublefish от 13-08-2015, 08:40:07
Есть необходимость сначала закрыть файл, затем выполнить с ним определённые действия и сохранить под другим именем.

1.dwg - я выделил всё в нём и удалил, нарисовал пару объектов, проверил что ошибок нет и очистил.
2.dwg  - создал новый dwg и нарисовал один объект - проверил что ошибок в файле нет.

Если открыто несколько чертежей в автокаде - то ни с 1.dwg ни 2.dwg  ошибки не возникает (поэтому не возникает мысли что проблема в dwg).

Почему фатал возникает если открыт только один dwg, при этом на каких то вылетает (наример 1.dwg), а на других не вылетает (например 2.dwg)

(код поправил)
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Дима_ от 13-08-2015, 09:21:24
а tempDb - это кто?
опс . не проснулся еще
з.ы. - может просто не успевает записать.
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: bargool от 13-08-2015, 09:23:18
А метод помечен как CommandFlags.Session?
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Doublefish от 13-08-2015, 09:33:58
да - [CommandMethod("testsavedwg", CommandFlags.Session)] код поправил

Проверил в AutoCAD 2013, 2014, 2015 (в составе С3D) - фатал возникает только с 1.dwg и только когда он открыт один, с 2.dwg фатал не возникает если открыт только он.
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Александр Ривилис от 13-08-2015, 10:54:37
Проверил в AutoCAD 2013, 2014, 2015 (в составе С3D) - фатал возникает только с 1.dwg и только когда он открыт один, с 2.dwg фатал не возникает если открыт только он.
Проверил в AutoCAD 2015 - ошибка не возникает ни с 1.dwg, ни с 2.dwg
P.S.: AutoCAD очень не любит состояния Zero Document (т.е. когда нет ни одного открытого документа). Так что советую как-то его предотвращать (например, создавать новый пустой документ).
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Александр Ривилис от 13-08-2015, 11:08:04
P.S.S: Проверил в AutoCAD 2013 - тоже никаких Fatal Error нет.
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Doublefish от 13-08-2015, 11:10:04
Я думаю что проблема опять в AutoCAD который входит в состав С3D - у вас я полагаю что просто AutoCAD 2015.
Есть предположиение  что он реагирует на какие то объекты в 1.dwg и при сохранении если не открыт ни один dwg этого сделать не может (в 2.dwg видимо таких объектов нет).

Подскажите пожалуйста каким образом создать пустой dwg и закрыть его после выполнения действий, чтобы обойти данную проблему?
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Александр Ривилис от 13-08-2015, 11:43:47
у вас я полагаю что просто AutoCAD 2015
Уже проверил с Civil3D 2015 - ошибка есть. Более того (чего никогда у меня не было ни в одной из версий в чистом AutoCAD) - после аварийного завершения сбрасывается в 0 системная переменная FILEDIA. Это с учетом того, что у меня "девственно чистый" Civil3D без никаких дополнений и изменений конфигурации.
Подскажите пожалуйста каким образом создать пустой dwg и закрыть его после выполнения действий, чтобы обойти данную проблему?
Закрывать его не нужно. Пусть один открытый пустой болтается:
Код - C# [Выбрать]
  1. [CommandMethod("testsavedwg", CommandFlags.Session)]
  2. public void testsavedwg()
  3. {
  4.   Document acDoc = Application.DocumentManager.MdiActiveDocument;
  5.   if (Application.DocumentManager.Count == 1)
  6.     Application.DocumentManager.Add("acadiso.dwt");
  7.   acDoc.CloseAndDiscard();
  8.   Database tempDb = new Database(false, true);
  9.   tempDb.ReadDwgFile(@"c:\Тест\1.dwg", FileShare.ReadWrite, false, "");
  10.   tempDb.SaveAs(@"c:\Тест\1_1.dwg", DwgVersion.Current);
  11. }
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Doublefish от 13-08-2015, 11:55:45
Да - filedia слетает каждый раз при этом фатале.

Приведённый вариант выше не работает
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Александр Ривилис от 13-08-2015, 11:59:28
Приведённый вариант выше не работает
Приведённый выше вариант я, перед тем как опубликовать, проверил - работает. Ты проверял именно тот код, который я написал?
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Doublefish от 13-08-2015, 12:12:03
Да именно этот код - я его скопировал и назвал testsavedwg2
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Александр Ривилис от 13-08-2015, 12:14:57
А теперь открой 1.dwg или 2.dwg и запусти этот же код.
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Doublefish от 13-08-2015, 12:21:27
Открыл только 2.dwg - таже ошибка: чертеж занят.

Вот так работает
Код - C# [Выбрать]
  1. [CommandMethod("testsavedwg3", CommandFlags.Session)]
  2.         public void testsavedwg3()
  3.         {
  4.             if (acadapp.DocumentManager.Count == 1)
  5.             {
  6.                 Document acDoc = Application.DocumentManager.MdiActiveDocument;
  7.                 acDoc.CloseAndDiscard();
  8.                 Application.DocumentManager.Add("acadiso.dwt");
  9.                 Database tempDb = new Database(false, true);
  10.                 tempDb.ReadDwgFile(@"c:\Тест\1.dwg", FileShare.ReadWrite, false, "");
  11.                 tempDb.SaveAs(@"c:\Тест\1_1.dwg", DwgVersion.Current);
  12.                 Document acDocTmp = Application.DocumentManager.MdiActiveDocument;
  13.                 acDocTmp.CloseAndDiscard();
  14.             }
  15.         }
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Александр Ривилис от 13-08-2015, 12:25:23
Вот так работает
Ну и хорошо.
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Doublefish от 13-08-2015, 12:30:58
Спасибо - отметил как решение.
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Александр Ривилис от 13-08-2015, 12:35:10
Маленькое замечание. Этот код будет работать в единственном случае если открыт только один чертеж.
Думаю так код будет "чище":
Код - C# [Выбрать]
  1. [CommandMethod("testsavedwg4", CommandFlags.Session)]
  2. public void testsavedwg4()
  3. {
  4.     Document acDoc = Application.DocumentManager.MdiActiveDocument;
  5.     if (acDoc != null) acDoc.CloseAndDiscard();
  6.     Document acDocTmp = null;
  7.     if (Application.DocumentManager.Count == 0) {
  8.       acDocTmp = Application.DocumentManager.Add("acadiso.dwt");
  9.     }
  10.     using (Database tempDb = new Database(false, true))
  11.     {
  12.       tempDb.ReadDwgFile(@"c:\Тест\1.dwg", FileShare.ReadWrite, false, "");
  13.       tempDb.CloseInput(true);
  14.       tempDb.SaveAs(@"c:\Тест\1_1.dwg", DwgVersion.Current);
  15.     }
  16.     if (acDocTmp != null)  acDocTmp.CloseAndDiscard();
  17. }
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Привалов Дмитрий от 17-08-2015, 08:45:05
acDocTmp = Application.DocumentManager.Add("acadiso.dwt");

Возможно существует аналог решения, без подгрузки шаблона, создав пустую БД с документом.
Database emptyDb = new Database(true, false);

только как работать с документом такой БД, получить на него ссылку и сделать текущим?
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Александр Ривилис от 17-08-2015, 12:56:24
только как работать с документом такой БД, получить на него ссылку и сделать текущим?
Никак. Если бы воспользовался поиском, то нашёл бы что нет API для создания документа на основе базы.
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Привалов Дмитрий от 17-08-2015, 16:37:06
нет API для создания документа на основе базы
т.е. второй параметр в new Database(true, false) не задействован?

Жаль, мне давно нужно было что-то подобное, для вырезки абриса из плана
Т.е. нужно было создавать промежуточные БД, а в них производить SelectCrossingPolygon
Тогда нашел обходное решение, ввиду простого прямоугольного контура.
переключение документа через API могло облегчить задачу.
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Александр Ривилис от 17-08-2015, 16:43:36
т.е. второй параметр в new Database(true, false) не задействован?
Задействован, но не так, как ты это понимаешь. Фактически он привязывает его к текущему документу.
Почитай эту тему: http://adn-cis.org/forum/index.php?topic=721.0
И это обсуждение: http://adn-cis.org/forum/index.php?topic=490.msg7629#msg7629
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Привалов Дмитрий от 18-08-2015, 09:21:25
Задействован, но не так, как ты это понимаешь. Фактически он привязывает его к текущему документу.
Почитай эту тему: http://adn-cis.org/forum/index.php?topic=721.0
И это обсуждение: http://adn-cis.org/forum/index.php?topic=490.msg7629#msg7629

Жаль что некоторые операции завязаны на документе, и нельзя полноценно создать документ с временной БД.

Пару вопросов не по теме, но тоже связаных с документом.
Есть архив, в нем есть файлы. Некоторые не чищенные, некоторые содержат ошибки БД.
Вопрос про команды purge, audit, recovery.
Отлавливать нежелательное состояние файлов разумно только автоматическим путем.

1. Насколько понимаю отследить есть ошибки или нет в чертеже, можно только открыв чертеж, запустить соответствующую команду и перехватывать сообщения в editor.
Или есть другие возможности?

2. Второй вопрос. Если возможностей нет. Можете ли попросить Autodesk добавить в новых версиях в API проверку чертежа, без необходимости его открывать с документом.
Что-то типа:
Database fileDb = new Database(false, true);
fileDb.ReadDwgFile(filename, System.IO.FileShare.Read, true, "");
DrawingState ds = fileDatabase.CheckDrawingState();
int auditErrorsCount = ds.AuditErrors;
int objectsForPurge = ds.NotUsedDbObjects;

По остальным объектам прокси, учебной версии, и т.д. собрать статистику проблем не представляет.
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Александр Ривилис от 18-08-2015, 10:07:35
1. Насколько понимаю отследить есть ошибки или нет в чертеже, можно только открыв чертеж, запустить соответствующую команду и перехватывать сообщения в editor.
Или есть другие возможности?
API для восстановления чертежа - новый API в AutoCAD 2015 (http://adn-cis.org/api-dlya-vosstanovleniya-chertezha-novyij-api-v-autocad-2015.html)
API для проверки чертежа - новый в AutoCAD 2015 (http://adn-cis.org/api-dlya-proverki-chertezha-novyij-v-autocad-2015.html)
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Привалов Дмитрий от 18-08-2015, 10:19:16
API для восстановления чертежа - новый API в AutoCAD 2015
API для проверки чертежа - новый в AutoCAD 2015
Это я видел и протестировал.
Мало чем отличаются от вызова стандартных команд recovery и audit.
информацию об ошибках выводит в командную строку, как и стандартные команды. В этом то и ограничение.

Хотелось бы получить информацию о наличии/отсутствии ошибок не в командную строку, а в виде bool, еще лучше int для объекта  Database.
Название: Re: Фатал при сохранении если открыт один dwg
Отправлено: Александр Ривилис от 18-08-2015, 10:34:29
В этом то и ограничение.
Записывай log-файл и потом считывай его и ищи ошибки. Если для чертежа требуется recover, то ReadDwgFile должно вызывать исключение, что и есть признаком ошибки.