Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Κατά την ανάπτυξη προσθηκών για εφαρμογές CAD (στην περίπτωσή μου αυτά είναι το AutoCAD, το Revit και το Renga) με την πάροδο του χρόνου, εμφανίζεται ένα πρόβλημα - κυκλοφορούν νέες εκδόσεις προγραμμάτων, αλλαγές στο API τους και πρέπει να γίνουν νέες εκδόσεις προσθηκών.

Όταν έχετε μόνο ένα πρόσθετο ή είστε ακόμα αυτοδίδακτος αρχάριος σε αυτό το θέμα, μπορείτε απλά να δημιουργήσετε ένα αντίγραφο του έργου, να αλλάξετε τις απαραίτητες θέσεις σε αυτό και να συναρμολογήσετε μια νέα έκδοση του πρόσθετου. Αντίστοιχα, μεταγενέστερες αλλαγές στον κώδικα θα συνεπάγονται πολλαπλή αύξηση του κόστους εργασίας.

Καθώς αποκτάτε εμπειρία και γνώση, θα βρείτε αρκετούς τρόπους για να αυτοματοποιήσετε αυτή τη διαδικασία. Περπάτησα αυτό το μονοπάτι και θέλω να σας πω σε τι κατέληξα και πόσο βολεύει.

Αρχικά, ας δούμε μια μέθοδο που είναι προφανής και την οποία χρησιμοποιώ εδώ και πολύ καιρό.

Σύνδεσμοι σε αρχεία έργου

Και για να είναι όλα απλά, οπτικά και κατανοητά, θα περιγράψω τα πάντα χρησιμοποιώντας ένα αφηρημένο παράδειγμα ανάπτυξης πρόσθετων.

Ας ανοίξουμε το Visual Studio (έχω την έκδοση Community 2019. Και ναι - στα ρωσικά) και ας δημιουργήσουμε μια νέα λύση. Ας τον φωνάξουμε MySuperPluginForRevit

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Θα δημιουργήσουμε ένα πρόσθετο για το Revit για τις εκδόσεις 2015-2020. Επομένως, ας δημιουργήσουμε ένα νέο έργο στη λύση (Net Framework Class Library) και ας το καλέσουμε MySuperPluginForRevit_2015

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Πρέπει να προσθέσουμε συνδέσμους στο Revit API. Φυσικά, μπορούμε να προσθέσουμε συνδέσμους σε τοπικά αρχεία (θα χρειαστεί να εγκαταστήσουμε όλα τα απαραίτητα SDK ή όλες τις εκδόσεις του Revit), αλλά θα ακολουθήσουμε αμέσως τη σωστή διαδρομή και θα συνδέσουμε το πακέτο NuGet. Μπορείτε να βρείτε αρκετά πακέτα, αλλά θα χρησιμοποιήσω τα δικά μου.

Αφού συνδέσετε το πακέτο, κάντε δεξί κλικ στο στοιχείο "παραπομπές"και επιλέξτε το στοιχείο"Μετακινήστε το packages.config στο PackageReference...»

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Εάν ξαφνικά σε αυτό το σημείο αρχίσετε να πανικοβάλλεστε, επειδή στο παράθυρο ιδιοτήτων πακέτου δεν θα υπάρχει κανένα σημαντικό στοιχείο "Αντιγράψτε τοπικά», την οποία πρέπει οπωσδήποτε να βάλουμε στην τιμή ψευδής, τότε μην πανικοβληθείτε - μεταβείτε στο φάκελο με το έργο, ανοίξτε το αρχείο με την επέκταση .csproj σε ένα πρόγραμμα επεξεργασίας που σας βολεύει (χρησιμοποιώ το Notepad++) και βρείτε μια καταχώριση για το πακέτο μας εκεί. Τώρα μοιάζει με αυτό:

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

Προσθέστε ένα ακίνητο σε αυτό χρόνο εκτέλεσης. Θα βγει ως εξής:

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

Τώρα, κατά την κατασκευή ενός έργου, τα αρχεία από το πακέτο δεν θα αντιγράφονται στο φάκελο εξόδου.
Ας πάμε παρακάτω - ας φανταστούμε αμέσως ότι η προσθήκη μας θα χρησιμοποιεί κάτι από το Revit API, το οποίο έχει αλλάξει με την πάροδο του χρόνου όταν κυκλοφόρησαν νέες εκδόσεις. Λοιπόν, ή απλά πρέπει να αλλάξουμε κάτι στον κώδικα ανάλογα με την έκδοση του Revit για την οποία φτιάχνουμε το πρόσθετο. Για να επιλύσουμε τέτοιες διαφορές στον κώδικα, θα χρησιμοποιήσουμε σύμβολα μεταγλώττισης υπό όρους. Ανοίξτε τις ιδιότητες του έργου, μεταβείτε στην καρτέλα "συνέλευση"και στο χωράφι"Συμβολισμός μεταγλώττισης υπό όρους"ας γράψουμε R2015.

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Σημειώστε ότι το σύμβολο πρέπει να προστεθεί και για τις διαμορφώσεις εντοπισμού σφαλμάτων και έκδοσης.

Λοιπόν, ενώ βρισκόμαστε στο παράθυρο ιδιοτήτων, πηγαίνουμε αμέσως στην καρτέλα “App"και στο χωράφι"Προεπιλεγμένος χώρος ονομάτων» αφαιρέστε το επίθημα _2015έτσι ώστε ο χώρος ονομάτων μας να είναι καθολικός και ανεξάρτητος από το όνομα του συγκροτήματος:

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Στην περίπτωσή μου, στο τελικό προϊόν, τα πρόσθετα όλων των εκδόσεων τοποθετούνται σε έναν φάκελο, επομένως τα ονόματα των συναρμολογήσεων μου παραμένουν με το επίθημα της φόρμας _20хх. Αλλά μπορείτε επίσης να αφαιρέσετε το επίθημα από το όνομα της συνέλευσης εάν τα αρχεία υποτίθεται ότι βρίσκονται σε διαφορετικούς φακέλους.

Ας πάμε στον κώδικα του αρχείου Class1.cs και προσομοιώστε κάποιο κώδικα εκεί, λαμβάνοντας υπόψη διαφορετικές εκδόσεις του Revit:

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

Έλαβα αμέσως υπόψη όλες τις εκδόσεις του Revit πάνω από την έκδοση 2015 (οι οποίες ήταν διαθέσιμες τη στιγμή της σύνταξης) και αμέσως έλαβα υπόψη την παρουσία συμβόλων μεταγλώττισης υπό όρους, τα οποία δημιουργούνται χρησιμοποιώντας το ίδιο πρότυπο.

Ας περάσουμε στο κύριο σημείο. Δημιουργούμε ένα νέο έργο στη λύση μας, μόνο για την έκδοση του πρόσθετου για το Revit 2016. Επαναλαμβάνουμε όλα τα βήματα που περιγράφονται παραπάνω, αντίστοιχα, αντικαθιστώντας τον αριθμό 2015 με τον αριθμό 2016. Αλλά το αρχείο Class1.cs διαγραφή από το νέο έργο.

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Αρχείο με τον απαιτούμενο κωδικό - Class1.cs – το έχουμε ήδη και πρέπει απλώς να εισαγάγουμε έναν σύνδεσμο προς αυτό σε ένα νέο έργο. Υπάρχουν δύο τρόποι εισαγωγής συνδέσμων:

  1. Μακρύς – κάντε δεξί κλικ στο έργο και επιλέξτε «Προσθήκη»->«Υπάρχον στοιχείο", στο παράθυρο που ανοίγει, βρείτε το απαιτούμενο αρχείο και αντί για την επιλογή "Προσθήκη"επιλέξτε την επιλογή"Προσθήκη ως σύνδεση»

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

  1. Σύντομη – απευθείας στον εξερευνητή λύσεων, επιλέξτε το επιθυμητό αρχείο (ή ακόμα και αρχεία, ή ακόμα και ολόκληρους φακέλους) και σύρετέ το σε ένα νέο έργο ενώ κρατάτε πατημένο το πλήκτρο Alt. Καθώς σύρετε, θα δείτε ότι όταν πατήσετε το πλήκτρο Alt, ο δρομέας του ποντικιού θα αλλάξει από σύμβολο συν σε βέλος.
    UPD: Έκανα μια μικρή σύγχυση σε αυτήν την παράγραφο - για να μεταφέρετε πολλά αρχεία θα πρέπει να κρατήσετε πατημένο Shift + Alt!

Αφού πραγματοποιήσουμε τη διαδικασία, θα έχουμε αρχείο στο δεύτερο έργο Class1.cs με το αντίστοιχο εικονίδιο (μπλε βέλος):

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Κατά την επεξεργασία κώδικα στο παράθυρο του προγράμματος επεξεργασίας, μπορείτε επίσης να επιλέξετε σε ποιο πλαίσιο έργου θα εμφανίζεται ο κώδικας, κάτι που θα σας επιτρέψει να δείτε τον κώδικα να επεξεργάζεται κάτω από διαφορετικά σύμβολα μεταγλώττισης υπό όρους:

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Δημιουργούμε όλα τα άλλα έργα (2017-2020) χρησιμοποιώντας αυτό το σχήμα. Life hack - εάν σύρετε αρχεία στον Εξερεύνηση λύσεων όχι από το βασικό έργο, αλλά από το έργο όπου έχουν ήδη εισαχθεί ως σύνδεσμος, τότε δεν χρειάζεται να κρατήσετε πατημένο το πλήκτρο Alt!

Η περιγραφόμενη επιλογή είναι αρκετά καλή μέχρι τη στιγμή της προσθήκης μιας νέας έκδοσης του πρόσθετου ή μέχρι τη στιγμή της προσθήκης νέων αρχείων στο έργο - όλα αυτά γίνονται πολύ κουραστικά. Και πρόσφατα ξαφνικά συνειδητοποίησα ξαφνικά πώς να τα λύσω όλα με ένα έργο και προχωράμε στη δεύτερη μέθοδο

Η μαγεία των διαμορφώσεων

Αφού ολοκληρώσετε την ανάγνωση εδώ, μπορείτε να αναφωνήσετε, "Γιατί περιέγραψες την πρώτη μέθοδο, αν το άρθρο αφορά αμέσως τη δεύτερη;" Και περιέγραψα τα πάντα για να γίνει πιο σαφές γιατί χρειαζόμαστε σύμβολα συλλογής υπό όρους και σε ποια σημεία διαφέρουν τα έργα μας. Και τώρα μας γίνεται πιο σαφές ποιες ακριβώς διαφορές στα έργα πρέπει να υλοποιήσουμε, αφήνοντας μόνο ένα έργο.

Και για να γίνουν όλα πιο προφανή, δεν θα δημιουργήσουμε ένα νέο έργο, αλλά θα κάνουμε αλλαγές στο τρέχον έργο μας που δημιουργήθηκε με τον πρώτο τρόπο.

Έτσι, πρώτα απ 'όλα, αφαιρούμε όλα τα έργα από τη λύση εκτός από το κύριο (που περιέχει απευθείας τα αρχεία). Εκείνοι. έργα για εκδόσεις 2016-2020. Ανοίξτε το φάκελο με τη λύση και διαγράψτε τους φακέλους αυτών των έργων εκεί.

Έχουμε ένα έργο στην απόφασή μας - MySuperPluginForRevit_2015. Ανοίξτε τις ιδιότητες του και:

  1. Στην καρτέλα "App"αφαιρέστε το επίθημα από το όνομα της συνέλευσης _2015 (θα γίνει σαφές το γιατί αργότερα)
  2. Στην καρτέλα "συνέλευση» αφαιρέστε το σύμβολο μεταγλώττισης υπό όρους R2015 από το αντίστοιχο πεδίο

Σημείωση: η τελευταία έκδοση του Visual Studio έχει σφάλμα - τα σύμβολα μεταγλώττισης υπό όρους δεν εμφανίζονται στο παράθυρο ιδιοτήτων του έργου, αν και είναι διαθέσιμα. Εάν αντιμετωπίζετε αυτό το σφάλμα, τότε πρέπει να τα αφαιρέσετε με μη αυτόματο τρόπο από το αρχείο .csproj. Ωστόσο, πρέπει ακόμα να δουλέψουμε σε αυτό, οπότε διαβάστε παρακάτω.

Μετονομάστε το έργο στο παράθυρο Εξερεύνηση λύσεων αφαιρώντας το επίθημα _2015 και στη συνέχεια αφαιρέστε το έργο από τη λύση. Αυτό είναι απαραίτητο για τη διατήρηση της τάξης και των συναισθημάτων των τελειομανών! Ανοίγουμε τον φάκελο της λύσης μας, μετονομάζουμε εκεί τον φάκελο του έργου με τον ίδιο τρόπο και φορτώνουμε το έργο ξανά στη λύση.

Ανοίξτε τη διαχείριση ρυθμίσεων. διαμόρφωση ΗΠΑ Απελευθερώστε κατ 'αρχήν, δεν θα χρειαστεί, επομένως το διαγράφουμε. Δημιουργούμε νέες διαμορφώσεις με ονόματα που είναι ήδη γνωστά σε εμάς R2015, R2016, ..., R2020. Λάβετε υπόψη ότι δεν χρειάζεται να αντιγράψετε ρυθμίσεις από άλλες διαμορφώσεις και δεν χρειάζεται να δημιουργήσετε διαμορφώσεις έργου:

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Μεταβείτε στο φάκελο με το έργο και ανοίξτε το αρχείο με την επέκταση .csproj σε ένα πρόγραμμα επεξεργασίας που σας ταιριάζει. Παρεμπιπτόντως, μπορείτε επίσης να το ανοίξετε στο Visual Studio - πρέπει να ξεφορτώσετε το έργο και, στη συνέχεια, το επιθυμητό στοιχείο θα βρίσκεται στο μενού περιβάλλοντος:

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Η επεξεργασία στο Visual Studio είναι ακόμη προτιμότερη, καθώς ο επεξεργαστής ευθυγραμμίζει και ζητά.

Στο αρχείο θα δούμε τα στοιχεία PropertyGroup – στην κορυφή είναι το γενικό και μετά έρχονται οι συνθήκες. Αυτά τα στοιχεία ορίζουν τις ιδιότητες του έργου όταν κατασκευάζεται. Το πρώτο στοιχείο, το οποίο είναι χωρίς όρους, ορίζει γενικές ιδιότητες και τα στοιχεία με συνθήκες, κατά συνέπεια, αλλάζουν ορισμένες ιδιότητες ανάλογα με τις διαμορφώσεις.

Μεταβείτε στο κοινό (πρώτο) στοιχείο PropertyGroup και κοιτάξτε το ακίνητο Όνομα συνέλευσης – αυτό είναι το όνομα της συνέλευσης και θα πρέπει να το έχουμε χωρίς επίθημα _2015. Εάν υπάρχει επίθημα, αφαιρέστε το.

Εύρεση στοιχείου με συνθήκη

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

Δεν το χρειαζόμαστε - το διαγράφουμε.

Στοιχείο με κατάσταση

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

θα χρειαστεί για να εργαστείτε στο στάδιο της ανάπτυξης κώδικα και του εντοπισμού σφαλμάτων. Μπορείτε να αλλάξετε τις ιδιότητές του ανάλογα με τις ανάγκες σας - να ορίσετε διαφορετικές διαδρομές εξόδου, να αλλάξετε σύμβολα μεταγλώττισης υπό όρους κ.λπ.

Τώρα ας δημιουργήσουμε νέα στοιχεία PropertyGroup για τις διαμορφώσεις μας. Σε αυτά τα στοιχεία χρειάζεται απλώς να ορίσουμε τέσσερις ιδιότητες:

  • OutputPath – φάκελος εξόδου. Ορίζω την προεπιλεγμένη τιμή binR20xx
  • Ορισμός σταθερών – σύμβολα μεταγλώττισης υπό όρους. Η τιμή πρέπει να καθοριστεί TRACE;R20хх
  • TargetFrameworkVersion – έκδοση πλατφόρμας. Διαφορετικές εκδόσεις του Revit API απαιτούν τον καθορισμό διαφορετικών πλατφορμών.
  • Όνομα συνέλευσης – όνομα συγκροτήματος (δηλαδή όνομα αρχείου). Μπορείτε να γράψετε το ακριβές όνομα του συγκροτήματος, αλλά για ευελιξία συνιστώ να γράψετε την τιμή $(AssemblyName)_20хх. Για να γίνει αυτό, αφαιρέσαμε προηγουμένως το επίθημα από το όνομα της συνέλευσης

Το πιο σημαντικό χαρακτηριστικό όλων αυτών των στοιχείων είναι ότι μπορούν απλώς να αντιγραφούν σε άλλα έργα χωρίς να τα αλλάξουν καθόλου. Αργότερα στο άρθρο θα επισυνάψω όλα τα περιεχόμενα του αρχείου .csproj.

Εντάξει, καταλάβαμε τις ιδιότητες του έργου - δεν είναι δύσκολο. Τι να κάνετε όμως με τις βιβλιοθήκες προσθηκών (πακέτα NuGet). Αν κοιτάξουμε περαιτέρω, θα δούμε ότι οι συμπεριλαμβανόμενες βιβλιοθήκες καθορίζονται στα στοιχεία Ομάδα αντικειμένων. Αλλά κακή τύχη - αυτό το στοιχείο επεξεργάζεται εσφαλμένα τις συνθήκες ως στοιχείο PropertyGroup. Ίσως πρόκειται ακόμη και για σφάλμα του Visual Studio, αλλά αν καθορίσετε πολλά στοιχεία Ομάδα αντικειμένων με συνθήκες διαμόρφωσης και εισαγάγετε διαφορετικούς συνδέσμους για πακέτα NuGet μέσα και, στη συνέχεια, όταν αλλάξετε τη διαμόρφωση, όλα τα καθορισμένα πακέτα συνδέονται στο έργο.

Το στοιχείο έρχεται σε βοήθεια Επιλέξτε, που λειτουργεί σύμφωνα με τη συνήθη λογική μας αν-τότε-αλλιώς.

Χρήση στοιχείου Επιλέξτε, ορίζουμε διαφορετικά πακέτα NuGet για διαφορετικές διαμορφώσεις:

Όλα τα περιεχόμενα 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>

Σημειώστε ότι σε μία από τις συνθήκες καθόρισα δύο διαμορφώσεις μέσω Ή. Με αυτόν τον τρόπο το απαιτούμενο πακέτο θα συνδεθεί κατά τη διαμόρφωση Debug.

Και εδώ έχουμε σχεδόν τα πάντα τέλεια. Φορτώνουμε ξανά το έργο, ενεργοποιούμε τη διαμόρφωση που χρειαζόμαστε, καλούμε το στοιχείο " στο μενού περιβάλλοντος της λύσης (όχι του έργου)Επαναφέρετε όλα τα πακέτα NuGet«και βλέπουμε πώς αλλάζουν τα πακέτα μας.

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Και σε αυτό το στάδιο έφτασα σε αδιέξοδο - για να συγκεντρώσουμε όλες τις διαμορφώσεις ταυτόχρονα, θα μπορούσαμε να χρησιμοποιήσουμε τη συναρμολόγηση παρτίδας (μενού "συνέλευση»->«Κατασκευή παρτίδας"), αλλά κατά την εναλλαγή διαμορφώσεων, τα πακέτα δεν αποκαθίστανται αυτόματα. Και κατά τη συναρμολόγηση του έργου, αυτό επίσης δεν συμβαίνει, αν και, θεωρητικά, θα έπρεπε. Δεν βρήκα λύση σε αυτό το πρόβλημα χρησιμοποιώντας τυπικά μέσα. Και πιθανότατα αυτό είναι επίσης ένα σφάλμα του Visual Studio.

Ως εκ τούτου, για τη συναρμολόγηση παρτίδας, αποφασίστηκε να χρησιμοποιηθεί ένα ειδικό αυτοματοποιημένο σύστημα συναρμολόγησης Nuke. Στην πραγματικότητα δεν το ήθελα αυτό γιατί νομίζω ότι είναι υπερβολικό όσον αφορά την ανάπτυξη πρόσθετων, αλλά αυτή τη στιγμή δεν βλέπω άλλη λύση. Και στην ερώτηση "Γιατί Nuke;" Η απάντηση είναι απλή - το χρησιμοποιούμε στη δουλειά.

Έτσι, μεταβείτε στο φάκελο της λύσης μας (όχι στο έργο), κρατήστε πατημένο το πλήκτρο αλλαγή και κάντε δεξί κλικ σε ένα κενό χώρο στο φάκελο - στο μενού περιβάλλοντος επιλέξτε το στοιχείο "Ανοίξτε το παράθυρο του PowerShell εδώ».

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Εάν δεν το έχετε εγκατεστημένο Nuke, μετά γράψτε πρώτα την εντολή

dotnet tool install Nuke.GlobalTool –global

Τώρα γράψτε την εντολή Nuke και θα σας ζητηθεί να ρυθμίσετε τις παραμέτρους Nuke για το τρέχον έργο. Δεν ξέρω πώς να το γράψω πιο σωστά στα ρωσικά - στα αγγλικά θα γραφτεί Δεν ήταν δυνατή η εύρεση του αρχείου .nuke. Θέλετε να ρυθμίσετε μια κατασκευή; [ε/η]

Πατήστε το πλήκτρο Y και, στη συνέχεια, θα εμφανιστούν απευθείας στοιχεία ρυθμίσεων. Χρειαζόμαστε την απλούστερη επιλογή χρήσης MSBuild, οπότε απαντάμε όπως στο στιγμιότυπο οθόνης:

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Ας πάμε στο Visual Studio, το οποίο θα μας ζητήσει να φορτώσουμε ξανά τη λύση, καθώς έχει προστεθεί ένα νέο έργο σε αυτήν. Φορτώνουμε ξανά τη λύση και βλέπουμε ότι έχουμε ένα έργο χτίζω στο οποίο μας ενδιαφέρει μόνο ένα αρχείο - Build.cs

Κάνουμε ένα έργο plugin με μεταγλώττιση για διαφορετικές εκδόσεις του Revit/AutoCAD

Ανοίξτε αυτό το αρχείο και γράψτε ένα σενάριο για να δημιουργήσετε το έργο για όλες τις διαμορφώσεις. Λοιπόν, ή χρησιμοποιήστε το σενάριο μου, το οποίο μπορείτε να επεξεργαστείτε για να ταιριάζει στις ανάγκες σας:

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

Επιστρέφουμε στο παράθυρο του PowerShell και γράφουμε ξανά την εντολή Nuke (μπορείτε να γράψετε την εντολή Nuke αναφέροντας τα απαιτούμενα στόχος. Αλλά έχουμε ένα στόχος, το οποίο εκτελείται από προεπιλογή). Αφού πατήσουμε το πλήκτρο Enter, θα νιώθουμε σαν πραγματικοί χάκερ, γιατί, όπως σε μια ταινία, το έργο μας θα συναρμολογηθεί αυτόματα για διαφορετικές διαμορφώσεις.

Παρεμπιπτόντως, μπορείτε να χρησιμοποιήσετε το PowerShell απευθείας από το Visual Studio (μενού "Άποψη»->«Άλλα παράθυρα»->«Κονσόλα Package Manager"), αλλά όλα θα είναι ασπρόμαυρα, κάτι που δεν είναι πολύ βολικό.

Αυτό ολοκληρώνει το άρθρο μου. Είμαι βέβαιος ότι μπορείτε να βρείτε μόνοι σας την επιλογή για το AutoCAD. Ελπίζω ότι το υλικό που παρουσιάζεται εδώ θα βρει τους «πελάτες» του.

Спасибо за внимание!

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο