Закрытие чертежа - "чертеж занят"?

Автор Тема: Закрытие чертежа - "чертеж занят"?  (Прочитано 7157 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 0
Наверное вопрос легкий (Autocad 2014), но я не знаю как правильно:

При открытии чертежа проверяю "учебную версию" если учебная хочу сразу закрыть - но вываливается ошибка "чертеж занят". как правильно закрыть чертеж, ну или оно чтобы дождалось (как освободился чертеж" и закрыло. Делаю так:
Код - C# [Выбрать]
  1. Autodesk.AutoCAD.ApplicationServices.Document dwgopen = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  2. bool pr=dwgopen.Database.IsEmr;
  3. if (pr)
  4. dwgopen.CloseAndDiscard();
  5.  
Как закрыть чертеж?
« Последнее редактирование: 17-11-2017, 16:32:19 от Александр Ривилис »

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #1 : 17-11-2017, 16:35:18 »
1. Пожалуйста прочитай у меня в подписи как следует форматировать код на форуме и в дальнейшем соблюдай это правило.
2. В каком контексте ты пытаешься закрыть документ? Это событие открытия документа или команда? И еслиа команда то контекста документа или контекста приложения?
Слишком мало информации.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #2 : 17-11-2017, 16:47:17 »
Простейший вариант - затолкай в консоль команду Close. Когда сможет тогда и выполнится.

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 0
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #3 : 17-11-2017, 18:57:15 »
при автозагрузке одного из лисп вызывается команда через командную строку:
Код - Auto/Visual Lisp [Выбрать]
  1. (command "checkuv")
А до этого загружается dll на c#, типо что то такого:
Код - C# [Выбрать]
  1. public class Main : IExtensionApplication
  2.     {
  3. //.........
  4.  
  5.         [CommandMethod("checkuv")]
  6.         public void checkuv()
  7.         {
  8. //ну и впринципе сам код который писался ранее
  9. Autodesk.AutoCAD.ApplicationServices.Document dwgopen = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  10. bool pr=dwgopen.Database.IsEmr;
  11. if (pr)
  12. dwgopen.CloseAndDiscard();
  13.          }
  14.  
  15. //.........
  16. }

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #4 : 17-11-2017, 19:41:24 »
Для начала попробуй заменить:
Код - C# [Выбрать]
  1. [CommandMethod("checkuv")]
на
Код - C# [Выбрать]
  1. [CommandMethod("checkuv",CommandFlags.Session)]
Еще вариант с использованием COM/ActiveX здесь: http://adndevblog.typepad.com/autocad/2012/05/closing-drawing-file-without-saving.html
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 0
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #5 : 17-11-2017, 22:03:22 »
Не помогло, не то не другое:
при загрузке автокада и запуска отдельно команды, оно срабатывает.
Но при загрузке команды через лисп - оно выдает ошибку и аварийно закрывается


как и предложение avc правда не в консоль а в командную строку close
Код - C# [Выбрать]
  1. dwgop.SendStringToExecute("(command \"_close\")\n", true, false, false);
- все тоже аварийное закрытие автокада

//без флага CommandFlags.Session простой способ закрытия выбивал ошибку, но не фатальную...

___________
а есть ли событие завершение открытие загрузки чертежа? = просто у меня подозрение, что оно просто не загружает доконца чертеж = т.е в него еще грузятся лиспы и длл ====и мы пытаемся закрыть его, хоть он еще не загрузился?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #6 : 18-11-2017, 00:16:16 »
а есть ли событие завершение открытие загрузки чертежа? = просто у меня подозрение, что оно просто не загружает доконца чертеж = т.е в него еще грузятся лиспы и длл ====и мы пытаемся закрыть его, хоть он еще не загрузился?
Такого события в чистом виде нет. И в любом случае из события закрыть чертеж ты не сможешь - в лучшем случае сможешь запустить команду на закрытие. Вариант с COM\ActiveX уже проверил?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #7 : 18-11-2017, 00:19:03 »
И в любом случае из события закрыть чертеж ты не сможешь
Вы имеете в виду события документа? Может быть, стоит попробовать сделать это в Application.Idle?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #8 : 18-11-2017, 00:21:32 »
Может быть, стоит попробовать сделать это в Application.Idle?
Запустить из этого события команду, закрывающую чертеж - можно. А вот выполнять в этом событии что-то типа CloseAndDiscard я бы не рискнул.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #9 : 18-11-2017, 00:34:23 »
Кстати команду можно запускать через:
Код - C# [Выбрать]
  1. [DllImport("accore.dll", CharSet = CharSet.Unicode,  CallingConvention = CallingConvention.Cdecl,  EntryPoint = "ads_queueexpr")]
  2. extern static private int ads_queueexpr(byte[] command);
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 0
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #10 : 18-11-2017, 15:08:32 »
Вариант с COM\ActiveX уже проверил?
да я сразу тогда и проверил, и отписался что не тот и не тот не прошел ...
насчет accore.dll попробую...

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 0
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #11 : 19-11-2017, 18:07:59 »
Кстати команду можно запускать через:
Александр, а это на 2014 автокаде работает или с 2015, или не так делаю:
Код - C# [Выбрать]
  1. ads_queueexpr(System.Text.Encoding.UTF32.GetBytes("Close"));
У меня самое интересное что оно запускается в отладчике раньше чем запускается сам автокад, а если дать потом с чертежа ничего не происходит. Пробывал и "_Close" и UTF8...может я что то не так делаю ::)

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #12 : 19-11-2017, 19:09:23 »
Кстати команду можно запускать через:
Александр, а это на 2014 автокаде работает или с 2015, или не так делаю:
Код - C# [Выбрать]
  1. ads_queueexpr(System.Text.Encoding.UTF32.GetBytes("Close"));
У меня самое интересное что оно запускается в отладчике раньше чем запускается сам автокад, а если дать потом с чертежа ничего не происходит. Пробывал и "_Close" и UTF8...может я что то не так делаю ::)
Работает начиная с AutoCAD 2000 еще до всяких .NET.

Должно быть как-то так:
Код - C# [Выбрать]
  1. ads_queueexpr("(command \"_Close\")\n");
В описании ads_queueexpr кажется ошибка. Должно быть:
Код - C# [Выбрать]
  1. [DllImport("accore.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
  2. extern static private int ads_queueexpr(string strExpr);
« Последнее редактирование: 19-11-2017, 20:08:07 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 0
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #13 : 19-11-2017, 20:57:22 »
все таже ошибка:



как впринципе если и в лисп(автозагрузки) вставить команду закрытия... :'(

п.с конечно можно поробывать ход конем, хоть мне и не нравится -не красиво  :( :
запускать паралельный процесс с эксепшн и таймером(первый самый вариант хоть исключение выкидвало) и через Invoke пробывать пока не закроет



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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #14 : 19-11-2017, 21:02:46 »
Ничего не понял. Еще же AutoCAD не загрузился.
Не нужно насиловать AutoCAD. Просто придумай другой алгоритм без закрытия чертежа. Например предупреди пользователя и всё.
А если речь идёт об AutoCAD 2014, то просто установи для него SP1 и забудь про отметку учебной версии.
Или воспользуйся моим кодом для снятия флажка учебной версии в AutoCAD 2014: http://adn-cis.org/forum/index.php?topic=1110.0
Тему читать всю от начала и до конца. Обратить внимание на EMRCLEAR.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 0
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #15 : 19-11-2017, 21:18:50 »
Например предупреди пользователя и всё.
А если речь идёт об AutoCAD 2014, то просто установи для него SP1 и забудь про отметку учебной версии.

Насчет сервес-пака он установлен и у меня то оно просто предупреждало пользователя, что "учебная версия" (а так автокад молчит). Но люди как пользовались, так и пользуются - а на наши чертежи потом ругаются, админ выложил "DWG TrueView" - чтобы люди пользовались и чистили (часть чистит, но все равно воз поныне там).

Или воспользуйся моим кодом для снятия флажка учебной версии в AutoCAD 2014: http://adn-cis.org/forum/index.php?topic=1110.0
Тему читать всю от начала и до конца. Обратить внимание на EMRCLEAR.
МХ, а вот это интересно - просто я думал что сбросить флаг нельзя так как он только для чтения - обязательно прочитаю (впринципе задумка и была чистка -скидывания учебки, просто флаг только для чтения и я подумал, что нельзя скинуть)

Отмечено как Решение prajdziswet 19-11-2017, 23:27:44

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #16 : 19-11-2017, 22:02:19 »
МХ, а вот это интересно - просто я думал что сбросить флаг нельзя так как он только для чтения - обязательно прочитаю (впринципе задумка и была чистка -скидывания учебки, просто флаг только для чтения и я подумал, что нельзя скинуть)
Он и есть "только для чтения", но так как Autodesk отказался от флага учебной версии, то я себе позволил небольшой "хак".
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #17 : 19-11-2017, 22:33:29 »
По теме закрытия у меня как-то была задача обновлять файл чертежа если пользователь открыл старый локальный  а на сервере лежит новая версия. Так вот из обработчика события открытия файла я так и не смог сделать его закрытие. Ограничился (в точности как писалось выше) предупреждением пользователю типа "Файл старый, вызови команду обновления". А вот уже из команды - пожалуйста, все вполне закрывается и открывается. Команда конечно сессионная. Вот рабочий код (Cns - это мой класс для работы с консолью Автокада):
Код - C# [Выбрать]
  1.   [CommandMethod("ReOpen", CommandFlags.NoBlockEditor | CommandFlags.Session | CommandFlags.Modal)]
  2.     public static void ReOpen()
  3.     {
  4.        try
  5.       {
  6.         Document doc = AcadApp.DocumentManager.MdiActiveDocument;
  7.         if (doc == null) return;
  8.  
  9.         if (!DocSaved)
  10.         {
  11.           if (!Cns.Query(
  12.             "Чертеж отредактирован и не сохранен!\n" +
  13.             "Перезагрузка вызовет потерю всех изменений.\n" +
  14.             "Закрыть файл без сохранения?"))
  15.             return;
  16.         }
  17.  
  18.         if (!doc.TryClose()) return;
  19.         string fileName = LoadFile(.......);
  20.         if (File.Exists(fileName))
  21.           AcadApp.DocumentManager.Open(fileName, false);
  22.         else
  23.           Cns.Err("Файл " + fileName + " не существует");
  24.         }
  25.       catch (System.Exception ex) { Cns.Err(ex); }
  26.     }
  27.        
  28.     public static bool DocSaved
  29.     {
  30.       get
  31.       {
  32.         object obj = AcadApp.GetSystemVariable("DBMOD"); // Check the value of DBMOD, if 0 then the drawing has no unsaved changes
  33.         return (System.Convert.ToInt16(obj) == 0);
  34.       }
  35.     }
  36.        
  37.     public static bool TryClose(this Document doc)
  38.     {
  39.       if (doc.LockMode(true) != DocumentLockMode.NotLocked)
  40.       {
  41.         Cns.Warning("Файл " + Path.GetFileNameWithoutExtension(doc.Name) + " заблокирован. Закрыть не получится.");
  42.         return false;
  43.       }
  44.       try
  45.       {
  46.         doc.CommitAll();
  47.         doc.CloseAndDiscard();
  48.       }
  49.       catch (Exception e)
  50.       {
  51.         Cns.Warning("Попытка закрыть чертеж " + Path.GetFileNameWithoutExtension(doc.Name) + " не удалась. Ошибка: " + e.Message);
  52.         return false;
  53.       }
  54.       return true;
  55.     }

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 0
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #18 : 19-11-2017, 23:06:49 »
то я себе позволил небольшой "хак".
буду разбираться...Спасибо!!!
Команда конечно сессионная. Вот рабочий код (Cns - это мой класс для работы с консолью Автокада)
И тебе avc, Большое Спасибо..Как раз у меня получается наверное не совсем сессионная (и смотрю закрывать как я),это хорошо видно на accore.dll - автокад даже не успевает загрузится, как она идет на обработку...Так же получается при моем (простом закрытии через ".CloseAndDiscard();),еще автокад грузит лисп-ы в чертеж и длл в автокад (но автокад уже загружен и поэтому исключение у меня вываливается, но чертеж не доконца еще загружен)=> как я пытаюсь его закрыть...

Большое СПАСИБО за подсказки ... :)

п.с А закрытие можно реализовать как писал выше(но мне это вариант не очень нравится = лучше прочитаю решение Александра по снятию флага= это лучше). А решение может быть таким (но это "костыль" извиняюсь за название, но моймете по ходу рассуждения):
- так как в моем случае автокад .CloseAndDiscard() - выдает исключение, можно его вызывать через определение время..
т.е вызываем паралельный поток (чтобы автокад продолжал выполнять свои действия) выполняющий через определенное время допустим 1 сек (или таймер) закрытие файла..и пробуем закрывать файл пока он не закроет, так как файл закрыть можно только из основного потока вызываем наш метод через Invoke...

но это не очень красивое решение, как писал выше "костыль"....

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #19 : 19-11-2017, 23:43:22 »
Сама идея закрывать чертеж по событию его открытия - уже звучит бредово. Понятно что документ будет заблокирован и куча процессов его читает в этот момент. Поэтому я не долго мучился и сдался. Хотя полно случаев когда это нужно. Можно и без таймеров попробовать - повесить обработчик простоя OnIdle и ждать пока разблокирован будет файл. Все в одном потоке. Может даже ивок не понадобится.
Эх, вот бы было событие BeforeOpen и получало бы оно имя файла до того как его Автокад начнет открывать - вот тогда была б красота....

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #20 : 19-11-2017, 23:55:29 »
Эх, вот бы было событие BeforeOpen и получало бы оно имя файла до того как его Автокад начнет открывать - вот тогда была б красота....
Это разве не оно?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #21 : 20-11-2017, 00:16:55 »
Это разве не оно?
Имя файла в нём не известно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 0
Re: Закрытие чертежа - "чертеж занят"?
« Ответ #22 : 20-11-2017, 08:12:20 »
Сама идея закрывать чертеж по событию его открытия - уже звучит бредово. Понятно что документ будет..
полностью согласен - но я привел, как вариант - хоть мне удобнее поступить (да и красивее будет), как предложил Александр...

Спасибо...(всегда что-то новое подчерпнешь...)