Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Prilikom razvoja dodataka za CAD aplikacije (u mom slučaju to su AutoCAD, Revit i Renga) s vremenom se javlja jedan problem - izlaze nove verzije programa, potrebno je napraviti izmjene njihovih API-ja i nove verzije dodataka.

Kada imate samo jedan dodatak ili ste još uvijek samouk početnik u ovoj stvari, možete jednostavno napraviti kopiju projekta, promijeniti potrebna mjesta u njemu i sastaviti novu verziju dodatka. U skladu s tim, naknadne izmjene kodeksa će povući višestruko povećanje troškova rada.

Kako budete stekli iskustvo i znanje, naći ćete nekoliko načina za automatizaciju ovog procesa. Išao sam ovim putem i želim da vam kažem šta sam završio i koliko je to zgodno.

Prvo, pogledajmo metodu koja je očigledna i koju sam dugo koristio.

Veze do projektnih datoteka

A da sve bude jednostavno, vizualno i razumljivo, sve ću opisati koristeći apstraktni primjer razvoja dodataka.

Otvorimo Visual Studio (imam verziju Community 2019. I da - na ruskom) i kreiramo novo rješenje. Hajde da ga pozovemo MySuperPluginForRevit

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Napravit ćemo dodatak za Revit za verzije 2015-2020. Stoga, napravimo novi projekt u rješenju (Net Framework Class Library) i nazovimo ga MySuperPluginForRevit_2015

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Moramo dodati veze na Revit API. Naravno, možemo dodati veze do lokalnih datoteka (trebaćemo da instaliramo sve potrebne SDK-ove ili sve verzije Revit-a), ali ćemo odmah krenuti pravim putem i povezati NuGet paket. Možete pronaći dosta paketa, ali ja ću koristiti svoje.

Nakon povezivanja paketa, desnom tipkom miša kliknite na stavku “reference" i odaberite stavku "Premjestite packages.config u PackageReference...»

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Ako iznenada u ovom trenutku počnete paničariti, jer u prozoru sa svojstvima paketa neće biti važne stavke “Kopirajte lokalno", koju svakako trebamo postaviti na vrijednost lažan, onda bez panike - idite u fasciklu sa projektom, otvorite datoteku sa ekstenzijom .csproj u editoru koji vam odgovara (koristim Notepad++) i tamo pronađite unos o našem paketu. Ona sada izgleda ovako:

<PackageReference Include="ModPlus.Revit.API.2015">
  <Version>1.0.0</Version>
</PackageReference>

Dodajte mu nekretninu runtime. Ispast će ovako:

<PackageReference Include="ModPlus.Revit.API.2015">
  <Version>1.0.0</Version>
  <ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>

Sada, kada pravite projekat, datoteke iz paketa neće biti kopirane u izlaznu fasciklu.
Idemo dalje - zamislimo odmah da će naš dodatak koristiti nešto iz Revit API-ja, koji se vremenom promijenio kada su nove verzije bile objavljene. Pa, ili jednostavno moramo nešto promijeniti u kodu ovisno o verziji Revit-a za koju pravimo dodatak. Da bismo riješili takve razlike u kodu, koristit ćemo simbole za uslovnu kompilaciju. Otvorite svojstva projekta, idite na karticu “Montaža"i na terenu"Notacija uslovne kompilacije"ajde da pišemo R2015.

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Imajte na umu da simbol mora biti dodat i za konfiguracije Debug i Release.

Pa, dok smo u prozoru sa svojstvima, odmah idemo na karticu „Aplikacija"i na terenu"Zadani prostor imena» uklonite sufiks _2015tako da je naš imenski prostor univerzalan i neovisan o nazivu sklopa:

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

U mom slučaju, u konačnom proizvodu, dodaci svih verzija su stavljeni u jedan folder, tako da moji nazivi sklopova ostaju sa sufiksom forme _20hh. Ali također možete ukloniti sufiks iz naziva sklopa ako se datoteke trebaju nalaziti u različitim mapama.

Idemo na kod datoteke Class1.cs i tamo simulirati neki kod, uzimajući u obzir različite verzije Revit-a:

namespace MySuperPluginForRevit
{
    using Autodesk.Revit.Attributes;
    using Autodesk.Revit.DB;
    using Autodesk.Revit.UI;

    [Regeneration(RegenerationOption.Manual)]
    [Transaction(TransactionMode.Manual)]
    public class Class1 : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
#if R2015
            TaskDialog.Show("ModPlus", "Hello Revit 2015");
#elif R2016
            TaskDialog.Show("ModPlus", "Hello Revit 2016");
#elif R2017
            TaskDialog.Show("ModPlus", "Hello Revit 2017");
#elif R2018
            TaskDialog.Show("ModPlus", "Hello Revit 2018");
#elif R2019
            TaskDialog.Show("ModPlus", "Hello Revit 2019");
#elif R2020
            TaskDialog.Show("ModPlus", "Hello Revit 2020");
#endif
            return Result.Succeeded;
        }
    }
}

Odmah sam uzeo u obzir sve verzije Revit-a iznad verzije 2015 (koje su bile dostupne u vrijeme pisanja teksta) i odmah uzeo u obzir prisustvo simbola uslovne kompilacije, koji su kreirani pomoću istog predloška.

Pređimo na glavni naglasak. U našem rješenju kreiramo novi projekat, samo za verziju dodatka za Revit 2016. Ponavljamo sve gore opisane korake, odnosno zamjenjujemo broj 2015 brojem 2016. Ali datoteka Class1.cs izbrisati iz novog projekta.

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Fajl sa potrebnim kodom - Class1.cs – već ga imamo i samo treba da ubacimo link do njega u novi projekat. Postoje dva načina za umetanje linkova:

  1. Dugo – kliknite desnim tasterom miša na projekat i izaberite “dodati»->«Postojeći element", u prozoru koji se otvori pronađite potrebnu datoteku i umjesto opcije "dodati"odaberi opciju"Dodaj kao vezu»

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

  1. Kratak – direktno u istraživaču rješenja odaberite željenu datoteku (ili čak datoteke, ili čak cijele mape) i prevucite je u novi projekt držeći pritisnutu tipku Alt. Dok prevlačite, videćete da kada pritisnete taster Alt, kursor miša će se promeniti iz znaka plus u strelicu.
    UPS: Napravio sam malu zabunu u ovom paragrafu - da biste prenijeli nekoliko datoteka, trebate držati pritisnuto Shift + Alt!

Nakon sprovođenja procedure, imaćemo fajl u drugom projektu Class1.cs sa odgovarajućom ikonom (plava strelica):

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Prilikom uređivanja koda u prozoru uređivača, također možete odabrati u kojem kontekstu projekta želite prikazati kod, što će vam omogućiti da vidite kod koji se uređuje pod različitim simbolima uslovne kompilacije:

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Sve ostale projekte (2017-2020) kreiramo koristeći ovu šemu. Life hack - ako prevučete datoteke u Solution Explorer ne iz osnovnog projekta, već iz projekta gdje su već umetnute kao veza, onda ne morate držati tipku Alt!

Opisana opcija je sasvim dobra do trenutka dodavanja nove verzije dodatka ili do trenutka dodavanja novih datoteka u projekat - sve to postaje jako zamorno. A nedavno sam odjednom odjednom shvatio kako da sve to sredim jednim projektom i prelazimo na drugu metodu

Magija konfiguracija

Kada završite čitanje ovdje, možete uzviknuti: "Zašto ste opisali prvu metodu, ako je članak odmah o drugoj?" I sve sam opisao da bi bilo jasnije zašto su nam potrebni simboli uslovne kompilacije i na kojim mjestima se naši projekti razlikuju. I sada nam postaje jasnije koje tačno razlike u projektima trebamo implementirati, ostavljajući samo jedan projekat.

I da sve bude jasnije, nećemo kreirati novi projekat, već ćemo napraviti izmjene u našem trenutnom projektu kreiranom na prvi način.

Dakle, prije svega uklanjamo sve projekte iz rješenja osim glavnog (koji direktno sadrži datoteke). One. projekti za verzije 2016-2020. Otvorite fasciklu sa rešenjem i tamo izbrišite fascikle ovih projekata.

Ostao nam je još jedan projekat u našoj odluci - MySuperPluginForRevit_2015. Otvorite njegova svojstva i:

  1. Na kartici „Aplikacija"uklonite sufiks iz naziva sklopa _2015 (kasnije će postati jasno zašto)
  2. Na kartici „Montaža» uklonite simbol uslovne kompilacije R2015 iz odgovarajućeg polja

Napomena: najnovija verzija Visual Studio-a ima grešku - simboli uslovne kompilacije se ne prikazuju u prozoru svojstava projekta, iako su dostupni. Ako naiđete na ovaj problem, morate ih ručno ukloniti iz .csproj datoteke. Međutim, još uvijek moramo raditi na tome, pa čitajte dalje.

Preimenujte projekat u prozoru Solution Explorer tako što ćete ukloniti sufiks _2015 a zatim uklonite projekat iz rješenja. Ovo je neophodno za održavanje reda i osjećaja perfekcionista! Otvaramo fasciklu našeg rešenja, preimenujemo fasciklu projekta tamo na isti način i ponovo učitavamo projekat u rešenje.

Otvorite upravitelja konfiguracije. US konfiguracija puštanje u principu neće biti potreban, pa ga brišemo. Kreiramo nove konfiguracije s imenima koja su nam već poznata R2015, R2016,…, R2020. Imajte na umu da ne morate kopirati postavke iz drugih konfiguracija i ne morate kreirati konfiguracije projekta:

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Idite u fasciklu sa projektom i otvorite datoteku sa ekstenzijom .csproj u editoru koji vam odgovara. Usput, možete ga otvoriti i u Visual Studio - potrebno je da skinete projekat i tada će se željena stavka naći u kontekstnom meniju:

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Uređivanje u Visual Studio-u je čak poželjnije, jer uređivač i poravnava i traži.

U datoteci ćemo vidjeti elemente PropertyGroup – na samom vrhu je ono generalno, a onda dolaze uslovi. Ovi elementi postavljaju svojstva projekta kada se gradi. Prvi element, koji je bez uslova, postavlja opšta svojstva, a elementi sa uslovima, shodno tome, menjaju neka svojstva u zavisnosti od konfiguracije.

Idite na zajednički (prvi) element PropertyGroup i pogledaj nekretninu AssemblyName – ovo je naziv skupštine i trebalo bi da ga imamo bez sufiksa _2015. Ako postoji sufiks, uklonite ga.

Pronalaženje elementa sa uslovom

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">

Ne treba nam - brišemo.

Element sa stanjem

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

će biti potrebno za rad u fazi razvoja koda i otklanjanja grešaka. Možete promijeniti njegova svojstva kako bi odgovarala vašim potrebama - postaviti različite izlazne putanje, promijeniti simbole uvjetne kompilacije, itd.

Sada kreirajmo nove elemente PropertyGroup za naše konfiguracije. U ovim elementima samo trebamo postaviti četiri svojstva:

  • OutputPath – izlazni folder. Postavio sam zadanu vrijednost binR20xx
  • DefineConstants – simboli uslovne kompilacije. Vrijednost treba navesti TRACE;R20hh
  • TargetFrameworkVersion – platformska verzija. Različite verzije Revit API-ja zahtijevaju navođenje različitih platformi.
  • AssemblyName – naziv sklopa (tj. naziv datoteke). Možete napisati tačan naziv sklopa, ali radi svestranosti preporučujem da upišete vrijednost $(AssemblyName)_20hh. Da bismo to učinili, prethodno smo uklonili sufiks iz naziva sklopa

Najvažnija karakteristika svih ovih elemenata je da se mogu jednostavno kopirati u druge projekte bez ikakve promjene. Kasnije ću u članku priložiti sav sadržaj .csproj datoteke.

U redu, shvatili smo svojstva projekta - nije teško. Ali šta učiniti sa bibliotekama dodataka (NuGet paketi). Ako pogledamo dalje, vidjet ćemo da su uključene biblioteke specificirane u elementima ItemGroup. Ali loša sreća - ovaj element pogrešno obrađuje uslove kao element PropertyGroup. Možda je ovo čak i greška Visual Studio-a, ali ako navedete nekoliko elemenata ItemGroup sa konfiguracionim uslovima, i ubacite različite veze do NuGet paketa unutra, a zatim kada promenite konfiguraciju, svi navedeni paketi su povezani sa projektom.

Element nam dolazi u pomoć Izabrati, koji radi po našoj uobičajenoj logici ako-onda-drugo.

Korištenje elementa Izabrati, postavljamo različite NuGet pakete za različite konfiguracije:

Svi sadržaji csproj

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0"  ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{5AD738D6-4122-4E76-B865-BE7CE0F6B3EB}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>MySuperPluginForRevit</RootNamespace>
    <AssemblyName>MySuperPluginForRevit</AssemblyName>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <Deterministic>true</Deterministic>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>binDebug</OutputPath>
    <DefineConstants>DEBUG;R2015</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'R2015|AnyCPU' ">
    <OutputPath>binR2015</OutputPath>
    <DefineConstants>TRACE;R2015</DefineConstants>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <AssemblyName>$(AssemblyName)_2015</AssemblyName>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'R2016|AnyCPU' ">
    <OutputPath>binR2016</OutputPath>
    <DefineConstants>TRACE;R2016</DefineConstants>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <AssemblyName>$(AssemblyName)_2016</AssemblyName>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'R2017|AnyCPU' ">
    <OutputPath>binR2017</OutputPath>
    <DefineConstants>TRACE;R2017</DefineConstants>
    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
    <AssemblyName>$(AssemblyName)_2017</AssemblyName>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'R2018|AnyCPU' ">
    <OutputPath>binR2018</OutputPath>
    <DefineConstants>TRACE;R2018</DefineConstants>
    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
    <AssemblyName>$(AssemblyName)_2018</AssemblyName>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'R2019|AnyCPU' ">
    <OutputPath>binR2019</OutputPath>
    <DefineConstants>TRACE;R2019</DefineConstants>
    <TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
    <AssemblyName>$(AssemblyName)_2019</AssemblyName>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'R2020|AnyCPU' ">
    <OutputPath>binR2020</OutputPath>
    <DefineConstants>TRACE;R2020</DefineConstants>
    <TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
    <AssemblyName>$(AssemblyName)_2020</AssemblyName>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Class1.cs" />
    <Compile Include="PropertiesAssemblyInfo.cs" />
  </ItemGroup>
  <Choose>
    <When Condition=" '$(Configuration)'=='R2015' ">
      <ItemGroup>
        <PackageReference Include="ModPlus.Revit.API.2015">
          <Version>1.0.0</Version>
          <ExcludeAssets>runtime</ExcludeAssets>
        </PackageReference>
      </ItemGroup>
    </When>
    <When Condition=" '$(Configuration)'=='R2016' ">
      <ItemGroup>
        <PackageReference Include="ModPlus.Revit.API.2016">
          <Version>1.0.0</Version>
          <ExcludeAssets>runtime</ExcludeAssets>
        </PackageReference>
      </ItemGroup>
    </When>
    <When Condition=" '$(Configuration)'=='R2017' ">
      <ItemGroup>
        <PackageReference Include="ModPlus.Revit.API.2017">
          <Version>1.0.0</Version>
          <ExcludeAssets>runtime</ExcludeAssets>
        </PackageReference>
      </ItemGroup>
    </When>
    <When Condition=" '$(Configuration)'=='R2018' ">
      <ItemGroup>
        <PackageReference Include="ModPlus.Revit.API.2018">
          <Version>1.0.0</Version>
          <ExcludeAssets>runtime</ExcludeAssets>
        </PackageReference>
      </ItemGroup>
    </When>
    <When Condition=" '$(Configuration)'=='R2019' ">
      <ItemGroup>
        <PackageReference Include="ModPlus.Revit.API.2019">
          <Version>1.0.0</Version>
          <ExcludeAssets>runtime</ExcludeAssets>
        </PackageReference>
      </ItemGroup>
    </When>
    <When Condition=" '$(Configuration)'=='R2020' or '$(Configuration)'=='Debug'">
      <ItemGroup>
        <PackageReference Include="ModPlus.Revit.API.2020">
          <Version>1.0.0</Version>
          <ExcludeAssets>runtime</ExcludeAssets>
        </PackageReference>
      </ItemGroup>
    </When>
  </Choose>
  <Import Project="$(MSBuildToolsPath)Microsoft.CSharp.targets" />
</Project>

Napominjemo da sam u jednom od uvjeta naveo dvije konfiguracije preko ILI. Na ovaj način će potrebni paket biti povezan tokom konfiguracije otkloniti neispravnost.

I ovdje imamo skoro sve savršeno. Učitavamo projekat nazad, omogućavamo konfiguraciju koja nam je potrebna, pozivamo stavku " u kontekstualnom meniju rešenja (ne projekta)Vratite sve NuGet pakete“i vidimo kako se naši paketi mijenjaju.

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

I u ovoj fazi sam došao u ćorsokak - da bismo prikupili sve konfiguracije odjednom, mogli bismo koristiti skupni sklop (meni "Montaža»->«Batch build"), ali prilikom promjene konfiguracije, paketi se ne vraćaju automatski. A prilikom sklapanja projekta to se također ne događa, iako bi u teoriji trebalo. Nisam našao rješenje za ovaj problem standardnim sredstvima. I najvjerovatnije je ovo također greška Visual Studio-a.

Stoga je za serijsku montažu odlučeno da se koristi poseban automatizirani sistem montaže Nuke. Zapravo nisam želio ovo jer mislim da je to previše u smislu razvoja dodataka, ali trenutno ne vidim drugo rješenje. I na pitanje "Zašto Nuke?" Odgovor je jednostavan - koristimo ga na poslu.

Dakle, idite na mapu našeg rješenja (ne projekta), držite tipku smjena i kliknite desnim tasterom miša na prazan prostor u fascikli - u kontekstnom meniju izaberite stavku “Otvorite prozor PowerShell ovdje".

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Ako ga nemate instaliran nuke, zatim prvo napišite naredbu

dotnet tool install Nuke.GlobalTool –global

Sada napišite naredbu nuke i od vas će biti zatraženo da konfigurišete nuke za trenutni projekat. Ne znam kako to ispravnije napisati na ruskom - na engleskom će biti napisano Ne mogu pronaći .nuke fajl. Želite li postaviti build? [y/n]

Pritisnite tipku Y i dalje će biti direktnih postavki. Potrebna nam je najjednostavnija opcija za korištenje MSBuild, pa odgovaramo kao na snimku ekrana:

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Idemo u Visual Studio, koji će nas upitati da ponovo učitamo rješenje, budući da mu je dodat novi projekat. Ponovno učitavamo rješenje i vidimo da imamo projekat graditi u kojem nas zanima samo jedan fajl - Build.cs

Izrađujemo jedan plugin projekat sa kompilacijom za različite verzije Revit/AutoCAD-a

Otvorite ovu datoteku i napišite skriptu za izradu projekta za sve konfiguracije. Pa, ili koristite moju skriptu, koju možete urediti kako bi odgovarala vašim potrebama:

using System.IO;
using Nuke.Common;
using Nuke.Common.Execution;
using Nuke.Common.ProjectModel;
using Nuke.Common.Tools.MSBuild;
using static Nuke.Common.Tools.MSBuild.MSBuildTasks;

[CheckBuildProjectConfigurations]
[UnsetVisualStudioEnvironmentVariables]
class Build : NukeBuild
{
    public static int Main () => Execute<Build>(x => x.Compile);

    [Solution] readonly Solution Solution;

    // If the solution name and the project (plugin) name are different, then indicate the project (plugin) name here
    string PluginName => Solution.Name;

    Target Compile => _ => _
        .Executes(() =>
        {
            var project = Solution.GetProject(PluginName);
            if (project == null)
                throw new FileNotFoundException("Not found!");

            var build = new List<string>();
            foreach (var (_, c) in project.Configurations)
            {
                var configuration = c.Split("|")[0];

                if (configuration == "Debug" || build.Contains(configuration))
                    continue;

                Logger.Normal($"Configuration: {configuration}");

                build.Add(configuration);

                MSBuild(_ => _
                    .SetProjectFile(project.Path)
                    .SetConfiguration(configuration)
                    .SetTargets("Restore"));
                MSBuild(_ => _
                    .SetProjectFile(project.Path)
                    .SetConfiguration(configuration)
                    .SetTargets("Rebuild"));
            }
        });
}

Vraćamo se u prozor PowerShell i ponovo pišemo naredbu nuke (možete napisati naredbu nuke ukazujući na potrebno meta. Ali imamo jednu meta, koji se pokreće prema zadanim postavkama). Nakon pritiska na tipku Enter osjećat ćemo se kao pravi hakeri, jer će, kao u filmu, naš projekat biti automatski sastavljen za različite konfiguracije.

Usput, PowerShell možete koristiti direktno iz Visual Studija (meni "Pogled»->«Ostali prozori»->«Package Manager Console"), ali sve će biti crno-bijelo, što nije baš zgodno.

Ovim završavam moj članak. Siguran sam da možete sami da smislite opciju za AutoCAD. Nadam se da će materijal koji je ovdje predstavljen pronaći svoje „klijente“.

Spasibo za vnimanie!

izvor: www.habr.com

Dodajte komentar