Простая альтернатива использованию COM-объекта Preferences в AutoCAD
Недавно один из разработчиков столкнулся с проблемой при написании кода на LISP, когда он пытался добавить несколько путей к свойству PrinterStyleSheetPath. Код выглядел примерно так:- (defun c:xx()
- (vl-load-com)
- (setq
- acad (vlax-get-acad-object)
- prefs (vla-get-preferences acad)
- files (vla-get-files prefs)
- )
- (vla-put-PrinterStyleSheetPath files "c:\\fenny;c:\\temp")
- )
Проблема в том, что как и для других переменных окружения, при установке значения PrinterStyleSheetPath не обрабатывается точка с запятой и соответственно получается недопустимый путь.
Проблема решается при помощи пары функций getenv и/или setenv.
Если вы не слишком знакомы с этими функциями, то объясню, что они работают в двухэтапном режиме. Первый этап – проверка раздела реестра FixedProfile на наличие там соответствующего параметр и (если он там не найден), то второй этап – поиск в системном окружении Windows.
Вот код, который устанавливает PrinterStyleSheetPath для нескольких путей в LISP…
Вот код, который устанавливает PrinterStyleSheetPath для нескольких путей в ObjectARX…
А вот для .NET похоже что нет естественного метода для вызова acedSetEnv()… Это потому что класс ObjectARX, для которого .NET есть лишь обертка, AcDbHostApplicationServices определяет только GetEnvironmentVariable(), а не SetEnvironmentVariable()) так что придется сделать PInvoke для acedSetEnv… Это несложно:
- [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl,
- CharSet = CharSet.Auto, EntryPoint = "acedGetEnv")]
- extern static private Int32 acedGetEnv(string var,
- [Out] System.Text.StringBuilder val);
- [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl,
- CharSet = CharSet.Auto, EntryPoint = "acedSetEnv")]
- extern static private Int32 acedSetEnv(string var, string val);
- // Проверка acedGetEnv и acedSetEnv Fenton Webb, DevTech, 05/06/2012
- [CommandMethod("testenv")]
- static public void testenv()
- {
- System.Text.StringBuilder buf = new System.Text.StringBuilder("", 1024);
- acedGetEnv("PATH", buf);
- buf.Append(";"); buf.Append(@"c:\temp");
- acedSetEnv("PATH", buf.ToString());
- }
Примечание переводчика: Начиная с 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://adn-cis.org/forum/index.php?topic=385
Опубликовано 06.12.2013