
CAD rakenduste pistikute arendamisel ( on see AutoCAD, Revit ja Renga) tekib aja jooksul ĂŒks probleem â ilmuvad uued programmid, muutub nende API ja tuleb teha uusi pistikute versioone.
Kui teil on vaid ĂŒks pistik vĂ”i olete selles osas veel algaja-isetegija, siis saate lihtsalt projekti koopia teha, muuta vajalikud kohad ja koostada pistiku uus versioon. Vastavalt sellele toob edasine koodimuudatus endaga kaasa tööjĂ”u mĂ€rgatava suurenemise.
Kogemuste ja teadmiste kogunemise kÀigus leiate mitu viisi selle protsessi automatiseerimiseks. Olen lÀbinud selle tee ja tahan teile rÀÀkida, kuhu ma lÔpuks jÔudsin ja kui mugav see on.
Alustame viisist, mis on ilmselge ja millega ma pikka aega kasutasin
Lingid projekti failidele
Ja et kÔik oleks lihtne, arusaadav ja selge, kirjeldan kÔike abstraktses nÀites pistiku arendamisest.
Avame Visual Studio (mul on versioon Community 2019. Ja jah â vene keeles) ja loome uue lahenduse. Nimeks anname MySuperPluginForRevit

Me loome Revitile plugina versioonide 2015-2020 jaoks. SeetÔttu loon lahendusse uue projekti (Net Frameworki klasside raamatukogu) ja nimetame selle MySuperPluginForRevit_2015

Peame lisama viiteid Revit API-le. Muidugi vĂ”ime lisada viiteid lokaalsetele failidele (kuna peab endale installima kĂ”ik vajalikud SDK-d vĂ”i kĂ”ik Revit versioonid), kuid me lĂ€heme kohe Ă”iget teed ja ĂŒhendame NuGet-paketi. VĂ”ite leida mitmeid pakette, kuid mina kasutan oma omi.
PĂ€rast paketi ĂŒhendamist klĂ”psake paremklĂ”psuga punktile «Lingid» ja valige menĂŒĂŒs punkt «Kanda packages.config ĂŒle PackageReferenceâŠÂ»

Kui Ă€kki hakkab selles kohas teil paanikahoog, kuna paketi omaduste aknas ei ole olulist punkti «Kopeeri lokaalselt», mille me peame kindlasti seadistama vÀÀrtuseks false, siis ei tasu paanikasse minna â lĂ€heme projekti kausta, avame .csproj laiendiga faili mugavas redigeerijas (mina kasutan Notepad++) ja otsime sealt ĂŒles kirje oma paketi kohta. See nĂ€eb praegu vĂ€lja nii:
1.0.0Lisame sellele omaduse runtime. Tuleb vÀlja nii:
1.0.0
runtimeNĂŒĂŒd, kui projekt on loodud, ei kopeerita paketi faile vĂ€ljundkausta.
JĂ€tkame â eeldame kohe, et meie plugin kasutab midagi Revit API-st, mis on aja jooksul uute versioonide vĂ€ljalaskmisega muutunud. VĂ”i lihtsalt peame koodis midagi oma versiooni Revit-i jĂ€rgi muutma, millele me plugina teeme. Selliste koodierinevuste lahendamiseks kasutame tingimuslikke kompileerimissĂŒmboleid. Avame projekti omadused, lĂ€heme vahekaardile âKoostamineâ ja kirjutame vĂ€ljadele âTingimusliku kompileerimise sĂŒmbolidâ R2015.

Pange tĂ€hele, et sĂŒmbol tuleb lisada nii Debug- kui ka Release-konfiguratsioonide jaoks.
Ja kuni oleme omaduste aknas, liigume kohe vahekaardile âRakendusâ ja kirjutame vĂ€ljadele âVaikimisi nimespatsioonâ ja eemaldame suffiksi _2015, et meie nimespatsioon oleks universaalne ja sĂ”ltumatu kogumi nimest:

Minu puhul kogunevad lĂ”ppproduktis pluginaid kĂ”igis versioonides ĂŒhte kausta, seega jÀÀvad minu koguse nimed suffiksiga nagu _20xx. Kuid saate lisandmooduli nimest sufiksi eemaldada, kui failide asukoht on erinevatesse kaustadesse jagatud.
Liigume faili koodi juurde Class1.cs ja simuleerime seal mingit koodi, arvestades erinevaid Revit 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", "Tere, Revit 2015");
#elif R2016
TaskDialog.Show("ModPlus", "Tere, Revit 2016");
#elif R2017
TaskDialog.Show("ModPlus", "Tere, Revit 2017");
#elif R2018
TaskDialog.Show("ModPlus", "Tere, Revit 2018");
#elif R2019
TaskDialog.Show("ModPlus", "Tere, Revit 2019");
#elif R2020
TaskDialog.Show("ModPlus", "Tere, Revit 2020");
#endif
return Result.Succeeded;
}
}
}Arvestasin kohe kĂ”iki Revit versioone, mis olid kĂ”rgemad kui 2015 (mis olid artikli kirjutamise ajal olemas) ja arvestasin kohe ka tingimuslike kompileerimise sĂŒmbolite olemasolu, mis mul luuakse sama malli alusel.
Liigume pearikka saanud osani. Loome meie lahenduses uue projekti, kuid seekord Revit 2016 plugina versioonile. Korrame eelnevaid samme, asendades numbrit 2015 numbriga 2016. Kuid faili Class1.cs uusest projektist kustutame.

Fail, mille on vajalik kood â Class1.cs â on meil juba olemas ja peame lihtsalt sellele uues projektis linki lisama. Linkide lisamiseks on kaks vĂ”imalust:
- Pikk â klikime projektile hiire parema nupuga, valime punkti âLisaâ -> âOlemasolev elementâ, avaneb aknas vajaliku faili leidmiseks ja valime âLisaâ asemel valiku âLisa lingina»

- LĂŒhike â otse lahenduste avajas valime vajaliku faili (vĂ”i isegi failid. VĂ”ib isegi terveid kaustu) ja lohistame uuele projekti, hoides all klahvi Alt. Loendamisel nĂ€ete, et Alt-klahvi all hoides muutub hiire kursor plussilt nooleks.
UPD: Ma tegin selles lĂ”igus veidi segadust â mitu faili ĂŒle kandmiseks tuleks hoida all Shift+Alt!
PÀrast protseduuri lÀbiviimist on meil teises projektis fail Class1.cs vastava ikooniga (sinine nool):

Koodi redigeerimise ajal redigeerimisaknas saate samuti valida, millises projekti kontekstis koodi kuvada, mis vĂ”imaldab teil nĂ€ha koodi redigeerida erinevate tingimuslike kompileerimise sĂŒmbolite korral:

Selle skeemi abil loome kĂ”ik teised projektid (2017-2020). Elu pettus â kui lohistate faile lahenduste vaatjas mitte pĂ”hprojekti, vaid projektist, kus need on juba sidemena lisatud, ei pea Alt-klahvi all hoidma!
Kirjeldatud variant on tĂ€iesti hea, kuni lisatakse uus plugina versioon vĂ”i lisatakse projekti uusi faile â see kĂ”ik muutub vĂ€ga vaevaseks. Ja hiljuti taipasin, kuidas seda kĂ”ike ĂŒhe projektiga kenasti lahendada, ning liigume teise meetodi juurde.
Konfiguratsiooni maagia
Siia lugedes vĂ”ite hĂŒĂŒda: "Miks sa esimest meetodit kirjeldasid, kui artikkel rÀÀgib kohe teisest?!" Ja kirjutasin kĂ”ik selleks, et oleks selgem, miks meil on vaja tingimusliku kompileerimise sĂŒmboleid ja millistes kohtades meie projektid erinevad. NĂŒĂŒd on selgem, millised tĂ€psed erinevused projektides tuleb ellu viia, jĂ€ttes vaid ĂŒhe projekti.
Ja et kÔik oleks selgem, ei loo me uut projekti, vaid teeme muudatused meie praeguses projektis, mis loodi esimese meetodi abil.
Esiteks eemaldame lahendusest kĂ”ik projektid peale peamise (millel on otseselt failid). St projektid aastatest 2016â2020. Avame lahenduse kausta ja eemaldame seal nende projektide kaustad.
Meie lahenduses on jÀÀnud alles ĂŒks projekt â MySuperPluginForRevit_2015. Avame tema omadused ja:
- Vahekaardil "Rakendus" eemaldame kogumi nimest suffiksi _2015 (edasi saab selgeks, miks)
- Vahekaardil "Koostamine" eemaldame tingimusliku kompileerimise sĂŒmboli R2015 vastavast vĂ€ljast
MĂ€rkus: viimasel versioonil Visual Studio's on tĂ”rge â tingimusliku kompileerimise sĂŒmbolid ei kuvata projekti omaduste aknas, kuigi need on olemas. Kui see tĂ”rge Teil esineb, peaksite need kĂ€sitsi .csproj failist eemaldama. Kuid me peame sellega edasi tegutsema, seega loeme edasi.
Nimeta projekt lahenduse aknas ĂŒmber, eemaldades suffiksi _2015 ja seejĂ€rel eemaldame projekti lahendusest. See on vajalik korrashoiu ja perfektsionistide tunnete sĂ€ilitamiseks! Avame meie lahenduse kausta, nimeta projektikaust seal sama moodi ĂŒmber ja laadime projekti tagasi lahendusse.
Avame konfiguratsioonihalduri. Meile on vajalik konfiguratsioon Release pĂ”himĂ”tteliselt ei ole vajalik, seega kustutame selle. Loome uued konfiguratsioonid juba tuttavate nimedega. R2015, R2016, âŠ, R2020. Pange tĂ€hele, et ei ole vaja kopeerida parameetreid teistest konfiguratsioonidest ega luua projekti konfiguratsioone:

Liigume projekti kausta ja avame .csproj laiendiga faili meelepĂ€rases redigeerijas. Muide, seda saab avada ka Visual Studio's â tuleb projekt lahti laadida ja kontekstimenĂŒĂŒs on vajalik punkt:

Redigeerimine Visual Studios on isegi eelistatavam, kuna redaktor joondab ja annab vihjeid.
Failis nĂ€eme elemente â ĂŒlemine element on ĂŒldine ja seejĂ€rel tingimustega. Need elemendid mÀÀravad projekti omadused selle kompileerimisel. Esimene element, mis on tingimusteta, mÀÀrab ĂŒldised omadused, samas kui tingimustega elemendid muudavad vastavalt mĂ”ningaid omadusi sĂ”ltuvalt konfiguratsioonidest.
Liigume ĂŒldise (esimese) elemendi juurde PropertyGroup ja vaatame omadust AssemblyName â see on kogumi nimi ja see peaks olema meil ilma sufiksita _2015. Kui sufiks on olemas, siis kustutame selle.
Otsime tingimusega elementi
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">See ei ole meile vajalik â kustutame selle.
Element tingimusega
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">on vajalik koodi arendamise ja silumise faasis. Saate muuta selle omadusi vastavalt oma vajadustele â seadistada erinevaid vĂ€ljundite teid, muuta tingimusliku kompileerimise sĂŒmboleid jne.
NĂŒĂŒd loome uusi elemente PropertyGroup meie konfiguratsioonide jaoks. Nendes elementides peame kĂ”ige olulisemad neli omadust seadistama:
- OutputPath â vĂ€ljundkaust. MÀÀran standardvÀÀrtuse binR20xx
- DefineConstants â tingimusliku kompileerimise sĂŒmbolid. Tuleb mÀÀrata vÀÀrtus TRACE;R20Ń Ń
- TargetFrameworkVersion â platvormi versioon. Erinevate Revit API versioonide jaoks tuleb mÀÀrata erinevad platvormid.
- AssemblyName â kogumi nimi (st faili nimi). Saate kirjutada otse vajaliku kogumi nime, kuid universaalsuse huvides soovitan kirjutada vÀÀrtus $(AssemblyName)_20Ń Ń . Selleks eemaldasime varem kogumi nimest sufiksi
KÔige tÀhtsam funktsioon nende elementide puhul on see, et neid saab lihtsalt kopeerida teistesse projektidesse, ilma et neid tuleks muuta. JÀrgmises artiklis lisatakse kÔik .csproj faili sisu.
Nii, projekti omadused on selged â see ei ole keeruline. Aga kuidas on asjadega, mis puudutavad lisakogusid (NuGet paketid)? Edasi liikudes nĂ€eme, et lisakogused mÀÀratakse elementides. . Kuid siin on probleem â see element töötleb tingimusi valesti nagu element. PropertyGroup. See vĂ”ib olla isegi Visual Studio viga, kuid kui mÀÀrata mitu elementi ItemGroup konfiguratsiooni tingimustega ja lisada sisse erinevad viidatud NuGet paketid, siis konfiguratsiooni muutmisel ĂŒhendatakse projekti kĂ”ik mÀÀratud paketid.
Meie appi tuleb element , mis töötab tuttava loogika alusel. if-then-else.
Kasutan elementi Valige, et mÀÀrata erinevad NuGet paketid erinevate konfiguratsioonide jaoks:
Kogu sisu csproj
Debug
AnyCPU
{5AD738D6-4122-4E76-B865-BE7CE0F6B3EB}
Library
Properties
MySuperPluginForRevit
MySuperPluginForRevit
v4.5
512
true
true
full
false
binDebug
DEBUG;R2015
prompt
4
binR2015
TRACE;R2015
v4.5
$(AssemblyName)_2015
binR2016
TRACE;R2016
v4.5
$(AssemblyName)_2016
binR2017
TRACE;R2017
v4.5.2
$(AssemblyName)_2017
binR2018
TRACE;R2018
v4.5.2
$(AssemblyName)_2018
binR2019
TRACE;R2019
v4.7
$(AssemblyName)_2019
binR2020
TRACE;R2020
v4.7
$(AssemblyName)_2020
1.0.0
runtime
1.0.0
runtime
1.0.0
runtime
1.0.0
runtime
1.0.0
runtime
1.0.0
runtimePange tĂ€hele, et ĂŒhes tingimusest olen ma mÀÀranud kaks konfiguratsiooni lĂ€bi VĂI (Or). Seega ĂŒhendatakse vajalik pakett konfiguratsiooni puhul Debug.
Ja nĂŒĂŒd on meil peaaegu kĂ”ik ideaalne. Laeme projekti tagasi, aktiveerime vajaliku konfiguratsiooni, valime kontekstimenĂŒĂŒst (mitte projekti) punkti âTaasta kĂ”ik NuGet paketidâ ja nĂ€eme, kuidas meie paketid muutuvad.

Ja nĂŒĂŒd olen ma selle etapi juures ummikseisus â et koguda kĂ”ik konfiguratsioonid, vĂ”iksime kasutada paketihaldust (menĂŒĂŒ âKoostamineâ -> âPaketihaldusâ), kuid konfiguratsioonide vahetamisel ei toimu automaatset taastamist. Samuti ei toimu projektide kogumisel, kuigi peaks. Standardsete vahendite abil ei ole ma selle probleemi lahendust leidnud. Ja tĂ”enĂ€oliselt on see ka Visual Studio tĂ”rge.
SeetĂ”ttu oli paketihalduses otsustatud kasutada spetsiaalset automatiseeritud kogumissĂŒsteemi . Tegelikult ei tahtnud ma seda, kuna pean seda pluginade arendamise raames liialdama, kuid hetkel ei nĂ€e ma muud lahendust. Ja kĂŒsimusele "Miks just Nuke?" on vastus lihtne â kasutame tööl.
NĂŒĂŒd liigume lahenduse kausta (mitte projekti), hoidke klahvi Shift ja klĂ”psake kaustas tĂŒhjal kohal hiire parema nupuga â kontekstimenĂŒĂŒst valige "Ava PowerShell aken siin».

Kui teil ei ole installitud nuke, siis kirjutage esmalt kÀsk
dotnet tool install Nuke.GlobalTool âglobalNĂŒĂŒd kirjutage kĂ€sk nuke ja teilt palutakse seadistada nuke praeguse projekti jaoks. Ma ei tea, kuidas see Ă”igemini vene keeles kirjutada â inglise keeles kirjutatakse Could not find .nuke file. Do you want to setup a build? [y/n]
Vajutame klahvi Y ja edasi tulevad otsesed seadistamise punktid. Meile on vajalik kÔige lihtsam variant koos MSBuild, seega vastame nagu ekraanipildil:

Liigume Visual Studio'sse, mis pakub meile lahenduse taaskĂ€ivitamist, kuna sellesse on lisatud uus projekt. TaaskĂ€ivitame lahenduse ja nĂ€eme, et meil on nĂŒĂŒd projekt build milles meid huvitab ainult ĂŒks fail â Build.cs

Avame selle faili ja kirjutame projekti koostamise skripti kÔikide konfiguratsioonide alla. VÔi kasutame minu skripti, mida saate enda jaoks redigeerida:
kasutades System.IO;
kasutades Nuke.Common;
kasutades Nuke.Common.Execution;
kasutades Nuke.Common.ProjectModel;
kasutades Nuke.Common.Tools.MSBuild;
kasutades staatiline Nuke.Common.Tools.MSBuild.MSBuildTasks;
[CheckBuildProjectConfigurations]
[UnsetVisualStudioEnvironmentVariables]
klass Build : NukeBuild
{
avalik staatiline int Main () => Execute<Build>(x => x.Compile);
[Solution] readonly Solution Solution;
// Kui lahenduse ja projekti (plugin) nimed on erinevad, siis nÀidake projekti (plugin) nime siin
string PluginName => Solution.Name;
Target Compile => _ => _
.Executes(() =>
{
var project = Solution.GetProject(PluginName);
if (project == null)
throw new FileNotFoundException("Ei leitud!");
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($"Konfiguratsioon: {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 jĂ€lle kĂ€su nuke (vĂ”ime kirjutada kĂ€su nuke vajalikega Target. Aga meil on ĂŒks Target, mis kĂ€ivitub vaikimisi). PĂ€rast Enter-klahvi vajutamist tunneme end tĂ”eliste hĂ€kkeritena, sest nagu filmis toimub automaatne meie projekti koostamine erinevate konfiguratsioonide jaoks.
Muide, PowerShelli saab kasutada otse Visual Studios (menĂŒĂŒs «Vaadeâ -> âTeised aknadâ -> âPakettide halduri konsool»), kuid seal on kĂ”ik must-valge, mis ei ole vĂ€ga mugav.
Minu artikkel on siin nun valmis. Olen kindel, et AutoCADi versiooniga saate ise hakkama. Loodan, et siin esitatud materjal leiab oma «kliendid».
AitÀh tÀhelepanu eest!
Allikas: habr.com
