Архив рубрики: AutoCAD

Динамический вызов функций неуправляемых DLL

В .NET-атрибутах можно указывать только константные выражения. Т.о. атрибуту DllImport нужно указывать имя библиотеки статически, дабы это имя было известно на этапе компиляции. Порой это порождает уродливые конструкции, разрастающиеся как снежный ком, по мере появления новых версий AutoCAD. Наглядный тому пример можно увидеть здесь в коде Александра Ривилиса: по мере появления AutoCAD 2018, 2019 и т.д. - этот код придётся каждый раз дописывать.


Как правило, имя нужной DLL достаточно просто выяснить во время выполнения кода. Например, в обозначенном выше коде Александра Ривилиса нужная функция хранится в файлах acdb17.dll, acdb18.dll, ac1st19.dll, ac1st20.dll, ac1st21.dll. Т.е. мы видим, что каждая библиотека в качестве суффикса использует значение Major версии приложения. Кроме того, мы видим, что начиная с версии 19 (AutoCAD 2013) функция была перенесена в др. библиотеку (т.е. изменился префикс в её имени). Зная обозначенные выше правила, можно динамически вычислить имя DLL файла, в котором находится интересующая нас функция.

Далее показываю небольшой пример того, как можно динамически вызывать функцию acedSetEnv в разных версиях AutoCAD, не создавая для неё статических обёрток. На всякий случай напоминаю, что до версии AutoCAD 2013 эта функция находилась в файле acad.exe, а начиная с AutoCAD 2013 была перенесена в accore.dll.

Код проверялся в AutoCAD 2009 и 2016.

-------------------------------------------------------------
/* Utils.cs */
using System;
using System.Text;
using System.Runtime.InteropServices;
using cad = Autodesk.AutoCAD.ApplicationServices.Application;

namespace Bushman.AutoCAD.Sandbox {

    [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet
        = CharSet.Auto)]
    public delegate int acedSetEnvDelegate(string envName,
        StringBuilder NewValue);

    public static class Utils {

        [DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibrary(string
            dllToLoad);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr
            hModule, string procedureName);


        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);

        const int AutoCAD_2013_Major = 19;

        public static string GetDllName() {

            if (cad.Version.Major < AutoCAD_2013_Major)
                return "acad.exe";
            else
                return "accore.dll";
        }

        public static acedSetEnvDelegate acedSetEnv;

        static Utils() {
            acedSetEnv = GetAcedSetEnv();
        }

        static acedSetEnvDelegate GetAcedSetEnv() {

            string dllName = Utils.GetDllName();
            IntPtr pDll = Utils.LoadLibrary(dllName);

            if (pDll == IntPtr.Zero) {
                return null;
            }

            string funcName = "acedSetEnv";

            IntPtr pAddressOfFunctionToCall = Utils
                .GetProcAddress(pDll, funcName);

            if (pAddressOfFunctionToCall == IntPtr.Zero) {

                return null;
            }

            acedSetEnvDelegate acedSetEnv = (
                acedSetEnvDelegate) Marshal
                .GetDelegateForFunctionPointer(
                pAddressOfFunctionToCall,
                typeof(acedSetEnvDelegate));

            bool result = Utils.FreeLibrary(pDll);

            return acedSetEnv;
        }
    }
}

 ------------------------------------------------------------

Далее создадим тестовую команду, которая изменит значение переменной "ACAD":

------------------------------------------------------------
/* Commands.cs */
using System;
using System.Runtime.InteropServices;
using System.Text;
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;

namespace Bushman.AutoCAD.Sandbox {

    public sealed class Commands {

        [CommandMethod("Test", CommandFlags.Modal)]
        public void Test() {

            Document doc = cad.DocumentManager
                .MdiActiveDocument;

            if (doc == null)
                return;

            Editor ed = doc.Editor;

            acedSetEnvDelegate acedSetEnv = Utils.acedSetEnv;

            if (acedSetEnv == null) {
                ed.WriteMessage("acedSetEnv function was " +
                    "not found.");
                return;
            }

            /* For example, we'll edit the "Support File Search
             * Path" value: */
            string varName = "ACAD";
            StringBuilder sb = new StringBuilder(
                @"C:\abc\def");

            int theResult = acedSetEnv(varName, sb); // 5100
        }
    }
}

---------------------------------------------------------------

Динамическое связывание и изменение системой переменной ACAD успешно происходит в обоих тестируемых версиях AutoCAD: 2009 и 2016.



Динамический вызов функций неуправляемых DLL

В .NET-атрибутах можно указывать только константные выражения. Т.о. атрибуту DllImport нужно указывать имя библиотеки статически, дабы это имя было известно на этапе компиляции. Порой это порождает уродливые конструкции, разрастающиеся как снежный ком, по мере появления новых версий AutoCAD. Наглядный тому пример можно увидеть здесь в коде Александра Ривилиса: по мере появления AutoCAD 2018, 2019 и т.д. - этот код придётся каждый раз дописывать.


Как правило, имя нужной DLL достаточно просто выяснить во время выполнения кода. Например, в обозначенном выше коде Александра Ривилиса нужная функция хранится в файлах acdb17.dll, acdb18.dll, ac1st19.dll, ac1st20.dll, ac1st21.dll. Т.е. мы видим, что каждая библиотека в качестве суффикса использует значение Major версии приложения. Кроме того, мы видим, что начиная с версии 19 (AutoCAD 2013) функция была перенесена в др. библиотеку (т.е. изменился префикс в её имени). Зная обозначенные выше правила, можно динамически вычислить имя DLL файла, в котором находится интересующая нас функция.

Далее показываю небольшой пример того, как можно динамически вызывать функцию acedSetEnv в разных версиях AutoCAD, не создавая для неё статических обёрток. На всякий случай напоминаю, что до версии AutoCAD 2013 эта функция находилась в файле acad.exe, а начиная с AutoCAD 2013 была перенесена в accore.dll.

Код проверялся в AutoCAD 2009 и 2016.

-------------------------------------------------------------
/* Utils.cs */
using System;
using System.Text;
using System.Runtime.InteropServices;
using cad = Autodesk.AutoCAD.ApplicationServices.Application;

namespace Bushman.AutoCAD.Sandbox {

    [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet
        = CharSet.Auto)]
    public delegate int acedSetEnvDelegate(string envName,
        StringBuilder NewValue);

    public static class Utils {

        [DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibrary(string
            dllToLoad);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress(IntPtr
            hModule, string procedureName);


        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);

        const int AutoCAD_2013_Major = 19;

        public static string GetDllName() {

            if (cad.Version.Major < AutoCAD_2013_Major)
                return "acad.exe";
            else
                return "accore.dll";
        }

        public static acedSetEnvDelegate acedSetEnv;

        static Utils() {
            acedSetEnv = GetAcedSetEnv();
        }

        static acedSetEnvDelegate GetAcedSetEnv() {

            string dllName = Utils.GetDllName();
            IntPtr pDll = Utils.LoadLibrary(dllName);

            if (pDll == IntPtr.Zero) {
                return null;
            }

            string funcName = "acedSetEnv";

            IntPtr pAddressOfFunctionToCall = Utils
                .GetProcAddress(pDll, funcName);

            if (pAddressOfFunctionToCall == IntPtr.Zero) {

                return null;
            }

            acedSetEnvDelegate acedSetEnv = (
                acedSetEnvDelegate) Marshal
                .GetDelegateForFunctionPointer(
                pAddressOfFunctionToCall,
                typeof(acedSetEnvDelegate));

            bool result = Utils.FreeLibrary(pDll);

            return acedSetEnv;
        }
    }
}

 ------------------------------------------------------------

Далее создадим тестовую команду, которая изменит значение переменной "ACAD":

------------------------------------------------------------
/* Commands.cs */
using System;
using System.Runtime.InteropServices;
using System.Text;
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;

namespace Bushman.AutoCAD.Sandbox {

    public sealed class Commands {

        [CommandMethod("Test", CommandFlags.Modal)]
        public void Test() {

            Document doc = cad.DocumentManager
                .MdiActiveDocument;

            if (doc == null)
                return;

            Editor ed = doc.Editor;

            acedSetEnvDelegate acedSetEnv = Utils.acedSetEnv;

            if (acedSetEnv == null) {
                ed.WriteMessage("acedSetEnv function was " +
                    "not found.");
                return;
            }

            /* For example, we'll edit the "Support File Search
             * Path" value: */
            string varName = "ACAD";
            StringBuilder sb = new StringBuilder(
                @"C:\abc\def");

            int theResult = acedSetEnv(varName, sb); // 5100
        }
    }
}

---------------------------------------------------------------

Динамическое связывание и изменение системой переменной ACAD успешно происходит в обоих тестируемых версиях AutoCAD: 2009 и 2016.



NuGet пакеты для AutoCAD .NET API

Пару лет назад, компания Autodesk начала (наконец-то!) опубликовывать NuGet-пакеты для AutoCAD .NET API. Об этом так же было радостно сообщено в блоге ADN. Однако, как это обычно и бывает у Autodesk, тестированием пакетов перед их публикацией в Autodesk не заморачиваются (как собственно и тестированием самого AutoCAD, ибо длительная, печальная практика показывает, что группа тестирования даже самого AutoCAD в компании Autodesk в принципе нарисована только "для галочки" - примеров, доказывающих это - множество, в т.ч. и в моём блоге).

 Пробежавшись по комментариям, оставленным пользователями в обозначенной выше записи блога ADN можно сразу заметить, что пакеты работают криво. Т.е. их тестированием себя никто не утруждал. С тех пор Autodesk выпустил ещё две версии AutoCAD. Казалось бы, что за два года можно было вполне довести до ума пакеты, на создание которых (с нуля) уходит не более получаса (причём сразу под все версии AutoCAD от 2009 и выше)... Но печальная практика в который раз демонстрирует обратное...

Я попробовал установить самую свежую на сегодняшний день версию пакета AutoCAD.NET (version 21.0.1). В душе теплилась надежда, что за два года проблему с CopyLocal в Autodesk всё же победили, тем более что её решение находится в Google за пару секунд по элементарной фразе: "NuGet CopyLocal false". Однако, как оказалось, воз и поныне там - ни одна сборка, подключенная путём установки NuGet пакета не имеет свойства CopyLocal установленного в false.

Я не верю в то, что в Autodesk работают настолько глупые люди (глупых бы не взяли на работу, как мне кажется). То, что я систематически вижу, всякий раз подтверждает моё давно сформировавшееся убеждение в том, что в Autodesk работают люди, многим из которых просто наплевать на качество своей работы (это ещё хуже, чем первый вариант)... К таким людям (ИМХО) на все 100% относится группа тестирования (во главе с Михаилом Белиловским, насколько я помню), которая выполняет свою работу (если вообще выполняет) из рук вон плохо - достаточно посмотреть на качество работы того же accoreconsole.exe. Подобным отношением к своей работе страдает и тот сотрудник Autodesk, которому поручили собирать и опубликовывать NuGet пакеты AutoCAD.NET. Можно сколько угодно с умным видом разъезжать по различным конференциям, изображая бурную радость и воодушевление в процессе разговоров о программировании в AutoCAD, но если ты не выполняешь свою прямую, первостепенную обязанность - отвечать за качество тестирования продукта, то грош цена таким разговорам, улыбкам... да и самим специалистам (ИМХО).

 Ладно, не буду более трепать себе понапрасну нервы из-за качества работы обозначенных выше персонажей (моих нервов они не стоят :) ) - давайте лучше вернёмся к их злосчастным NuGet пакетам...

Отсутствие нужного значения в свойстве CopyLocal не является единственной проблемой. Текущая реализация пакетов подразумевает, что каждый раз, запуская команду Update-Package (без опции -Version) вы тем самым будете обновлять все сборки AutoCAD, подключенные в вашем проекте, до самой последней версии AutoCAD (для которой имеется соответствующий NuGet пакет).

Однако вовсе не факт, что разработчик захочет именно такое поведение. Лично я хочу, чтобы если я в своём проекте указал использование сборок от AutoCAD 2016, то и все обновления должны происходить только в рамках интересующей меня версии AutoCAD. Мне не нужно, чтобы происходило автоматическое обновление сборок до версии AutoCAD 2017, 2018 или 2020 - не надо за меня принимать подобных решений(!!!)...

Если мне понадобится создать отдельную сборку для более новой версии AutoCAD, то я сам создам дополнительный проект в составе своего решения, и уже в него подключу NuGet пакет более новой, нужной мне версии AutoCAD, с последующим добавлением файлов исходного кода из предыдущего проекта (добавленных посредством ссылок на оригиналы).

Для того, чтобы избежать обозначенной выше проблемы, созданной Autodesk'ом, нужно для каждой версии AutoCAD формировать (всего лишь!) уникальное имя пакета (т.е. его Id). Значения Minor и Major для версий этих пакетов можно брать либо из соответствующий значений версий AutoCAD, либо начинать с 1 (это не имеет значения, но выбрав стиль нумерации версий, следует придерживаться его и в др. пакетах во избежание путанницы).

Autodesk предоставляет NuGet пакеты только начиная с версии AutoCAD  2015. Для более поздних версий пакеты не предоставляются.

Поскольку NuGet пакеты компани Autodesk не пригодны к полноценному использованию в том виде, в котором они уже который год поставляются пользователям (ИМХО), а так же поскольку отсутствуют пакеты для интересующих меня версий AutoCAD, то я создал свои NuGet пакеты, предоставляющие AutoCAD .NET API, в которых отсутствуют обозначеные мною выше проблемы.

Чаще всего я компилирую код своих проектов под AutoCAD 2009 и 2013. Результат компиляции первого из них может затем успешно загружаться в AutoCAD 2009-2012, а второго - в AutoCAD 2013 и во все более новые версии. В виду этого, в первую очередь я создал NuGet пакеты именно для AutoCAD 2009 и 2013.

В ближайшее время я, на всякий случай, создам аналогичные NuGet пакеты для всех остальных версий AutoCAD из диапазона AutoCAD 2009-2017 (на тот случай, если мне в каком-то проекте, по какой-то причине, понадобится иная версия API).

UPD
Опубликовал NuGet пакеты для AutoCAD 2009-2017 (на каждую версию AutoCAD по три пакета).

NuGet пакеты для AutoCAD .NET API

Пару лет назад, компания Autodesk начала (наконец-то!) опубликовывать NuGet-пакеты для AutoCAD .NET API. Об этом так же было радостно сообщено в блоге ADN. Однако, как это обычно и бывает у Autodesk, тестированием пакетов перед их публикацией в Autodesk не заморачиваются (как собственно и тестированием самого AutoCAD, ибо длительная, печальная практика показывает, что группа тестирования даже самого AutoCAD в компании Autodesk в принципе нарисована только "для галочки" - примеров, доказывающих это - множество, в т.ч. и в моём блоге).

 Пробежавшись по комментариям, оставленным пользователями в обозначенной выше записи блога ADN можно сразу заметить, что пакеты работают криво. Т.е. их тестированием себя никто не утруждал. С тех пор Autodesk выпустил ещё две версии AutoCAD. Казалось бы, что за два года можно было вполне довести до ума пакеты, на создание которых (с нуля) уходит не более получаса (причём сразу под все версии AutoCAD от 2009 и выше)... Но печальная практика в который раз демонстрирует обратное...

Я попробовал установить самую свежую на сегодняшний день версию пакета AutoCAD.NET (version 21.0.1). В душе теплилась надежда, что за два года проблему с CopyLocal в Autodesk всё же победили, тем более что её решение находится в Google за пару секунд по элементарной фразе: "NuGet CopyLocal false". Однако, как оказалось, воз и поныне там - ни одна сборка, подключенная путём установки NuGet пакета не имеет свойства CopyLocal установленного в false.

Я не верю в то, что в Autodesk работают настолько глупые люди (глупых бы не взяли на работу, как мне кажется). То, что я систематически вижу, всякий раз подтверждает моё давно сформировавшееся убеждение в том, что в Autodesk работают люди, многим из которых просто наплевать на качество своей работы (это ещё хуже, чем первый вариант)... К таким людям (ИМХО) на все 100% относится группа тестирования (во главе с Михаилом Белиловским, насколько я помню), которая выполняет свою работу (если вообще выполняет) из рук вон плохо - достаточно посмотреть на качество работы того же accoreconsole.exe. Подобным отношением к своей работе страдает и тот сотрудник Autodesk, которому поручили собирать и опубликовывать NuGet пакеты AutoCAD.NET. Можно сколько угодно с умным видом разъезжать по различным конференциям, изображая бурную радость и воодушевление в процессе разговоров о программировании в AutoCAD, но если ты не выполняешь свою прямую, первостепенную обязанность - отвечать за качество тестирования продукта, то грош цена таким разговорам, улыбкам... да и самим специалистам (ИМХО).

 Ладно, не буду более трепать себе понапрасну нервы из-за качества работы обозначенных выше персонажей (моих нервов они не стоят :) ) - давайте лучше вернёмся к их злосчастным NuGet пакетам...

Отсутствие нужного значения в свойстве CopyLocal не является единственной проблемой. Текущая реализация пакетов подразумевает, что каждый раз, запуская команду Update-Package (без опции -Version) вы тем самым будете обновлять все сборки AutoCAD, подключенные в вашем проекте, до самой последней версии AutoCAD (для которой имеется соответствующий NuGet пакет).

Однако вовсе не факт, что разработчик захочет именно такое поведение. Лично я хочу, чтобы если я в своём проекте указал использование сборок от AutoCAD 2016, то и все обновления должны происходить только в рамках интересующей меня версии AutoCAD. Мне не нужно, чтобы происходило автоматическое обновление сборок до версии AutoCAD 2017, 2018 или 2020 - не надо за меня принимать подобных решений(!!!)...

Если мне понадобится создать отдельную сборку для более новой версии AutoCAD, то я сам создам дополнительный проект в составе своего решения, и уже в него подключу NuGet пакет более новой, нужной мне версии AutoCAD, с последующим добавлением файлов исходного кода из предыдущего проекта (добавленных посредством ссылок на оригиналы).

Для того, чтобы избежать обозначенной выше проблемы, созданной Autodesk'ом, нужно для каждой версии AutoCAD формировать (всего лишь!) уникальное имя пакета (т.е. его Id). Значения Minor и Major для версий этих пакетов можно брать либо из соответствующий значений версий AutoCAD, либо начинать с 1 (это не имеет значения, но выбрав стиль нумерации версий, следует придерживаться его и в др. пакетах во избежание путанницы).

Autodesk предоставляет NuGet пакеты только начиная с версии AutoCAD  2015. Для более поздних версий пакеты не предоставляются.

Поскольку NuGet пакеты компани Autodesk не пригодны к полноценному использованию в том виде, в котором они уже который год поставляются пользователям (ИМХО), а так же поскольку отсутствуют пакеты для интересующих меня версий AutoCAD, то я создал свои NuGet пакеты, предоставляющие AutoCAD .NET API, в которых отсутствуют обозначеные мною выше проблемы.

Чаще всего я компилирую код своих проектов под AutoCAD 2009 и 2013. Результат компиляции первого из них может затем успешно загружаться в AutoCAD 2009-2012, а второго - в AutoCAD 2013 и во все более новые версии. В виду этого, в первую очередь я создал NuGet пакеты именно для AutoCAD 2009 и 2013.

В ближайшее время я, на всякий случай, создам аналогичные NuGet пакеты для всех остальных версий AutoCAD из диапазона AutoCAD 2009-2017 (на тот случай, если мне в каком-то проекте, по какой-то причине, понадобится иная версия API).

UPD
Опубликовал NuGet пакеты для AutoCAD 2009-2017 (на каждую версию AutoCAD по три пакета).

Прокси в AutoCAD

Обновлена утилита по работе с прокси в AutoCAD.

Что нового...

1. CadProxy был переименован в Proxy Tools for AutoCAD (т.е. в Прокси-инструменты для AutoCAD).
2. Теперь это бесплатное программное обеспечение вместо открытого программного обеспечения.
3. Добавлены русская и английская лицензии.
4. Добавлена русская локализация.
5. Для AutoCAD 2009-2011: в процессе загрузки приложения в AutoCAD, родительский каталог приложения будет добавлен в Путь доступа к вспомогательным файлам (если это ещё не было сделано ранее).* Это необходио для работы справочной системы приложения.
6. Для AutoCAD 2009-2011: в реестре будет выполнена регистрация приложения (загрузка по требованию), если это не было сделано ранее.* В виду этого, вызов команды _NETLOAD для этих версий AutoCAD потребуется только один раз.
7. Операция ПРОВЕРИТЬ (_AUDIT) будет выполняться каждый раз перед расчленением или удалением прокси, если команды ВЗПРОКСИ (_XPROXY) или УДПРОКСИ (_RMPROXY) не являются предыдущей выполненной командой. Так же команда ПРОВЕРИТЬ (_AUDIT) будет автоматически выполняться и после работы этих команд.
8. Если файлы меню CUICUIX были ранее загружены пользователем в AutoCAD непосредственно из каталога расширения, тогда они будут выгружены, скопированы в Windows-профиль пользователя и затем в AutoCAD будут загружены эти копии.*
9. Изображения в файлах меню CUICUIX были заменены. Теперь эти изображения используют ICO формат вместо BMP (новые изображения используют прозрачность).
10. MNR-файлы были удалены из MSI-инсталлятора.
11. MSI-инсталлятор был полностью переписан. Теперь он показывает лицензию, устанавливаемые наборы компонентов, а так же предоставляет фиксированный набор каталогов, в которые может быть выполнена установка приложения.
12. Имеется две версии локализации MSI-установщика: английская и русская.
13. Инсталлятор добавляет пункты меню в Пуск -> Все программы. Локализация этих пунктов меню совпадает с локализацией использованного MSI-инсталлятора.
14. Теперь 32-битная версия MSI-инсталлятора не может использоваться для Windows x64 (ограничение добавлено намеренно).
15. Теперь расширение может быть установлено как с административными правами, так и без них. Это зависит от выбора, который сделает пользователь в процессе установки приложения.
16. Файл справки полностью переписан.
17. Исправлены некоторые ошибки в программном коде.


* - Проверка будет выполняться каждый раз при загрузке приложения в AutoCAD.

Пользовательское меню:



 Меню в Пуск -> Все программы:


 Дополнительная информация, размещаемая в реестре:


Возможность выбрать целевой каталог установки:


Локализованная справка:




Прокси в AutoCAD

Обновлена утилита по работе с прокси в AutoCAD.

Что нового...

1. CadProxy был переименован в Proxy Tools for AutoCAD (т.е. в Прокси-инструменты для AutoCAD).
2. Теперь это бесплатное программное обеспечение вместо открытого программного обеспечения.
3. Добавлены русская и английская лицензии.
4. Добавлена русская локализация.
5. Для AutoCAD 2009-2011: в процессе загрузки приложения в AutoCAD, родительский каталог приложения будет добавлен в Путь доступа к вспомогательным файлам (если это ещё не было сделано ранее).* Это необходио для работы справочной системы приложения.
6. Для AutoCAD 2009-2011: в реестре будет выполнена регистрация приложения (загрузка по требованию), если это не было сделано ранее.* В виду этого, вызов команды _NETLOAD для этих версий AutoCAD потребуется только один раз.
7. Операция ПРОВЕРИТЬ (_AUDIT) будет выполняться каждый раз перед расчленением или удалением прокси, если команды ВЗПРОКСИ (_XPROXY) или УДПРОКСИ (_RMPROXY) не являются предыдущей выполненной командой. Так же команда ПРОВЕРИТЬ (_AUDIT) будет автоматически выполняться и после работы этих команд.
8. Если файлы меню CUI\CUIX были ранее загружены пользователем в AutoCAD непосредственно из каталога расширения, тогда они будут выгружены, скопированы в Windows-профиль пользователя и затем в AutoCAD будут загружены эти копии.*
9. Изображения в файлах меню CUI\CUIX были заменены. Теперь эти изображения используют ICO формат вместо BMP (новые изображения используют прозрачность).
10. MNR-файлы были удалены из MSI-инсталлятора.
11. MSI-инсталлятор был полностью переписан. Теперь он показывает лицензию, устанавливаемые наборы компонентов, а так же предоставляет фиксированный набор каталогов, в которые может быть выполнена установка приложения.
12. Имеется две версии локализации MSI-установщика: английская и русская.
13. Инсталлятор добавляет пункты меню в Пуск -> Все программы. Локализация этих пунктов меню совпадает с локализацией использованного MSI-инсталлятора.
14. Теперь 32-битная версия MSI-инсталлятора не может использоваться для Windows x64 (ограничение добавлено намеренно).
15. Теперь расширение может быть установлено как с административными правами, так и без них. Это зависит от выбора, который сделает пользователь в процессе установки приложения.
16. Файл справки полностью переписан.
17. Исправлены некоторые ошибки в программном коде.


* - Проверка будет выполняться каждый раз при загрузке приложения в AutoCAD.

Пользовательское меню:



 Меню в Пуск -> Все программы:


 Дополнительная информация, размещаемая в реестре:


Возможность выбрать целевой каталог установки:


Локализованная справка:




И снова о хостинге WCF-сервисов в 2016-м accoreconsole.exe…

Подумал тут... Вполне возможно, что Autodesk умышленно прикрыла возможность хостинга сервисов в 2016-м accoreconsole.exe, дабы если не полностью пресечь (т.к. это не возможно), то хотя бы максимально усложнить возможность использования инструмента в системе распределённых приложений взаимодействующих через сервисы...

Наличие возможности хостинга WCF-сервисов в accoreconsole.exe для ряда случаев может существенно сократить потребность в количестве приобретаемых лицензий AutoCAD на предприятиях, где выполнение некоторого (если даже не всего) объёма работ можно автоматизировать (т.е. сделать программно). Одним сервисом или набором сервисов (читать как "одной лицензией AutoCAD") в таком случае сможет пользоваться неограниченное количество сотрудников компании одновременно. Для компании клиента это, безусловно, экономия... Но вот для компании Autodesk - это потеря денег... Т.е. налицо явный конфликт интересов и вполне очевидно, кто в данной ситуации имеет на руках "все козыри".

Кроме того, не стоит забывать, что теперь в Autodesk хотят одних и тех же овец стричь каждый год (новая ценовая политика) в виду чего даже сама по себе потенциальная возможность  сокращения лицензий вряд ли будет воспринята ими положительно. Т.о., как я уже писал выше: не исключено, что в 2016-м AutoCAD "кислород" сервисам был перекрыт преднамеренно...

Резюме
Я не удивлюсь, если в более новых версиях AutoCAD приложение accoreconsole.exe будет вовсе тихо изъято, мол "за ненадобностью"...

И снова о хостинге WCF-сервисов в 2016-м accoreconsole.exe…

Подумал тут... Вполне возможно, что Autodesk умышленно прикрыла возможность хостинга сервисов в 2016-м accoreconsole.exe, дабы если не полностью пресечь (т.к. это не возможно), то хотя бы максимально усложнить возможность использования инструмента в системе распределённых приложений взаимодействующих через сервисы...

Наличие возможности хостинга WCF-сервисов в accoreconsole.exe для ряда случаев может существенно сократить потребность в количестве приобретаемых лицензий AutoCAD на предприятиях, где выполнение некоторого (если даже не всего) объёма работ можно автоматизировать (т.е. сделать программно). Одним сервисом или набором сервисов (читать как "одной лицензией AutoCAD") в таком случае сможет пользоваться неограниченное количество сотрудников компании одновременно. Для компании клиента это, безусловно, экономия... Но вот для компании Autodesk - это потеря денег... Т.е. налицо явный конфликт интересов и вполне очевидно, кто в данной ситуации имеет на руках "все козыри".

Кроме того, не стоит забывать, что теперь в Autodesk хотят одних и тех же овец стричь каждый год (новая ценовая политика) в виду чего даже сама по себе потенциальная возможность  сокращения лицензий вряд ли будет воспринята ими положительно. Т.о., как я уже писал выше: не исключено, что в 2016-м AutoCAD "кислород" сервисам был перекрыт преднамеренно...

Резюме
Я не удивлюсь, если в более новых версиях AutoCAD приложение accoreconsole.exe будет вовсе тихо изъято, мол "за ненадобностью"...

О хостинге WCF-сервисов в accoreconsole.exe (продолжение)

В продолжение предыдущей записи по обозначенной теме...

Экспериментальным путём выяснил, что проблема хостинга WCF сервисов в accoreconsole.exe присутствует в AutoCAD 2016, но отсутствует во всех более ранних версиях (2013-2015). Проверялось на AutoCAD 2016 x64 SP1 English с установленным Hotfix 3. Проверить наличие обозначенной проблемы в AutoCAD 2017 нет возможности за неимением оного, но очень даже не исключено, что обозначенный баг будет теперь и в нём и во всех последующих версиях...

Примечание:
Во всех без исключениях версиях accoreconsole.exe наблюдал ещё и такую проблему: то, что программно отправляется в консоль AutoCAD через Editor.WriteLine(...) по факту в консоли не появляется... Можно вместо этого воспользоваться Application.ShowAlertDialog(...) - в этом случае текст попадает в консоль, но это очень похоже на выдёргивание зубов плоскогубцами через зад...

О хостинге WCF-сервисов в accoreconsole.exe (продолжение)

В продолжение предыдущей записи по обозначенной теме...

Экспериментальным путём выяснил, что проблема хостинга WCF сервисов в accoreconsole.exe присутствует в AutoCAD 2016, но отсутствует во всех более ранних версиях (2013-2015). Проверялось на AutoCAD 2016 x64 SP1 English с установленным Hotfix 3. Проверить наличие обозначенной проблемы в AutoCAD 2017 нет возможности за неимением оного, но очень даже не исключено, что обозначенный баг будет теперь и в нём и во всех последующих версиях...

Примечание:
Во всех без исключениях версиях accoreconsole.exe наблюдал ещё и такую проблему: то, что программно отправляется в консоль AutoCAD через Editor.WriteLine(...) по факту в консоли не появляется... Можно вместо этого воспользоваться Application.ShowAlertDialog(...) - в этом случае текст попадает в консоль, но это очень похоже на выдёргивание зубов плоскогубцами через зад...