ADN Club > AutoCAD .NET API

AutoCAD 2025 - переползаю на Net8

(1/7) > >>

avc:
Эта тема - не вопрос. Просто делюсь опытом.
Итак 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"));        }А вот например sni.dll загружать почему-то нельзя. Сам загрузится из System.Data.SqlClient.dll. Многие пишут что надо менять System.Data.SqlClient на Microsoft.Data.SqlClient. Но нет, там совсем другие классы и методы, старый код не компилируется.

Далее у нас получился проект без версии. Добавляем в него наш старый AssemblyInfo как ссылку и опять лезем в конфиг проекта:

--- Код - XML [Выбрать] ---    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>    <GenerateAssemblyVersionAttribute>true</GenerateAssemblyVersionAttribute>Без второй строчки (о которой никто не пишет!!) версия dll не будет видна в проводнике Windows.

Теперь надо еще сам код редактировать. К запуску процессов добавляем 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_GREATERusing 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>

Привалов Дмитрий:

--- Цитата: avc от 27-03-2024, 19:08:04 ---Главная проблема: Microsoft не довели до ума этот Net8 и потеряли уйму совершенно необходимой функциональности. В эту версию не встроена работа с реестром Windows, c железом (WMI), с данными (SQL) и так далее.
--- Конец цитаты ---
Формулировка не верная, довела до ума, но под другие задачи.
.NET(.NET Core) это мультиплатформенные решения, которые должны одинаково выполняться на различных ОС. В них оставили только общий функционал для всех платформ.
Не стоит ожидать появления например работу с ActiveX и работу с реестром в .NET
Более того не очень понятно, что в .NET с Winforms, WPF, MAUI и т.д. похоже Microsoft не планирует переносить все на Linux, т.к. они слишком завязаны на Windows.

Для разработки под Windows, .NET менее функционален, чем .NET Framework.
Наверное ветки .NET и .NET Framework будут и далее развиваться параллельно.

Алексей Кулик:
Позволю себе немного не согласиться :)
NET6 (на котором я на данный момент сижу), и, подозреваю, NET8 - совершенно другая платформа.
Действительно, многое, что в NET FrameWork было "из коробки", придется доставлять NuGet-пакетами (там не только реестр, но и кодировки файлов, и овердофига чего еще). Насчет совместимости ничего сказать не могу - пока не сталкивался.
Новый проект можно не создавать с нуля, а пробросить связь (Link) на старый проект. Т.е. в одном решении будет сразу два проекта - один под FrameWork, второй под NET8.
Вытаскивать из NuGet ничего не надо. Для предоставления конечным пользователям можно использовать AssemblyResolve в инициализаторе. И выполнять не сборку, а публикацию проекта. Ну или в cspoj руками прописать как ты и сделал:
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
По крайней мере у меня оно работает.
Работу с SQL, возможно, будет иметь смысл переложить на EntityFramework (который вообще положить в отдельную сборку NET Standard 2.0 для совместного использования в NET Framework и NET8). Тогда и с клиентами особо можно не заморачиваться ;)
Версию сборки также можно руками прописать в csproj:
<Version>1.2.3.4</Version>
После этого и в GUI MS VS станет доступным соответствующее поле.
Для использования в проекте WinForms достаточно прописать как и у тебя:
<UseWindowsForms>true</UseWindowsForms>
Для использования WPF - соответственно
<UseWPF>true</UseWPF>
Насчет ресурсов ничего не скажу, пока не требовалось. А ресурсные библиотеки под меню у меня все равно в отдельном проекте болтаются...
---
Согласен, что многое (если не все) непривычно и далеко не всегда очевидно. Но все же решаемо ИМХО :)

avc:
Еще несколько интересных моментов.

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

Сборки, скомпилированные под Net Framework 4.8 и Net8.0 прекрасно дружат между собой. Для меня это была неожиданность, но AutoCAD 2025 прекрасно запустил мою стартовую dll (которая выбирает какую основную библиотеку запускать), хотя она под 4.8. Более того, я сделал библиотеки с общим кодом и общими ресурсами, компилирую под 4.8, а использую во всех плагинах, включая Net8.0. Компилятор прекрасно такую связь съедает и в рантайме тоже проблем нет. Лишь бы в этих общих сборках не было вызовов тех самых "потерянных" классов.

Еще была веселуха с запуском отладчика. В проекте Net8.0 некуда вписать путь запуска AutoCAD. Нагулил, что в меню Отладка появился пункт "Свойства отладки для проекта...". Он открывает секретный диалог "Профили запуска". Но этого мало. Надо еще догадаться, что в этом диалоге нужно создать новый "профиль" и вот только в нем уже можно будет прописать путь к AutoCAD 2025. Настраивается тяжело, но есть и бонус - теперь переключать запускаемый проект можно из панели инструментов VS, а не только из длинного неудобного контекстного меню проекта.

Алексей Кулик:
ИМХО проблема в другом - в ключах запуска acad, насколько я помню, нельзя прописать загрузку dll. И приходится делать scr-файл, который и подсовывать под загрузку

Навигация

[0] Главная страница сообщений

[#] Следующая страница

Перейти к полной версии