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

ADN Club => ObjectARX => Тема начата: Дмитрий Гилин от 27-08-2014, 14:32:39

Название: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI
Отправлено: Дмитрий Гилин от 27-08-2014, 14:32:39
Здравствуйте, коллеги!

По работе возникла необходимость адаптировать приложение под AutoCAD 2015.
Если коротко – после выполнения всех рекомендаций, приложение успешно загружается и работает. Но, при попытке вызвать редактор CUI, происходит исключение:
System.ArgumentNullException: Значение не может быть неопределенным.
Имя параметра: stream
   в System.Resources.ResourceSet..ctor(Stream stream)
   в Autodesk.AutoCAD.Customization.MyResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
   в System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
   в Autodesk.AutoCAD.Customization.CustomizationSection.FillPropertyBag(IPropertyBag bag)
   в Autodesk.AutoCAD.Customization.PropertyControl.SetCustomizationSectionProperties(CustomizationSection cs, CUITreeNode node)
   в Autodesk.AutoCAD.Customization.MainForm.handleTreeNodeItemSelected(Boolean recreateToolbarPreview)
   в Autodesk.AutoCAD.Customization.MainForm.tabControl_SelectedIndexChanged(Object sender, EventArgs e)/
   в System.Windows.Forms.TabControl.OnSelectedIndexChanged(EventArgs e)
   в System.Windows.Forms.TabControl.WmSelChange()
   в System.Windows.Forms.TabControl.set_SelectedIndex(Int32 value)
   в Autodesk.AutoCAD.Customization.MainForm.OnLoad(EventArgs e)
   в System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   в System.Windows.Forms.Control.CreateControl()
   в System.Windows.Forms.Control.WmShowWindow(Message& m)
   в System.Windows.Forms.Control.WndProc(Message& m)
   в System.Windows.Forms.Form.WndProc(Message& m)
   в System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


Теперь подробнее.
Приложение существует уже долгие годы, и мне не в первый раз приходится переводить его на очередную версию AutoCAd’а.
Приложение состоит из нескольких частей.
ARX-часть написана на Unmanaged C++ & ObjectARX, через COM-интерфейс она связана с .Net-частью, реализующей пользовательский интерфейс на WinForms. Исторически, .Net-часть реализована на MS Framework 3.5.

Судя по исключению, ошибка происходит при чтении ресурсов при загрузке формы редактора. Возможно проблема с тем, что не совпадают культуры AutoCAD и Windows. У меня установлен AutoCAD 2015 SP1, English. Windows 7 Корпоративная, Русская.

Я попытался найти информацию об ошибке в интернете.
Вот здесь, автор neyton_ (примерно в середине страницы) описывает очень похожую ошибку - Bug after CUI command - http://forums.autodesk.com/t5/autocad-civil-3d-general/c3d-2015-list-of-current-bugs-issues/td-p/5012764/page/7 , но информации об исправлении нет.

В конфигурационном файле acad.exe.config пробовал в различных комбинациях такие атрибуты как <supportedRuntime>, <generatePublisherEvidence>, <loadFromRemoteSources>, <legacyUnhandledExceptionPolicy>, не помогает.

Пробовал отключать функциональность приложения, реагирующую на события AutoCAD, да и просто большие куски кода, которые предположительно могли повлиять – не помогло.

Рассматривал вариант увеличения версии Framework нашей .Net-части с версии 3.5 до 4.0, но это довольно большой объем работы, по-быстрому не получилось.
Название: Re: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI
Отправлено: Александр Ривилис от 27-08-2014, 16:31:03
Надеюсь, что в .NET части нет обращения к AutoCAD никоим образом - ни AutoCAD .NET API, ни ActiveX/COM, ни AutoCAD .NET API
Название: Re: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI
Отправлено: Дмитрий Гилин от 27-08-2014, 16:35:44
Александр,
в .Net-части обращений к Autocad нет.

P.S. впервые встречаю столь серьезную защиту от роботов при публикации сообщений ;)
Название: Re: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI
Отправлено: Александр Ривилис от 27-08-2014, 17:06:22
Александр,
в .Net-части обращений к Autocad нет.

P.S. впервые встречаю столь серьезную защиту от роботов при публикации сообщений ;)
1. Забыл поприветствовать на форуме - исправляюсь. :)
2. Про ботов-роботов - это правда. У нас нет ни времени, ни желания с ними бороться, а прецеденты уже были. Но это только первые два (или три) сообщения - потом вопросов не будет.
3. Боюсь что здесь проблема не из-за версии AutoCAD. Если бы причина была в этом, то и в 2014-ом, который использует .NET 4.0 она бы проявлялась. Скорее причина в том, что начиная с AutoCAD 2015 используется FIBERLESS-среда.
4. Боюсь что помочь так не получится - с такой технологией я не сталкивался. Да и вряд ли кто-то из ребят такое использовал.
Предположений может быть масса - вплоть до того, что какие-то ресурсы не переключаются/не закрываются. Или действительно переключается язык, а AutoCAD в 2015 обратно не переключает. Так что возможно это тебе нужно делать самому.
5. Что еще я могу порекомендовать? Нужно сделать с нуля отдельный минимальный пример native arx и .NET COM и проверить с ними. Если будет та же ошибка с CUI - отправим в ADN DevHelp.
Название: Re: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI
Отправлено: Дмитрий Гилин от 27-08-2014, 17:32:02
Александр, спасибо за ответ.
Может подскажете где почитать про FIBERLESS и как это отражается на программирование под AutoCAD2015?

'...сделать с нуля отдельный минимальный пример' - непростая задачка, буду думать.
Название: Re: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI
Отправлено: Александр Ривилис от 27-08-2014, 17:43:07
Может подскажете где почитать про FIBERLESS и как это отражается на программирование под AutoCAD2015?
Немного здесь: http://adn-cis.org/autocad2015-for-develop.html в контексте AutoCAD.
А вообще в MSDN:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682661%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686919%28v=vs.85%29.aspx
ну и поиском "FIBER Windows" в интернете.
Сказывается например на то, что вместо acedCommand приходится использовать acedCommandS (если известны все аргументы заранее) или acedCommandC (если приходится взаимодействовать с пользователем): http://adn-cis.org/autocad-2015-vyizov-komand.html
Название: Re: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI
Отправлено: Дмитрий Гилин от 04-09-2014, 16:05:03
Добрый день, Александр.

Ну, я вроде бы разобрался с проблемой.
FIBERLESS оказался не причем.
В попытке сделать ‘отдельный минимальный пример’ стал исключать отдельные части программы, и нашел строчку, где Thread.CurrentThread.CurrentUICulture назначается русская культура.

Напомню, эта часть приложения написана на FW3.5, видимо диалог редактирования CUI также работает под FW3.5, несмотря на то, что ACAD2015 на FW4.0. Во время загрузки, диалог пытается загрузить ресурсы из русской культуры, но ACAD английский, русских ресурсов не имеет, и возникает исключение.

Как-то так ;)
Название: Re: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI
Отправлено: Александр Ривилис от 04-09-2014, 17:49:28
В попытке сделать ‘отдельный минимальный пример’ стал исключать отдельные части программы, и нашел строчку, где Thread.CurrentThread.CurrentUICulture назначается русская культура.
Надеюсь ты восстанавливаешь исходное значение и теперь всё в порядке?
Название: Re: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI
Отправлено: Александр Ривилис от 04-09-2014, 17:53:40
P.S.: AutoCAD 2015 использует .NET 4.5. В инсталляции AutoCAD 2015 есть и .NET 3.5 SP1, и .NET 4.0, и .NET 4.5
Название: Re: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI
Отправлено: Дмитрий Гилин от 05-09-2014, 10:23:19
Цитировать
Надеюсь ты восстанавливаешь исходное значение и теперь всё в порядке?

Было в голове такое решение, но у нас миллион вызовов, это два миллиона переключений... где-нибудь да забудешь.

Пошел по другому пути. У нас ресурсы для двух культур - для нейтральной английские, и русские. Но английские давно перестали поддерживать, т.к. нет ни одного иностранного заказчика, и не предвидится. Поэтому я решил оставить только одну культуру, русскую.
Для этого пришлось написать утилитку, которая русские строки перекинула в культуру по умолчанию.

Сейчас программа на тестировании.
Название: Re: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI
Отправлено: Александр Ривилис от 05-09-2014, 19:32:29
Было в голове такое решение, но у нас миллион вызовов, это два миллиона переключений... где-нибудь да забудешь.
Удобнее всего сделать вспомогательный класс с интерфейсом IDisposable. В этом случае не забудешь. Когда-то я писал что-то такое для временного переключения десятичного разделителя с запятой на точку:
Код - C# [Выбрать]
  1. class NumberFormatDot: IDisposable
  2.   {
  3.  
  4.     private CultureInfo cInfoThread = Thread.CurrentThread.CurrentCulture;
  5.     public NumberFormatDot()
  6.     {
  7.       cInfoThread = Thread.CurrentThread.CurrentCulture;
  8.       CultureInfo ccInfo = cInfoThread.Clone() as CultureInfo;
  9.       ccInfo.NumberFormat.NumberDecimalSeparator = ".";
  10.       Thread.CurrentThread.CurrentCulture = ccInfo;
  11.     }
  12.     public void Dispose()
  13.     {
  14.       Thread.CurrentThread.CurrentCulture = cInfoThread;
  15.     }
  16.   };  
  17.  

И пример использования:

Код - C# [Выбрать]
  1.     [CommandMethod("PNT")]
  2. static public void Pnt()
  3. {
  4.       Editor ed = Autodesk.AutoCAD.ApplicationServices.Application
  5.                          .DocumentManager.MdiActiveDocument.Editor;
  6.       ed.WriteMessage("\nPoint: {0}",new Point3d(1.5,2.6,3.7));
  7.       using (new NumberFormatDot()) {
  8.         ed.WriteMessage("\nPoint: {0}",new Point3d(1.5,2.6,3.7));
  9.       }
  10.       ed.WriteMessage("\nPoint: {0}",new Point3d(1.5,2.6,3.7));
  11. }

Вот по образцу можно и для CurrentUICulture. Мне кажется, что это будет правильнее.
Название: Re: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI
Отправлено: Андрей Бушман от 24-09-2014, 22:41:35
Во время загрузки, диалог пытается загрузить ресурсы из русской культуры, но ACAD английский, русских ресурсов не имеет, и возникает исключение.

Как-то так
Если .NET не находит локализованных ресурсов, то он ищет Default локализацию. Поэтому в своих проектах я всегда делаю сначала default и уже затем копирую его и локализовываю.