Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Lors du développement de plugins pour des applications CAO (dans mon cas il s'agit d'AutoCAD, Revit et Renga) au fil du temps, un problème apparaît - de nouvelles versions de programmes sont publiées, leurs API doivent être modifiées et de nouvelles versions de plugins doivent être créées.

Lorsque vous n'avez qu'un seul plugin ou que vous êtes encore autodidacte débutant en la matière, vous pouvez simplement faire une copie du projet, y modifier les emplacements nécessaires et assembler une nouvelle version du plugin. En conséquence, les modifications ultérieures du code entraîneront une augmentation multiple des coûts de main-d'œuvre.

Au fur et à mesure que vous acquerrez de l'expérience et des connaissances, vous découvrirez plusieurs façons d'automatiser ce processus. J'ai parcouru ce chemin et je veux vous dire avec quoi je me suis retrouvé et à quel point c'est pratique.

Voyons d’abord une méthode qui est évidente et que j’utilise depuis longtemps.

Liens vers les fichiers du projet

Et pour que tout soit simple, visuel et compréhensible, je vais tout décrire à l'aide d'un exemple abstrait de développement de plugin.

Ouvrons Visual Studio (j'ai la version Community 2019. Et oui - en russe) et créons une nouvelle solution. Appelons-le MonSuperPluginForRevit

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Nous allons créer un plugin pour Revit pour les versions 2015-2020. Par conséquent, créons un nouveau projet dans la solution (Net Framework Class Library) et appelons-le MonSuperPluginForRevit_2015

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Nous devons ajouter des liens vers l'API Revit. Bien sûr, nous pouvons ajouter des liens vers des fichiers locaux (nous devrons installer tous les SDK nécessaires ou toutes les versions de Revit), mais nous suivrons immédiatement le bon chemin et connecterons le package NuGet. Vous pouvez trouver de nombreux packages, mais j'utiliserai le mien.

Après avoir connecté le package, faites un clic droit sur l'élément «références" et sélectionnez l'élément "Déplacez packages.config vers PackageReference...»

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Si soudainement, à ce stade, vous commencez à paniquer, car dans la fenêtre des propriétés du package, il n'y aura aucun élément important "Copier localement", que nous devons absolument définir sur la valeur non, alors pas de panique - allez dans le dossier contenant le projet, ouvrez le fichier avec l'extension .csproj dans un éditeur qui vous convient (j'utilise Notepad++) et trouvez-y une entrée sur notre package. Elle ressemble à ça maintenant :

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

Ajoutez-y une propriété Durée. Cela se passera comme ceci :

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

Désormais, lors de la création d'un projet, les fichiers du package ne seront pas copiés dans le dossier de sortie.
Allons plus loin - imaginons immédiatement que notre plugin utilise quelque chose de l'API Revit, qui a changé au fil du temps avec la sortie de nouvelles versions. Eh bien, ou nous devons simplement modifier quelque chose dans le code en fonction de la version de Revit pour laquelle nous créons le plugin. Pour résoudre de telles différences de code, nous utiliserons des symboles de compilation conditionnelle. Ouvrez les propriétés du projet, allez dans l'onglet "assemblage" et sur le terrain "Notation de compilation conditionnelle"écrivons R2015.

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Notez que le symbole doit être ajouté pour les configurations Debug et Release.

Eh bien, pendant que nous sommes dans la fenêtre des propriétés, nous allons immédiatement dans l'onglet "Application" et sur le terrain "Espace de noms par défaut» supprimer le suffixe _2015afin que notre espace de noms soit universel et indépendant du nom de l'assembly :

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Dans mon cas, dans le produit final, les plugins de toutes les versions sont placés dans un seul dossier, donc mes noms d'assembly restent avec le suffixe du formulaire _20хх. Mais vous pouvez également supprimer le suffixe du nom de l'assembly si les fichiers sont censés se trouver dans des dossiers différents.

Passons au code du fichier Classe1.cs et simulez-y du code, en tenant compte des différentes versions de 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;
        }
    }
}

J'ai immédiatement pris en compte toutes les versions de Revit supérieures à la version 2015 (qui étaient disponibles au moment de la rédaction) et j'ai immédiatement pris en compte la présence de symboles de compilation conditionnelle, qui sont créés à l'aide du même modèle.

Passons au point culminant principal. Nous créons un nouveau projet dans notre solution, uniquement pour la version du plugin pour Revit 2016. Nous répétons respectivement toutes les étapes décrites ci-dessus en remplaçant le numéro 2015 par le numéro 2016. Mais le fichier Classe1.cs supprimer du nouveau projet.

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Fichier avec le code requis - Classe1.cs – nous l’avons déjà et il nous suffit d’insérer un lien vers celui-ci dans un nouveau projet. Il existe deux manières d'insérer des liens :

  1. Long – faites un clic droit sur le projet et sélectionnez «ajouter"->"Élément existant", dans la fenêtre qui s'ouvre, recherchez le fichier souhaité et à la place de l'option "ajouter" sélectionnez l'option "Ajouter comme connexion»

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

  1. court – directement dans l'explorateur de solutions, sélectionnez le fichier souhaité (voire des fichiers, voire des dossiers entiers) et faites-le glisser dans un nouveau projet tout en maintenant la touche Alt enfoncée. Au fur et à mesure que vous faites glisser, vous verrez que lorsque vous appuyez sur la touche Alt, le curseur de la souris passe d'un signe plus à une flèche.
    UPD: J'ai fait une petite confusion dans ce paragraphe - pour transférer plusieurs fichiers, vous devez maintenir enfoncé Maj + Alt!

Après avoir effectué la procédure, nous aurons un fichier dans le deuxième projet Classe1.cs avec l'icône correspondante (flèche bleue) :

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Lors de l'édition du code dans la fenêtre de l'éditeur, vous pouvez également choisir dans quel contexte de projet afficher le code, ce qui vous permettra de voir le code en cours d'édition sous différents symboles de compilation conditionnelle :

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Nous créons tous les autres projets (2017-2020) en utilisant ce schéma. Life hack - si vous faites glisser des fichiers dans l'Explorateur de solutions non pas depuis le projet de base, mais depuis le projet dans lequel ils sont déjà insérés sous forme de lien, vous n'avez pas besoin de maintenir la touche Alt enfoncée !

L'option décrite est assez bonne jusqu'au moment de l'ajout d'une nouvelle version du plugin ou jusqu'au moment de l'ajout de nouveaux fichiers au projet - tout cela devient très fastidieux. Et récemment, j'ai soudain réalisé comment tout régler avec un seul projet et nous passons à la deuxième méthode

La magie des configurations

Après avoir fini de lire ici, vous pourriez vous exclamer : « Pourquoi avez-vous décrit la première méthode, si l'article concerne immédiatement la seconde ?! » Et j'ai tout décrit pour expliquer plus clairement pourquoi nous avons besoin de symboles de compilation conditionnelle et en quoi nos projets diffèrent. Et maintenant, il nous devient plus clair quelles différences dans les projets nous devons mettre en œuvre, ne laissant qu'un seul projet.

Et pour que tout soit plus évident, nous ne créerons pas de nouveau projet, mais apporterons des modifications à notre projet actuel créé de la première manière.

Donc, tout d'abord, on supprime tous les projets de la solution sauf le principal (contenant directement les fichiers). Ceux. projets pour les versions 2016-2020. Ouvrez le dossier contenant la solution et supprimez-y les dossiers de ces projets.

Il nous reste un projet dans notre décision - MonSuperPluginForRevit_2015. Ouvrez ses propriétés et :

  1. Sur l'onglet "Application"supprimez le suffixe du nom de l'assembly _2015 (on comprendra pourquoi plus tard)
  2. Sur l'onglet "assemblage» supprimer le symbole de compilation conditionnelle R2015 du champ correspondant

Remarque : la dernière version de Visual Studio présente un bug : les symboles de compilation conditionnelle ne sont pas affichés dans la fenêtre des propriétés du projet, bien qu'ils soient disponibles. Si vous rencontrez ce problème, vous devez les supprimer manuellement du fichier .csproj. Cependant, nous devons encore y travailler, alors poursuivez votre lecture.

Renommez le projet dans la fenêtre Explorateur de solutions en supprimant le suffixe _2015 puis supprimez le projet de la solution. C'est nécessaire pour maintenir l'ordre et les sentiments des perfectionnistes ! Ouvrez le dossier de notre solution, renommez-y le dossier du projet de la même manière et chargez à nouveau le projet dans la solution.

Ouvrez le gestionnaire de configuration. Configuration américaine Libération en principe, il ne sera pas nécessaire, nous le supprimons donc. Nous créons de nouvelles configurations avec des noms qui nous sont déjà familiers R2015, R2016, ..., R2020. Notez que vous n'avez pas besoin de copier les paramètres d'autres configurations et que vous n'avez pas besoin de créer des configurations de projet :

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Accédez au dossier contenant le projet et ouvrez le fichier avec l'extension .csproj dans un éditeur qui vous convient. À propos, vous pouvez également l'ouvrir dans Visual Studio - vous devez décharger le projet, puis l'élément souhaité sera dans le menu contextuel :

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

L'édition dans Visual Studio est même préférable, puisque l'éditeur aligne et invite.

Dans le fichier nous verrons les éléments GroupePropriété – tout en haut se trouve la condition générale, puis viennent les conditions. Ces éléments définissent les propriétés du projet lors de sa construction. Le premier élément, qui est sans conditions, définit les propriétés générales, et les éléments avec conditions modifient donc certaines propriétés en fonction des configurations.

Accédez au (premier) élément commun GroupePropriété et regarde la propriété Nom de l'assemblage – c'est le nom de l'assemblée et nous devrions l'avoir sans suffixe _2015. S'il y a un suffixe, supprimez-le.

Trouver un élément avec une condition

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

Nous n'en avons pas besoin - nous le supprimons.

Élément avec condition

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

sera nécessaire pour travailler au stade du développement du code et du débogage. Vous pouvez modifier ses propriétés en fonction de vos besoins - définir différents chemins de sortie, modifier les symboles de compilation conditionnelle, etc.

Créons maintenant de nouveaux éléments GroupePropriété pour nos configurations. Dans ces éléments, il nous suffit de définir quatre propriétés :

  • Chemin de sortie - dossier de sortie. J'ai défini la valeur par défaut poubelleR20xx
  • Définir les constantes – symboles de compilation conditionnelle. La valeur doit être précisée TRACE;R20хх
  • Version du cadre cible – version plateforme. Différentes versions de l'API Revit nécessitent la spécification de différentes plates-formes.
  • Nom de l'assemblage – nom de l’assembly (c’est-à-dire le nom du fichier). Vous pouvez écrire le nom exact de l'assembly, mais pour des raisons de polyvalence, je recommande d'écrire la valeur $(Nom de l'Assemblée)_20хх. Pour ce faire, nous avons précédemment supprimé le suffixe du nom de l'assembly

La caractéristique la plus importante de tous ces éléments est qu’ils peuvent simplement être copiés dans d’autres projets sans aucune modification. Plus loin dans l'article, je joindrai tout le contenu du fichier .csproj.

D'accord, nous avons compris les propriétés du projet - ce n'est pas difficile. Mais que faire des bibliothèques de plug-ins (packages NuGet). Si nous regardons plus loin, nous verrons que les bibliothèques incluses sont spécifiées dans les éléments Groupe d'articles. Mais pas de chance : cet élément traite incorrectement les conditions en tant qu'élément GroupePropriété. C'est peut-être même un problème de Visual Studio, mais si vous spécifiez plusieurs éléments Groupe d'articles avec des conditions de configuration et insérez différents liens vers les packages NuGet à l'intérieur, puis lorsque vous modifiez la configuration, tous les packages spécifiés sont connectés au projet.

L'élément nous vient en aide Selectionnez, qui fonctionne selon notre logique habituelle si-alors-sinon.

Utilisation de l'élément Selectionnez, nous définissons différents packages NuGet pour différentes configurations :

Tous les contenus 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>

Veuillez noter que dans l'une des conditions j'ai spécifié deux configurations via OU. De cette façon, le package requis sera connecté lors de la configuration Déboguer.

Et ici, nous avons presque tout parfait. Nous chargeons le projet, activons la configuration dont nous avons besoin, appelons l'élément " dans le menu contextuel de la solution (pas du projet)Restaurer tous les packages NuGet"et nous voyons comment nos forfaits changent.

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Et à ce stade, je suis arrivé dans une impasse - afin de collecter toutes les configurations d'un coup, nous pourrions utiliser l'assemblage par lots (menu "assemblage"->"Construction par lots"), mais lors du changement de configuration, les packages ne sont pas automatiquement restaurés. Et lors de l'assemblage du projet, cela ne se produit pas non plus, même si, en théorie, cela devrait le faire. Je n'ai pas trouvé de solution à ce problème avec des moyens standards. Et il s’agit très probablement aussi d’un bug de Visual Studio.

Par conséquent, pour l'assemblage par lots, il a été décidé d'utiliser un système d'assemblage automatisé spécial. Nuke. En fait, je ne voulais pas cela parce que je pense que c'est excessif en termes de développement de plugins, mais pour le moment je ne vois pas d'autre solution. Et à la question « Pourquoi Nuke ? » La réponse est simple : nous l'utilisons au travail.

Alors, allez dans le dossier de notre solution (pas du projet), maintenez la touche enfoncée Shift et faites un clic droit sur un espace vide du dossier - dans le menu contextuel, sélectionnez l'élément "Ouvrez la fenêtre PowerShell ici».

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Si vous ne l'avez pas installé nuke, puis écrivez d'abord la commande

dotnet tool install Nuke.GlobalTool –global

Maintenant, écrivez la commande nuke et vous serez invité à configurer nuke pour le projet en cours. Je ne sais pas comment écrire cela plus correctement en russe - en anglais, ce sera écrit Impossible de trouver le fichier .nuke. Voulez-vous configurer une version ? [o/n]

Appuyez sur la touche Y, puis il y aura des éléments de paramètres directs. Nous avons besoin de l'option la plus simple en utilisant MSBuild, nous répondons donc comme dans la capture d'écran :

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Passons à Visual Studio, qui nous proposera de recharger la solution, puisqu'un nouveau projet y a été ajouté. On recharge la solution et on voit qu'on a un projet construire dans lequel nous ne nous intéressons qu'à un seul fichier - Construire.cs

Nous réalisons un projet de plugin avec compilation pour différentes versions de Revit/AutoCAD

Ouvrez ce fichier et écrivez un script pour créer le projet pour toutes les configurations. Eh bien, ou utilisez mon script, que vous pouvez modifier en fonction de vos besoins :

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

Nous revenons à la fenêtre PowerShell et réécrivons la commande nuke (vous pouvez écrire la commande nuke indiquant le nécessaire Target. Mais nous en avons un Target, qui s'exécute par défaut). Après avoir appuyé sur la touche Entrée, nous nous sentirons comme de vrais hackers, car, comme dans un film, notre projet sera automatiquement assemblé pour différentes configurations.

D'ailleurs, vous pouvez utiliser PowerShell directement depuis Visual Studio (menu "Voir"->"Autres fenêtres"->"Console du gestionnaire de packages"), mais tout sera en noir et blanc, ce qui n'est pas très pratique.

Ceci conclut mon article. Je suis sûr que vous pouvez découvrir vous-même l'option pour AutoCAD. J'espère que le matériel présenté ici trouvera ses « clients ».

Je vous remercie!

Source: habr.com

Ajouter un commentaire