21
AutoCAD .NET API / AutoCAD 2025 - переползаю на Net8
« Последний ответ от avc 27-03-2024, 19:08:04 »Эта тема - не вопрос. Просто делюсь опытом.
Итак Autodesk внял мольбам и дал возможность программировать на современном C#. Но эта хорошая затея вылилась в большую головную боль. И будет теперь болью надолго.
Главная проблема: Microsoft не довели до ума этот Net8 и потеряли уйму совершенно необходимой функциональности. В эту версию не встроена работа с реестром Windows, c железом (WMI), с данными (SQL) и так далее. Отчасти это решается закачкой отдельных библиотек (NuGet). И вот тут начинается свистопляска. У библиотек этих куча несовместимых версий. В сам AutoCAD как оказалось входят старые версии и надо компилировать именно под них. Несколько версий одной библиотеки в один AutoCAD не загрузишь и если разные плагины на разные версии скомпилированы, то это не просто сбой, это фатал AutoCAD. А завтра Autodesk обновит эти библиотеки и все плагины надо будет перекомпилировать. В общем стараниями Microsoft, мы погрузились в темные древние времена вечно несовместимых ActiveX...
Теперь по порядку.
Старые проекты не скомпилировать под Net8. Надо создавать новый проект. Есть плагин к VS для миграции. Но он не работает. Он не перененосит настройки из AssemblyInfo, теряет все ресурсы форм и компонентов WinForms, не подгружает недостающие библиотеки, забытые Microsoft. Создаем проект с ноля - так быстрее.
Ищем нужные NuGet пакеты. Из того что у меня используется, оказалось что System.Managment уже есть в AutoCAD 2025. Но (!) он там старый, версия 6.0. Нужно именно 6.0 подключать к проекту, иначе будет фатал при попытке принудительной загрузки нового 8.0 или при инициализации классов его использующих (если не пытаться загружать dll принудительно).
Далее из всех этих NuGet надо вытащить нужные dll и доставить их всем пользователям плагинов!! Теперь ваш плагин это сложная составная программа, а не один файл. Увы. Придется делать инсталлятор, если у вас его еще нет. Вытащить dll не просто. У этих NuGet нет свойства "копировать в целевую папку". И вообще с удобным визуальным интерфейсом настроек проекта Microsoft распрощались. Теперь все полезные настройки надо долго гуглить и вставлять в жуткий html-файл проекта. Брррр. Настройка, чтоб dll копировались в папку плагина:
Теперь нам надо у пользователя загрузить эти dll. Но в папке плагина Автокад их не находит. Либо надо требовать права админа инсталлтору и закидывать в системные папки (я пробовал прям в папку AutoCAD - это работает). Либо в коде прописать принудительную загрузку. В Initialize добавляем:
А вот например sni.dll загружать почему-то нельзя. Сам загрузится из System.Data.SqlClient.dll. Многие пишут что надо менять System.Data.SqlClient на Microsoft.Data.SqlClient. Но нет, там совсем другие классы и методы, старый код не компилируется.
Далее у нас получился проект без версии. Добавляем в него наш старый AssemblyInfo как ссылку и опять лезем в конфиг проекта:
Без второй строчки (о которой никто не пишет!!) версия dll не будет видна в проводнике Windows.
Теперь надо еще сам код редактировать. К запуску процессов добавляем UseShellExecute = true:
Еще у меня появился конфликт RegistryKey с автокадовским API
VS завалила меня бредовыми предупреждениями. Заблокировал тоже в файле проекта:
Еще шаманил с ресурсами. Итого начало файла проекта получилось таким:
Итак Autodesk внял мольбам и дал возможность программировать на современном C#. Но эта хорошая затея вылилась в большую головную боль. И будет теперь болью надолго.
Главная проблема: Microsoft не довели до ума этот Net8 и потеряли уйму совершенно необходимой функциональности. В эту версию не встроена работа с реестром Windows, c железом (WMI), с данными (SQL) и так далее. Отчасти это решается закачкой отдельных библиотек (NuGet). И вот тут начинается свистопляска. У библиотек этих куча несовместимых версий. В сам AutoCAD как оказалось входят старые версии и надо компилировать именно под них. Несколько версий одной библиотеки в один AutoCAD не загрузишь и если разные плагины на разные версии скомпилированы, то это не просто сбой, это фатал AutoCAD. А завтра Autodesk обновит эти библиотеки и все плагины надо будет перекомпилировать. В общем стараниями Microsoft, мы погрузились в темные древние времена вечно несовместимых ActiveX...
Теперь по порядку.
Старые проекты не скомпилировать под Net8. Надо создавать новый проект. Есть плагин к VS для миграции. Но он не работает. Он не перененосит настройки из AssemblyInfo, теряет все ресурсы форм и компонентов WinForms, не подгружает недостающие библиотеки, забытые Microsoft. Создаем проект с ноля - так быстрее.
Ищем нужные NuGet пакеты. Из того что у меня используется, оказалось что System.Managment уже есть в AutoCAD 2025. Но (!) он там старый, версия 6.0. Нужно именно 6.0 подключать к проекту, иначе будет фатал при попытке принудительной загрузки нового 8.0 или при инициализации классов его использующих (если не пытаться загружать dll принудительно).
Далее из всех этих NuGet надо вытащить нужные dll и доставить их всем пользователям плагинов!! Теперь ваш плагин это сложная составная программа, а не один файл. Увы. Придется делать инсталлятор, если у вас его еще нет. Вытащить dll не просто. У этих NuGet нет свойства "копировать в целевую папку". И вообще с удобным визуальным интерфейсом настроек проекта Microsoft распрощались. Теперь все полезные настройки надо долго гуглить и вставлять в жуткий html-файл проекта. Брррр. Настройка, чтоб dll копировались в папку плагина:
Код - XML [Выбрать]
- <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
Теперь нам надо у пользователя загрузить эти dll. Но в папке плагина Автокад их не находит. Либо надо требовать права админа инсталлтору и закидывать в системные папки (я пробовал прям в папку AutoCAD - это работает). Либо в коде прописать принудительную загрузку. В Initialize добавляем:
Код - C# [Выбрать]
- if (CadApp.Version.Major >= 25) // Net8
- {
- Assembly.LoadFrom(Path.Combine(path, "System.CodeDom.dll"));
- Assembly.LoadFrom(Path.Combine(path, "System.Data.SqlClient.dll"));
- Assembly.LoadFrom(Path.Combine(path, "System.Management.dll"));
- }
Далее у нас получился проект без версии. Добавляем в него наш старый AssemblyInfo как ссылку и опять лезем в конфиг проекта:
Код - XML [Выбрать]
- <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
- <GenerateAssemblyVersionAttribute>true</GenerateAssemblyVersionAttribute>
Теперь надо еще сам код редактировать. К запуску процессов добавляем UseShellExecute = true:
Код - C# [Выбрать]
- #if NET8_0_OR_GREATER
- Process.Start(new ProcessStartInfo(myexe) { UseShellExecute = true });
- #else
- Process.Start(myexe);
- #endif
Еще у меня появился конфликт RegistryKey с автокадовским API
Код - C# [Выбрать]
- #if NET8_0_OR_GREATER
- using RegistryKey = Microsoft.Win32.RegistryKey;
- #endif
VS завалила меня бредовыми предупреждениями. Заблокировал тоже в файле проекта:
Код - XML [Выбрать]
- <NoWarn>
- 1701;1702;CA1416;SYSLIB0021;SYSLIB0022;SYSLIB0011;SYSLIB0014
- </NoWarn>
Еще шаманил с ресурсами. Итого начало файла проекта получилось таким:
Код - XML [Выбрать]
- <Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <TargetFramework>net8.0-windows</TargetFramework>
- <RuntimeIdentifier>win-x64</RuntimeIdentifier>
- <OutputType>Library</OutputType>
- <RootNamespace>AVC</RootNamespace>
- <AssemblyName>AVC_Plugin_Ac25</AssemblyName>
- <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
- <GenerateAssemblyVersionAttribute>true</GenerateAssemblyVersionAttribute>
- <UseWindowsForms>true</UseWindowsForms>
- <UseWPF>true</UseWPF>
- <ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
- <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
- <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
- <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
- <GenerateResourceWarnOnBinaryFormatterUse>false</GenerateResourceWarnOnBinaryFormatterUse>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <OutputPath>C:\Users\shurik\AppData\Roaming\Autodesk\ApplicationPlugins\AVC_Pro.bundle\Contents\Windows\</OutputPath>
- <DefineConstants>DEBUG;TRACE;CAD</DefineConstants>
- <LangVersion>preview</LangVersion>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>none</DebugType>
- <OutputPath>C:\Users\shurik\AppData\Roaming\Autodesk\ApplicationPlugins\AVC_Pro.bundle\Contents\Windows\</OutputPath>
- <DefineConstants>CAD;STOPHACK</DefineConstants>
- <LangVersion>preview</LangVersion>
- <NoWarn>
- 1701;1702;CA1416;SYSLIB0021;SYSLIB0022;SYSLIB0011;SYSLIB0014
- </NoWarn>