Создать чертеж в текущем проекте AutoCAD Electrical

Автор Тема: Создать чертеж в текущем проекте AutoCAD Electrical  (Прочитано 12172 раз)

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

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

  • ADN OPEN
  • Сообщений: 27
  • Карма: 2
1. Сомневаюсь, что acedEvaluateLisp работает в контексте приложения
Тогда б в двенадцатой строке должен был тоже некорректно отрабатывать вызов.
2. В lisp-выражении есть Discr1, Discr2, Discr3. Это что-такое? Ты не передаёшь это значение в код.
Это описание для создаваемого документа. Можно заменить на nil впринципе.
3. После NewDB.SaveAs(FullFileName, DwgVersion.Newest); должно быть NewDB.Dispose()
Сборщик мусора все равно вызовет Dispose при выходе из функции. Но ладно.
4. Если у команды есть флаг CommandFlags.Session, то не нужен вызов ExecuteInApplicationContext
5. Не нужно засовывать код в спойлер, если в нём меньше 300 строк.
Понял.
Попробуй для начала вместо первого nil в AcadEvalLisp указать полный путь к добавляемому файлу
Пробовал. Именно экранирующие слеши, передающиеся в строке в автокад, и не распарсиваются.
Бензопила пилит тело, а виолончель душу.

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

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

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Сборщик мусора все равно вызовет Dispose при выходе из функции.
Во-первых ты путаешь, С# и C++. В C++ действительно при выходе из области видимости для автоматической переменной вызывается деструктор. В C# сборщик мусора может вызвать Dispose() в любой момент времени. Может вообще не вызвать до завершения работы AutoCAD.
Тогда б в двенадцатой строке должен был тоже некорректно отрабатывать вызов.
Не совсем так. Кое-что работает и в контексте приложения, но далеко не всё. Кстати при работе в контексте приложения если меняется Database, то следует её блокировать. Не пишет ли что-то (c:ace_add_dwg_to_project) в сам чертеж я сказать не могу. Так что лучше его на всякий случай заблокировать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 27
  • Карма: 2
Александр Ривилис, собака не в этом порылась в любом случае.
После выполнения моей команды автокад вообще перестает принимать свои родные команды.
То есть до запуска моей команды в командную строку автокада пишешь (c:ace_add_dwg_to_project nil (list nil nil (list Discr1 Discr2 Discr3) nil nil)) и он добавляет текущий чертеж в проект. После запуска моей команды пишешь в командную строку все тоже самое, но автокад не реагирует.
Я нашел вот эту тему, где решается моя проблема: https://forums.autodesk.com/t5/autocad-electrical-forum/add-drawings-to-active-project/td-p/4672543
Если в трех словах, то надо обновить проект (командой (c:ace_wdp_reread)).
С учетом всех замечаний рабочий код вот такой:
Код - C# [Выбрать]
  1.     public class test : IExtensionApplication
  2.     {
  3.         [System.Security.SuppressUnmanagedCodeSecurity]
  4.         [System.Runtime.InteropServices.DllImport("accore.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode, CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl, EntryPoint = "?acedEvaluateLisp@@YAHPEB_WAEAPEAUresbuf@@@Z")]
  5.         extern public static int acedEvaluateLisp(string lispLine, out IntPtr result);
  6.      
  7.         [CommandMethod("qwe", CommandFlags.Session)]
  8.         public void Qwe()
  9.         {
  10.             Document CurrDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  11.      
  12.             ResultBuffer rb = DrawDraw.AcadEvalLisp("(ace_getactiveproject)");
  13.             TypedValue tv = rb.AsArray().FirstOrDefault();
  14.             String CurrFileName = tv.Value.ToString();
  15.      
  16.             String TemplateFileName = @"C:\Template\А3 С4 л2.dwt";
  17.             String FileName = "NewFileName.dwg";
  18.             String FullFileName = Path.Combine(Path.GetDirectoryName(CurrFileName), FileName);
  19.      
  20.                
  21.      
  22.             Database NewDB = new Database(false, true);
  23.             NewDB.ReadDwgFile(TemplateFileName, FileOpenMode.OpenForReadAndWriteNoShare, true, "");
  24.             NewDB.CloseInput(true);
  25.                
  26.                        
  27.             if (File.Exists(FullFileName)) // Если есть файл с таким именем, то удалить
  28.             {
  29.                 var AllOpenDocs = Application.DocumentManager.Cast<Document>(); // Если открыт, то закрыть
  30.                 foreach (Document d in AllOpenDocs)
  31.                     if (d.Name.ToLower().Equals(FullFileName.ToLower()))
  32.                         d.CloseAndDiscard(); // Должен быть установлен флаг CommandFlags.Session
  33.      
  34.                 File.Delete(FullFileName);
  35.             }
  36.             NewDB.SaveAs(FullFileName, DwgVersion.Newest);
  37.             NewDB.Dispose();
  38.  
  39.             Document NewDoc = Application.DocumentManager.Open(FullFileName, false);
  40.             Application.DocumentManager.MdiActiveDocument = NewDoc;
  41.             using (NewDoc.LockDocument())
  42.             {
  43.                 rb = DrawDraw.AcadEvalLisp("(c:ace_wdp_reread)");
  44.                 rb = DrawDraw.AcadEvalLisp("(c:ace_add_dwg_to_project nil (list nil nil (list nil nil nil) nil nil))");
  45.             }
  46.         }
  47.     }

Остается только прикрутить это все на формочку.
Бензопила пилит тело, а виолончель душу.