Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

CAD rakenduste jaoks pistikprogrammide (minu puhul need on AutoCAD, Revit ja Renga) aja jooksul ilmneb üks probleem - programmide uued versioonid ilmuvad, nende API muudatused ja pluginate uued versioonid on vaja teha.

Kui teil on ainult üks pistikprogramm või olete selles küsimuses alles iseõppinud algaja, saate lihtsalt teha projektist koopia, muuta selles vajalikke kohti ja koostada pistikprogrammi uus versioon. Sellest tulenevalt toovad koodi hilisemad muudatused kaasa tööjõukulude mitmekordse suurenemise.

Kogemuste ja teadmiste omandamisel leiate mitmeid viise selle protsessi automatiseerimiseks. Kõndisin seda teed ja tahan teile rääkida, milleni ma jõudsin ja kui mugav see on.

Kõigepealt vaatame meetodit, mis on ilmselge ja mida olen pikka aega kasutanud.

Lingid projektifailidele

Ja et kõik oleks lihtne, visuaalne ja arusaadav, kirjeldan kõike, kasutades plugina arendamise abstraktset näidet.

Avame Visual Studio (mul on Community 2019 versioon. Ja jah – vene keeles) ja loome uue lahenduse. Helistame talle MySuperPluginForRevit

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Valmistame Reviti pistikprogrammi versioonide 2015–2020 jaoks. Seetõttu loome lahenduses (Net Framework Class Library) uue projekti ja nimetame selle MySuperPluginForRevit_2015

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Peame lisama lingid Revit API-le. Loomulikult saame lisada linke kohalikele failidele (peame installima kõik vajalikud SDK-d või kõik Reviti versioonid), kuid läheme kohe õiget teed ja ühendame NuGeti paketi. Pakendeid leiab päris mitu, aga kasutan enda oma.

Pärast paketi ühendamist paremklõpsake üksusel "Viited"ja valige üksus"Teisalda paketid.config kausta PackageReference...»

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Kui äkki hakkate sel hetkel paanikasse sattuma, sest paketi atribuutide aknas pole olulist elementi "Kopeerige kohapeal", mille väärtust peame kindlasti määrama vale, siis ärge paanitsege - minge projektiga kausta, avage .csproj laiendiga fail teile sobivas redaktoris (kasutan Notepad++) ja leidke sealt kirje meie paketi kohta. Ta näeb praegu välja selline:

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

Lisage sellele atribuut käitusaeg. See selgub järgmiselt:

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

Nüüd projekti koostamisel paketist faile väljundkausta ei kopeerita.
Lähme edasi – kujutame kohe ette, et meie plugin hakkab kasutama midagi Revit API-st, mis on uute versioonide ilmumisel aja jooksul muutunud. Noh, või peame lihtsalt koodis midagi muutma, olenevalt Reviti versioonist, mille jaoks pistikprogrammi loome. Selliste koodierinevuste lahendamiseks kasutame tingimusliku kompileerimise sümboleid. Avage projekti atribuudid, minge vahekaardile "Assamblee"ja põllul"Tingimuslik koostamise tähistus"kirjutame R2015.

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Pange tähele, et sümbol tuleb lisada nii silumise kui ka väljalaske konfiguratsioonide jaoks.

Noh, kui oleme atribuutide aknas, läheme kohe vahekaardile "Taotlus"ja põllul"Vaikenimeruum» eemaldage järelliide _2015nii et meie nimeruum oleks universaalne ja koostunimest sõltumatu:

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Minu puhul pannakse lõpptootes kõigi versioonide pluginad ühte kausta, nii et minu koostenimed jäävad vormi järelliidese _20хх. Kui failid peaksid asuma erinevates kaustades, saate aga ka koostunimest järelliite eemaldada.

Läheme faili koodi juurde Klass1.cs ja simuleerida seal mõnda koodi, võttes arvesse Reviti erinevaid versioone:

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;
        }
    }
}

Võtsin kohe arvesse kõiki Reviti versioone, mis olid üle 2015. aasta versiooni (mis olid selle kirjutamise ajal saadaval) ja võtsin kohe arvesse tingimuslike kompileerimissümbolite olemasolu, mis luuakse sama malli abil.

Liigume edasi peamise esiletõstmise juurde. Loome oma lahenduses uue projekti, ainult Revit 2016 plugina versiooni jaoks. Korrame vastavalt kõiki ülalkirjeldatud samme, asendades numbri 2015 numbriga 2016. Kuid fail Klass1.cs uuest projektist kustutada.

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Fail nõutava koodiga - Klass1.cs – meil on see juba olemas ja peame lihtsalt uude projekti lisama selle lingi. Linkide sisestamiseks on kaks võimalust:

  1. Pikk - paremklõpsake projektil ja valige "Lisama»->«Olemasolev element", leidke avanevas aknas vajalik fail ja valiku" asemelLisama"vali valik"Lisa ühendusena»

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

  1. Lühike – otse lahenduseuurijas valige soovitud fail (või isegi failid või isegi terved kaustad) ja lohistage see uude projekti, hoides all klahvi Alt. Lohistes näete, et kui vajutate klahvi Alt, muutub hiirekursor plussmärgist nooleks.
    UPD: Tegin selles lõigus väikese segaduse – mitme faili ülekandmiseks peaksite all hoidma Tõstuklahv + Alt!

Pärast protseduuri läbiviimist on meil teises projektis toimik Klass1.cs vastava ikooniga (sinine nool):

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Redigeerijaaknas koodi redigeerimisel saate valida ka, millises projekti kontekstis koodi kuvada, mis võimaldab näha redigeeritavat koodi erinevate tingimuslike kompileerimissümbolite all:

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Kõik teised projektid (2017-2020) loome seda skeemi kasutades. Life hack - kui lohistate Solution Exploreris faile mitte põhiprojektist, vaid projektist, kuhu need on juba lingina sisestatud, ei pea te klahvi Alt all hoidma!

Kirjeldatud variant on päris hea kuni pistikprogrammi uue versiooni lisamise hetkeni või kuni projekti uute failide lisamiseni – see kõik muutub väga tüütuks. Ja hiljuti mõistsin järsku, kuidas seda kõike ühe projektiga lahendada, ja liigume teise meetodi juurde

Konfiguratsioonide maagia

Kui olete siin lugemise lõpetanud, võite hüüda: "Miks te kirjeldasite esimest meetodit, kui artikkel räägib kohe teisest?!" Ja kirjeldasin kõike, et oleks arusaadavam, miks me vajame tingimusliku koostamise sümboleid ja millistes kohtades meie projektid erinevad. Ja nüüd saab meile täpselt selgeks, milliseid erinevusi projektides peame ellu viima, jättes alles vaid ühe projekti.

Ja et kõik oleks arusaadavam, ei loo me uut projekti, vaid teeme muudatusi oma praeguses esimesel viisil loodud projektis.

Nii et kõigepealt eemaldame lahendusest kõik projektid peale peamise (sisaldab faile otse). Need. projektid versioonidele 2016–2020. Ava lahendusega kaust ja kustuta seal nende projektide kaustad.

Meie otsuses on jäänud üks projekt - MySuperPluginForRevit_2015. Avage selle omadused ja:

  1. Vahekaardil "Taotlus"eemaldage kooste nimest järelliide _2015 (Hiljem selgub miks)
  2. Vahekaardil "Assamblee» eemaldage tingimusliku kompileerimise sümbol R2015 vastavast väljast

Märkus: Visual Studio uusimas versioonis on viga – tingimusliku kompileerimise sümboleid ei kuvata projekti atribuutide aknas, kuigi need on saadaval. Kui teil tekib see tõrge, peate need failist .csproj käsitsi eemaldama. Siiski peame sellega veel tööd tegema, nii et lugege edasi.

Nimetage projekt aknas Solution Explorer ümber, eemaldades järelliide _2015 ja seejärel eemaldage projekt lahendusest. See on vajalik korra ja perfektsionistide tunnete säilitamiseks! Ava meie lahenduse kaust, nimeta seal samamoodi projekti kaust ümber ja laadi projekt tagasi lahendusse.

Avage konfiguratsioonihaldur. USA konfiguratsioon Vabastage põhimõtteliselt pole seda vaja, seega kustutame selle. Loome uusi konfiguratsioone meile juba tuttavate nimedega R2015, R2016, ... R2020. Pange tähele, et te ei pea sätteid teistest konfiguratsioonidest kopeerima ega projekti konfiguratsioone looma:

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Minge projektiga kausta ja avage .csproj laiendiga fail teile sobivas redaktoris. Muide, saate selle avada ka Visual Studios - peate projekti maha laadima ja siis on soovitud üksus kontekstimenüüs:

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Redigeerimine Visual Studios on isegi eelistatavam, kuna redaktor nii joodab kui ka küsib.

Failis näeme elemente PropertyGroup – kõige tipus on üldine ja siis tulevad tingimused. Need elemendid määravad projekti omadused selle ehitamisel. Esimene element, mis on ilma tingimusteta, määrab üldised omadused ja tingimustega elemendid muudavad vastavalt konfiguratsioonidest mõningaid omadusi.

Minge ühise (esimese) elemendi juurde PropertyGroup ja vaata vara üle AssemblyName – see on koostu nimi ja see peaks olema ilma järelliideta _2015. Kui on järelliide, eemaldage see.

Tingimusega elemendi leidmine

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

Meil pole seda vaja – me kustutame selle.

Tingimusega element

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

on vaja koodi arendamise ja silumise etapis töötamiseks. Saate muuta selle omadusi vastavalt oma vajadustele – määrata erinevaid väljundteid, muuta tingimusliku kompileerimise sümboleid jne.

Nüüd loome uusi elemente PropertyGroup meie konfiguratsioonide jaoks. Nendes elementides peame lihtsalt määrama neli atribuuti:

  • Väljundtee - väljundkaust. Määrasin vaikeväärtuse binR20xx
  • DefineConstants – tingimusliku kompileerimise sümbolid. Väärtus tuleks täpsustada TRACE;R20хх
  • TargetFrameworkVersion - platvormi versioon. Revit API erinevad versioonid nõuavad erinevate platvormide määramist.
  • AssemblyName – koostu nimi (st faili nimi). Võite kirjutada koostu täpse nime, kuid mitmekülgsuse huvides soovitan kirjutada väärtuse $(AssemblyName)_20хх. Selleks eemaldasime eelnevalt koostenimest järelliide

Kõigi nende elementide kõige olulisem omadus on see, et neid saab lihtsalt kopeerida teistesse projektidesse ilma neid üldse muutmata. Hiljem lisan artiklis kogu .csproj-faili sisu.

Olgu, oleme projekti omadused välja mõelnud – see pole keeruline. Aga mida teha pistikprogrammide raamatukogudega (NuGeti paketid). Kui vaatame kaugemale, näeme, et kaasatud teegid on elementides täpsustatud Kaubarühm. Kuid halb õnn - see element töötleb tingimusi elemendina valesti PropertyGroup. Võib-olla on see isegi Visual Studio tõrge, kuid kui määrate mitu elementi Kaubarühm konfiguratsioonitingimustega ja sisestage sisse erinevad lingid NuGeti pakettidele, siis konfiguratsiooni muutmisel ühendatakse kõik määratud paketid projektiga.

Element tuleb meile appi Vali, mis töötab meie tavapärase loogika kohaselt kui-siis-veel.

Elemendi kasutamine Vali, määrasime erinevatele konfiguratsioonidele erinevad NuGeti paketid:

Kogu sisu 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>

Pange tähele, et ühes tingimustes määrasin kaks konfiguratsiooni kaudu VÕI. Nii ühendatakse vajalik pakett seadistamise käigus siluda.

Ja siin on meil peaaegu kõik täiuslik. Laadime projekti tagasi, lubame vajaliku konfiguratsiooni, kutsume lahenduse (mitte projekti) kontekstimenüüs üksuse “Taastage kõik NuGeti paketid"ja me näeme, kuidas meie paketid muutuvad.

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Ja selles etapis jõudsin ummikusse - kõigi konfiguratsioonide korraga kogumiseks saime kasutada partii kokkupanekut (menüü "Assamblee»->«Partii ehitamine"), kuid konfiguratsioonide vahetamisel pakette automaatselt ei taastata. Ja projekti kokkupanemisel ka seda ei juhtu, kuigi teoreetiliselt peaks see nii minema. Ma ei ole standardsete vahenditega sellele probleemile lahendust leidnud. Ja tõenäoliselt on see ka Visual Studio viga.

Seetõttu otsustati partii kokkupanekuks kasutada spetsiaalset automatiseeritud montaažisüsteemi Nuke. Ma tegelikult ei tahtnud seda, sest arvan, et see on pistikprogrammide arendamise seisukohalt liialdatud, kuid hetkel ma muud lahendust ei näe. Ja küsimusele "Miks Nuke?" Vastus on lihtne – me kasutame seda tööl.

Niisiis, minge meie lahenduse (mitte projekti) kausta, hoidke klahvi all nihe ja paremklõpsake kausta tühjal alal - valige kontekstimenüüst üksus "Ava PowerShelli aken siin'.

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Kui teil pole seda installitud nuke, seejärel kirjutage esmalt käsk

dotnet tool install Nuke.GlobalTool –global

Nüüd kirjutage käsk nuke ja teil palutakse konfigureerida nuke praeguse projekti jaoks. Ma ei tea, kuidas seda vene keeles õigemini kirjutada - inglise keeles kirjutatakse. Nuke faili ei leitud. Kas soovite konstruktsiooni seadistada? [ja/n]

Vajutage klahvi Y ja seejärel kuvatakse otsesätete üksused. Vajame lihtsaimat võimalust MSBuild, seega vastame nagu ekraanipildil:

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Läheme Visual Studiosse, mis palub meil lahendus uuesti laadida, kuna sellele on lisatud uus projekt. Laadime lahenduse uuesti ja näeme, et meil on projekt olemas ehitama milles meid huvitab ainult üks fail - Build.cs

Teeme ühe pluginaprojekti koos kompileerimisega Revit/AutoCAD erinevatele versioonidele

Avage see fail ja kirjutage kõigi konfiguratsioonide jaoks projekti koostamiseks skript. Noh, või kasutage minu skripti, mida saate oma vajaduste järgi muuta:

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"));
            }
        });
}

Naaseme PowerShelli aknasse ja kirjutame käsu uuesti nuke (võite kirjutada käsu nuke märkides nõutava sihtmärk. Aga meil on üks sihtmärk, mis töötab vaikimisi). Pärast sisestusklahvi vajutamist tunneme end tõeliste häkkeritena, sest nagu filmis, komplekteeritakse meie projekt automaatselt erinevate konfiguratsioonide jaoks.

Muide, saate PowerShelli kasutada otse Visual Studiost (menüü "Vaata»->«Muud aknad»->«Paketihalduri konsool"), kuid kõik on must-valge, mis pole eriti mugav.

Sellega minu artikkel lõpetatakse. Olen kindel, et saate AutoCADi valiku ise välja mõelda. Loodan, et siin esitatud materjal leiab oma “kliendid”.

Tänan teid tähelepanu eest!

Allikas: www.habr.com

Lisa kommentaar