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

06/12/2013

Простая альтернатива использованию COM-объекта Preferences в AutoCAD

Недавно один из разработчиков столкнулся с проблемой при написании кода на LISP, когда он пытался добавить несколько путей к свойству PrinterStyleSheetPath. Код выглядел примерно так:

Код - Auto/Visual LISP: [Выделить]
  1. (defun c:xx()
  2.   (vl-load-com)
  3.   (setq
  4.     acad (vlax-get-acad-object)
  5.     prefs (vla-get-preferences acad)
  6.     files (vla-get-files prefs)
  7.   )
  8.   (vla-put-PrinterStyleSheetPath files "c:\\fenny;c:\\temp")
  9. )

Проблема в том, что как и для других переменных окружения, при установке значения PrinterStyleSheetPath не обрабатывается точка с запятой и соответственно получается недопустимый путь.

Проблема решается при помощи пары функций getenv и/или setenv.

Если вы не слишком знакомы с этими функциями, то объясню, что они  работают в двухэтапном режиме. Первый этап – проверка раздела реестра FixedProfile на наличие там соответствующего параметр и (если он там не найден), то второй этап  – поиск в системном окружении Windows.

Вот код, который устанавливает PrinterStyleSheetPath для нескольких путей в LISP…

(setenv "PrinterStyleSheetDir" "c:\\fenton;c:\\temp")

Вот код, который устанавливает PrinterStyleSheetPath для нескольких путей в ObjectARX…

acedSetEnv(_T("PrinterStyleSheetDir"), _T("c:\\fenton;c:\\temp"));

А вот для .NET похоже что нет естественного метода для вызова acedSetEnv()… Это потому что класс ObjectARX, для которого .NET есть лишь обертка, AcDbHostApplicationServices определяет только GetEnvironmentVariable(), а не SetEnvironmentVariable()) так что придется сделать PInvoke для acedSetEnv… Это несложно:

Код - C#: [Выделить]
  1. [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl,
  2.       CharSet = CharSet.Auto, EntryPoint = "acedGetEnv")]
  3. extern static private Int32 acedGetEnv(string var,
  4.         [Out] System.Text.StringBuilder val);
  5. [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl,
  6.       CharSet = CharSet.Auto, EntryPoint = "acedSetEnv")]
  7. extern static private Int32 acedSetEnv(string var, string val);
  8. // Проверка acedGetEnv и acedSetEnv Fenton Webb, DevTech, 05/06/2012
  9. [CommandMethod("testenv")]
  10. static public void testenv()
  11. {
  12.   System.Text.StringBuilder buf = new System.Text.StringBuilder("", 1024);
  13.   acedGetEnv("PATH", buf);
  14.   buf.Append(";"); buf.Append(@"c:\temp");
  15.   acedSetEnv("PATH", buf.ToString());
  16. }


Примечание переводчика: Начиная с AutoCAD 2013 функции acedSetEnv/acedGetEnv экспортируются не из acad.exe, а из accore.dll

Наконец , я лично думаю, что еще одно очень большое преимущество использования GetEnv / acedGetEnv () и SetEnv / acedSetEnv () вместо COM .NET является то, что уменьшится необходимость использования библиотеки DLL COM Interop в вашем проекте, а именно - Autodesk.AutoCAD.Interop.dll  и / или Autodesk.AutoCAD.Interop.Common.dll. Чтобы объяснить почему я считаю это крайне важным, напомню, когда что вы добавляете эти DLL как ссылки к проекту вы больше не можете полагаться на «Any CPU» в настройках вашего проекта, который создаёт универсальную сборку, работающую и в 32-битном и 64-битномt AutoCAD. Таким образом, вам очень вероятно придётся создавать две отдельных (32-х и 64-разрядные) версии вашего приложения. На самом деле все зависит от того, какие части библиотеки COM Interop вы используете. Мой совет, если вы используете эти библиотеки COM Interop, и вы собираете их как «Any CPU», то убедитесь, что ваше приложение работает и с 32бит и 64бит ... Если это не так, то вы уже знаете, что должны создать отдельные 32-х и 64-разрядные версии. Если это работает, то это здорово! На самом деле, хороший первый тест просто установить ваш тип процессора в Win32 и перекомпилировать, сделать то же самое для 64 - если вы получаете какие-нибудь ошибки то безусловно, есть проблемы ...

Источник: http://adndevblog.typepad.com/autocad/2012/06/a-simple-alternative-to-accessing-the-com-preferences-object-in-autocad.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=385

Опубликовано 06.12.2013