На Revit 2015 перестал работать add-in

Автор Тема: На Revit 2015 перестал работать add-in  (Прочитано 31210 раз)

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

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

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Re: На Revit 2015 перестал работать add-in
« Ответ #15 : 07-08-2014, 09:59:15 »
Да, я понял. Договорились. Спасибо
Сколько голов, столько умов. Но голов больше

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: На Revit 2015 перестал работать add-in
« Ответ #16 : 15-08-2014, 08:56:21 »
Дамир,  добрый день.
Скажите, у вас получилось отладить код и узнать в чем была причина падения Revit'а?
« Последнее редактирование: 15-08-2014, 09:07:03 от Виктор Чекалин »

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

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Re: На Revit 2015 перестал работать add-in
« Ответ #17 : 17-08-2014, 00:09:32 »
Воспользовался Ваше рекомендацией по уроку отладки кода.  Прописал запуск Revit'a в проекте. Как я понял, необходимо в файле манифеста прописать путь к новой dll, поскольку отладка собирает новое решение.
Цитировать
Поскольку теперь мы начнем отладку кода плагина, Visual C# Express создает отладочную версию DLL-файла плагина .NET. Для того чтобы Revit прочитал отладочную версию DLL-файла вместо финальной версии, созданной на первом уроке, необходимо изменить путь к DLL-файлу в манифесте следующим образом (изменения отмечены полужирным шрифтом):


При запуске отладки открывается окно приветствия Revit и тут же закрывается... На этом я и остановился. Не знаю, что делать дальше
Сколько голов, столько умов. Но голов больше

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

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Re: На Revit 2015 перестал работать add-in
« Ответ #18 : 17-08-2014, 00:30:06 »

Повторил все действия теперь другой результат.


Мои действия:
1. В файле WallsArea2014.csproj проекта добавил строку:
<StartAction>Program</StartAction>
   <StartProgram>C:\Program Files\Autodesk\Revit 2015\Revit.exe</StartProgram>
  </PropertyGroup>
2. В файле манифеста WallsArea2014.addin заменил строку на:

<AddIn Type="Command">
    <Assembly>C:\Users\damir\Downloads\11\WallsArea2014\bin\x64\Debug\WallsArea2014.dll</Assembly>
    <ClientId>86c9fb46-b50f-4612-9152-e24fef5ecdab</ClientId>
По этому пути собирается новая dll.


В итоге при запуске отладки VS собирает новое решение не выдает ошибок, а пишет следующее:


Повторил все действия заново.
VS написал следующее:
Цитировать
Программа "[11848] Revit.exe" завершилась с кодом -529697949 (0xe06d7363) 'Microsoft C++ Exception'.


Окно запуска Revit'a просто мигает и все. Сам Revit не грузится. Зато при запуске Revit'a вручную и выполнении команды также появляется нужное окошко лога, но без фатальной ошибки. Однако, окошко уведомлений по прежнему пустое и площадь стен не считается.
Сколько голов, столько умов. Но голов больше

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

  • Administrator
  • *****
  • Сообщений: 13918
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: На Revit 2015 перестал работать add-in
« Ответ #19 : 17-08-2014, 02:22:26 »
1) Какая версия VS используется?
2) Для какой платформы .NET (4 или 4.5) выполняется компиляция?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Re: На Revit 2015 перестал работать add-in
« Ответ #20 : 17-08-2014, 11:54:02 »
Прошу прощения, фатал все тки появляется. Но пока вопрос в другом. Хотелось бы осуществить отладку корректно.


1) Какая версия VS используется?
2) Для какой платформы .NET (4 или 4.5) выполняется компиляция?
Visual Studio Express 2013 for Desktop
Framework 4.5


По этой ссылке (gif, 26 mb) мои действия в Revit

« Последнее редактирование: 17-08-2014, 13:49:39 от Дамир »
Сколько голов, столько умов. Но голов больше

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: На Revit 2015 перестал работать add-in
« Ответ #21 : 18-08-2014, 09:55:49 »
Дамир, добрый день,
Попробуйте создать новый пустой проект, и на нем уже пробовать запустить надстройку в режиме отладки. Я вложил к посту такой проект. Подправьте в нем пути к файлаи RevitAPI.dll и RevitAPIUI.dll и пути в файле манифеста.
Предварительно удалите файл манифеста вашей надстройки из папки C:\Users\UserName\AppData\Roaming\Autodesk\Revit\AddIns\2015 чтобы исключить ее влияние.  После этого уже попробуйте запустить тот почти пустой проект в режиме отладки. Сообщите результат.

Также не могли бы вы выложить код команды, т.е. код класса, реализующего интерфейс IExternalCommand? Есть у меня одно предположение, почему Revit может падать.

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

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Re: На Revit 2015 перестал работать add-in
« Ответ #22 : 18-08-2014, 10:05:52 »

Виктор Чекалин, хорошо. Попробуй сделать как Вы сказали.
Здесь ссылка на весь проект.
Сколько голов, столько умов. Но голов больше

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: На Revit 2015 перестал работать add-in
« Ответ #23 : 18-08-2014, 10:33:09 »
Дамир, я посмотрел код. Мои подозрения подтвердились.
Код - C# [Выбрать]
  1.             ProgressDlg dlg = new ProgressDlg();
  2.             dlg.ActiveDocument = commandData.Application.ActiveUIDocument.Document;
  3.             dlg.Show();
  4.             dlg.RunWorker();
  5.  
  6.             return Result.Succeeded;

Вы вызываете методы RevitAPI из другого потока. RevitAPI не поддерживает многопоточность.
Если говорить вкратце, то есть только три возможных места, где можно безопасно вызывать методы RevitAPI:
  • Метод Execute, класса, реализующего интерфейс IExternalCommand
  • Метод OnStartup, класса, реализующего интерфейс IExternalApplication
  • Обработка события Idling

В вашем коде вы отображаете немодальную форму (метод Show). После вызова метода Show код продолжает выполняться дальше, и в итоге вы выходите из контекста метода Execute и в другом потоке вызываете методы RevitAPI.

Сразу отвечу на вопрос почему это работало в Revit 2014. Строго говоря, Autodesk и ранее говорил о том что вызов методов из небезопасных контекстов не гарантируется и что делать так ни в коем случе нельзя. Иными словами имеющийся код мог не работать при определенных обстоятельствах и в Revit 2014 и в худшем случае вообще испортить весь файл модели с невозможностью последующего открытия.

Решение только одно - избавляйтесь от многопоточности. В вашем случае от BackgroundWorker.

Как вариант, можно попробовать изменить ваш код на вот такой:
Код - C# [Выбрать]
  1.             ProgressDlg dlg = new ProgressDlg();
  2.             dlg.ActiveDocument = commandData.Application.ActiveUIDocument.Document;            
  3.             dlg.RunWorker();
  4.             dlg.ShowDialog();
  5.  
  6.             return Result.Succeeded;

Т.е. использовать все же модальную форму, но результат не гарантируется.

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

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Re: На Revit 2015 перестал работать add-in
« Ответ #24 : 18-08-2014, 10:38:47 »
Виктор Чекалин, благодарю. Если честно я пока не знаток C# (для того и начал изучение этой темы), поэтому Ваше предположение понял в общей форме. Постараюсь воспользоваться Вашей рекомендацией по мере своих сил. По мере вопросов отпишу.
Как я понял, пока я заменю код на Ваш вариант.
Сколько голов, столько умов. Но голов больше

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

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Re: На Revit 2015 перестал работать add-in
« Ответ #25 : 18-08-2014, 20:52:17 »
Заменил код как Вы и указали. Файл манифеста корректен, dll лежит по верному пути. Ошибка повторилась
Сколько голов, столько умов. Но голов больше

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: На Revit 2015 перестал работать add-in
« Ответ #26 : 18-08-2014, 21:16:19 »
Жаль. :( Значит все же придется избавиться от многопоточности. Говоря простым языком, показать процесс построения отчета не получится.
Поместите код, который у вас выполнялся с помощью BackgroundWorker (BackgroundWorker.DoWork) в обработку события Load или Shown для формы.


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

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Re: На Revit 2015 перестал работать add-in
« Ответ #27 : 18-08-2014, 23:55:10 »
Говоря простым языком, показать процесс построения отчета не получится
я так понял не получится осуществить отладку?

Поместите код, который у вас выполнялся с помощью BackgroundWorker (BackgroundWorker.DoWork) в обработку события Load или Shown для формы.
фрагмент я нашел, но, если честно, не знаю как именно поместить его под обработку этих событий. Наверно в ProgressDlg.cs эти события руками создать?
Прошу прощения за простые вопросы, думаю мне не хватает знаний C#.
Сколько голов, столько умов. Но голов больше

Оффлайн Виктор Чекалин

  • Administrator
  • *****
  • Сообщений: 694
  • Карма: 111
  • Skype: chekalin-v
Re: На Revit 2015 перестал работать add-in
« Ответ #28 : 19-08-2014, 09:03:07 »
Нет, отладка здесь не причем. Кстати отладка многопоточных приложений тоже требует определенного навыка. Но, так как мы разобрались в причинах, то пока отладка вам не нужна.
Попробую объяснить простым языком.
Многопоточность применяется для того, чтобы выполнять некие длительные действия в приложении, при этом само приложение остается доступным и в нем можно продолжать работать. В вашем случае, после запуска формы вы начинаете строить отчет (то самое длительное действие) и отображаете так называемый ProgressBar, отображающий процесс построения отчета.
В случае избавления от многопоточности, код по построению отчета будет выполняться синхронно, т.е. форма вашего приложения не будет доступна до тех пор, пока выполняется построение отчета. Для пользователя это будет выглядеть как будто программа "зависла". После того как отчет построится, пользователь все же увидет форму с данными.

Цитировать
фрагмент я нашел, но, если честно, не знаю как именно поместить его под обработку этих событий. Наверно в ProgressDlg.cs эти события руками создать?
Прошу прощения за простые вопросы, думаю мне не хватает знаний C#
Открываете вашу форму в Visual Studio. В редакторе дважды щелкаете на заголовок формы (там где иконка, заголовок ProgressDlg и кнопки сворачивания, закрытия и минимизации). После этого у вас создается подписка на событие Load и генерируется код:
Код - C# [Выбрать]
  1.         private void ProgressDlg_Load(object sender, EventArgs e)
  2.         {
  3.  
  4.         }

В методе Execute класса CalcAreaAction удаляете параметр worker и удаляете в этом методе все что связано с worker.

Метод обработки события Load должен получиться примерно такой:
Код - C# [Выбрать]
  1.         private void ProgressDlg_Load(object sender, EventArgs e)
  2.         {
  3.             CalcAreaAction act = new CalcAreaAction();
  4.             act.Execute(ActiveDocument);
  5.             m_log.Text = act.Log;
  6.             m_close.Enabled = true;
  7.             m_logToFile.Enabled = true;
  8.         }

Код команды после этого должен вылдяеть так (не должно быть вызова метода RunWorker):
Код - C# [Выбрать]
  1.         public Result Execute(ExternalCommandData commandData,
  2.             ref string message, ElementSet elements)
  3.         {
  4.             ProgressDlg dlg = new ProgressDlg();
  5.             dlg.ActiveDocument = commandData.Application.ActiveUIDocument.Document;
  6.             dlg.ShowDialog();
  7.             //dlg.RunWorker();
  8.  
  9.             return Result.Succeeded;
  10.         }
           

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

  • ADN Club
  • **
  • Сообщений: 94
  • Карма: 1
Re: На Revit 2015 перестал работать add-in
« Ответ #29 : 22-08-2014, 16:44:38 »
Благодарю, Вас за помощь. 
Постараюсь вернуться к Вашей рекомендации. Небольшая заминка со временем. Отпишу по результатам. Еще раз спасибо
Сколько голов, столько умов. Но голов больше