Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI

Автор Тема: Перевод приложения на AutoCAD 2015, или – исключение при редактировании CUI  (Прочитано 14041 раз)

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

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

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

  • ADN Club
  • Сообщений: 15
  • Карма: 0
Здравствуйте, коллеги!

По работе возникла необходимость адаптировать приложение под 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, но это довольно большой объем работы, по-быстрому не получилось.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Надеюсь, что в .NET части нет обращения к AutoCAD никоим образом - ни AutoCAD .NET API, ни ActiveX/COM, ни AutoCAD .NET API
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • Сообщений: 15
  • Карма: 0
Александр,
в .Net-части обращений к Autocad нет.

P.S. впервые встречаю столь серьезную защиту от роботов при публикации сообщений ;)

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Александр,
в .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.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • Сообщений: 15
  • Карма: 0
Александр, спасибо за ответ.
Может подскажете где почитать про FIBERLESS и как это отражается на программирование под AutoCAD2015?

'...сделать с нуля отдельный минимальный пример' - непростая задачка, буду думать.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Может подскажете где почитать про 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
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • Сообщений: 15
  • Карма: 0
Добрый день, Александр.

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

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

Как-то так ;)

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
В попытке сделать ‘отдельный минимальный пример’ стал исключать отдельные части программы, и нашел строчку, где Thread.CurrentThread.CurrentUICulture назначается русская культура.
Надеюсь ты восстанавливаешь исходное значение и теперь всё в порядке?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
P.S.: AutoCAD 2015 использует .NET 4.5. В инсталляции AutoCAD 2015 есть и .NET 3.5 SP1, и .NET 4.0, и .NET 4.5
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • Сообщений: 15
  • Карма: 0
Цитировать
Надеюсь ты восстанавливаешь исходное значение и теперь всё в порядке?

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

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

Сейчас программа на тестировании.

Отмечено как Решение Александр Ривилис 24-09-2020, 15:48:23

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Было в голове такое решение, но у нас миллион вызовов, это два миллиона переключений... где-нибудь да забудешь.
Удобнее всего сделать вспомогательный класс с интерфейсом 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. Мне кажется, что это будет правильнее.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Во время загрузки, диалог пытается загрузить ресурсы из русской культуры, но ACAD английский, русских ресурсов не имеет, и возникает исключение.

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