Cet article est un didacticiel qui vous guide tout au long du processus de création et de publication d'un nouveau composant pour la plate-forme UiPath RPA . Cela est pratique dans différents cas, par exemple, pour une intégration simple avec les systèmes de l'entreprise ou dans des situations où l'entreprise souhaite aider des employés qui ne sont pas particulièrement compétents en programmation à créer leurs propres processus pour les robots. Mais, il me semble, cette technique fonctionne particulièrement bien dans les cas où vous devez intégrer votre produit dans l'écosystème robotique, permettant aux utilisateurs de configurer l'intégration des processus internes en quelques clics. Un exemple est le connecteur écrit par Abbyy pour son produit distribué Abbyy Flexicapture . Un autre exemple est UiPath lui-même, qui a ainsi implémenté la connexion à son nouveau module ML pour la vision par ordinateur (Computer Vision dans le gestionnaire de paquets), les actions pour travailler avec PDF, etc.
Maintenant dans l' App Store UiPath Go! déjà en plein essor a commencé à apparaître des connecteurs pour des solutions populaires, telles que Salesforce ou ServiceNow, et, très probablement, cette tendance ne fait que gagner en popularité.
Alors, comment commencez-vous à développer votre propre action?
NB En anglais, une action est une activité, rappelez-vous ceci si vous avez besoin de google quelque chose
Si vous n'avez pas envie de faire tous les réglages, vous pouvez essayer l'exemple de code qui a été suivi dans les étapes de ce didacticiel. Il se trouve sur GitLab . Le code de l'article est raccourci et simplifié, il est disponible sur Yandex Disk

Ce dont nous avons besoin avant de commencer à travailler:
- Visual Studio (la version gratuite de VS Community Edition est parfaite. Lors de l'installation, vous devez sélectionner .NET Desktop Development ou spécifier manuellement les packages suivants:
- Gestionnaire de paquets Nuget
- Pack de ciblage .NET Framework 4.6.1 (4.6 nécessaire)
- C # et Visual Basic (les actions peuvent être écrites dans n'importe quel langage .NET, mais, traditionnellement, C # ou VB.NET est utilisé). Ce didacticiel utilisera C #.
- Windows Workflow Foundation
- UiPath Studio (et ici la même chose, CE gratuit, il vous suffit de remplir le formulaire de demande UiPath Community Edition ).
NB Pour le développement de l'action elle-même, nous n'en avons pas besoin, mais, bien sûr, je veux voir ce que nous allons faire.
- NuGet Package Manager (fourni avec VS 2017+ ou téléchargé sur Nuget.org
Commencez à créer
Créer un projet dans VS
- Créez un projet de
C# Class Library (.NET Framework)
. Veuillez noter que les variations sur le thème (par exemple, la bibliothèque de classes C # (.NET Standard) ) ne nous conviennent pas.

- Nous lui choisissons un nom significatif (le format habituel <Developer> .UiPath.Activities. <Project Name> ) et indiquons que nous voulons utiliser le
.NET Framework 4.6.1
.
L' ID du package NuGet doit contenir le mot Activités. Étant donné que nous voulons tout prendre de VS, il est préférable de nommer immédiatement le projet correctement afin de pouvoir le récupérer dans NuGet plus tard.

- Dans le projet créé, nous créons les sous-dossiers suivants (il s'agit d'une étape facultative, mais il est plus pratique de travailler avec des packages d'actions lorsque vous souhaitez proposer aux utilisateurs plusieurs actions à la fois et que le nombre de fichiers commence à s'accumuler):
- Activités (ici nous aurons un code d'action)
- Designer (ici nous aurons la forme de fenêtres d'action)
- Ressources (ici, nous allons stocker des images, des icônes et d'autres choses nécessaires)
- Renommez le fichier Class1.cs que nous avons créé en VS selon le nom de notre première action et déplacez-le dans le dossier Activités.

Création et publication d'actions faciles
À ce stade, nous avons un projet vide compilé dans .dll
. Passons maintenant à la création de l'action elle-même.
NB Étant donné qu'UiPath prend en charge plusieurs langues, nous devrons à la fin ajouter de la localisation et modifier légèrement ce que nous faisons maintenant, mais commençons par ce qui est nécessaire et suffisant.
- Nous en avons besoin de deux en
using
:
using System; using System.Activities;
- Nous
CodeActivity
notre classe de CodeActivity
:
public class TutorialForHabr: CodeActivity {}
- Nous définissons les paramètres d'entrée et de sortie:
public class TutorialForHabr: CodeActivity { public InArgument<Int32> Row { get; set; } public InArgument<Int32> Column { get; set; } public OutArgument<String> Cell { get; set; } }
NB Les paramètres d'action sont entrés InArgument< >
, sortie OutArgument< >
et mixtes, permettant à la fois de recevoir et de recevoir les paramètres InOutArgument< >
- Et la méthode
Execute
, qui est la seule méthode que nous devons définitivement définir:
protected override void Execute(CodeActivityContext context) { string colstr = "";
À ce stade, nous avons une action de travail pour UiPath qui implémente des fonctionnalités simples mais nécessaires.
Nous allons le publier, puis passer à la deuxième partie et reprendre, un peu, les «décorations».
Publier via NuGet
Vous pouvez créer un package NuGet via l'interface graphique du gestionnaire de packages NuGet ou via la ligne de commande en appelant nuget.exe pack
. La commande pack
accepte deux paramètres principaux en entrée: le nom du fichier de projet .csproj ou le nom du fichier .nuspec contenant les méta-informations du package. La première option ne nous permet pas, sans modifications manuelles supplémentaires du fichier .json, de définir certaines propriétés de package qui sont importantes pour nous, par exemple les balises, la licence ou l'URL du référentiel, et elle ne nous permet pas de définir une icône pour le projet qui sera visible dans le gestionnaire de packages.
Dans la deuxième variante, nous dupliquons certaines propriétés du package, qui pourraient néanmoins être automatiquement extraites de Visual Studio.
Par conséquent, nous allons suivre le chemin 1.5 et créer un fichier avec l'extension .nuspec à la racine du projet (le nom n'a pas d'importance, il n'y a qu'un seul fichier), qui contiendra les informations qui ne peuvent pas être obtenues à partir de .csproj et combiner ces deux sources de données.
<?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>$id$</id> <title>$title$</title> <version>$version$</version> <authors>$author$</authors> <owners>$author$</owners> <requireLicenseAcceptance>false</requireLicenseAcceptance> <licenseUrl>https://choosealicense.com/licenses/mit/</licenseUrl> <projectUrl>https://gitlab.com/ilyak/ilyak.uipath.activities</projectUrl> <iconUrl>http://www.uipath.com/hubfs/Logos/uipath-nuget-logo.png</iconUrl> <description>$description$</description> <copyright>$copyright$</copyright> <tags>UiPath,Activity,Excel</tags> </metadata> <files> <file src="bin\Debug\IlyaK.UiPath.Activities.TutorialForHabr.dll" target="lib\net461\IlyaK.UiPath.Activities.TutorialForHabr.dll" /> </files> </package>
Comme vous pouvez le voir, la structure de .nuspec est assez évidente. Si vous êtes réticent à jouer avec XML, vous pouvez le créer via l'éditeur visuel NuGet Package Manager et l'enregistrer dans le dossier du projet pour une utilisation future. Des variables comme $copyright
sont tirées des informations contenues dans le fichier .dll, c'est-à-dire de Visual Studio.
Maintenant, nous voulons utiliser notre .nuspec pour qu'à chaque build nous obtenions un nouveau paquet. Pour ce faire, nous allons dans Propriétés et allons dans l'onglet Créer des événements.
Écrivez des mots magiques dans une ligne de commande d'événement post-build
IF EXIST "$(ProjectDir)$(OutDir)*.nupkg" del "$(ProjectDir)$(OutDir)*.nupkg" nuget.exe pack "$(ProjectPath)" IF EXIST "$(ProjectDir)$(OutDir)*.nupkg" xcopy /Y "$(ProjectDir)$(OutDir)*.nupkg" "C:\Program Files (x86)\UiPath\Studio\Packages\"
ce qui, traduit en russe, signifie
- Supprimer les anciens packages dans le dossier où la génération est créée
- Créez un nouveau package à l'aide des fichiers .csproj et .nuspec
- Placez-le dans le dossier
C:\Program Files (x86)\UiPath\Studio\Packages\
Quel est ce dossier? Il s'agit du référentiel de packages local utilisé par UiPath Studio. Dès qu'un nouveau package apparaît, il sera automatiquement disponible via le gestionnaire de packages et il sera possible de l'ajouter aux processus de robotisation.

NB Le chemin d'accès au référentiel local peut être modifié via les paramètres UiPath Studio afin qu'il soit pratique d'y copier des fichiers en cas de problème avec les autorisations.

C'est tout, en fait, félicitations!
NB Veuillez noter que smart Studio lui-même a créé une catégorie pour notre action, en utilisant des points comme niveaux d'imbrication, et place des espaces devant les majuscules au nom de l'action.
La prochaine partie de l'article sera consacrée à la "beauté": comment créer une interface visuelle pour une action, attribuer une icône et localiser des textes.
Sérieux
Attributs
Pour que notre action fonctionne, la première partie suffit. Mais je veux que nous puissions choisir une catégorie, montrer des astuces, etc.
Pour cela, nous avons besoin d'attributs. Il existe des attributs qui conviennent à l'action elle-même et à ses paramètres:
[Category (" , ")] [DisplayName (" ")] [Description (" ")]
Et il y a ceux qui ne sont que des paramètres nécessaires:
[RequiredArgument]
Localisation
Malheureusement, il existe une subtilité avec des attributs: dans la version russe d'UiPath Studio, les noms des catégories d'actions et les catégories de leurs propriétés sont également traduits. Par conséquent, si nous définissons l'attribut [Category("Input")]
pour le paramètre d'entrée, il s'affichera correctement dans la version anglaise, mais dans la version russe, il tombera dans sa propre catégorie d' entrée distincte, et non dans la catégorie d' entrée standard. Il en va de même pour les actions: dans la version russe, l' intégration d' applications devient l' intégration d'applications .
Nous devons donc déplacer les constantes de texte vers des ressources dépendantes de la langue et les utiliser à partir de là.
Pour ce faire, créez un fichier magique Localization.cs contenant des fonctions de localisation des attributs
Localization.cs using IlyaK.UiPath.Activities.TutorialForHabr.Properties; using System; using System.ComponentModel; namespace IlyaK.UiPath.Activities.TutorialForHabr { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.Delegate | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter)] public class LocalizedCategoryAttribute : CategoryAttribute { public LocalizedCategoryAttribute(string category) : base(category) { } protected override string GetLocalizedString(string value) { return Resources.ResourceManager.GetString(value) ?? base.GetLocalizedString(value); } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)] public class LocalizedDisplayNameAttribute : DisplayNameAttribute { public LocalizedDisplayNameAttribute(string displayName) : base(displayName) { } public override string DisplayName { get { return Resources.ResourceManager.GetString(DisplayNameValue) ?? base.DisplayName; } } } public class LocalizedDescriptionAttribute : DescriptionAttribute { public LocalizedDescriptionAttribute(string displayName) : base(displayName) { } public override string Description { get { return Resources.ResourceManager.GetString(DescriptionValue) ?? base.Description; } } } }
Il nous permettra de remplacer le design
[Category("Name")
sur
[LocalizedCategory(nameof(Resources.CategoryName))]
pour que ce mécanisme fonctionne, nous devons:
- Créez des fichiers de ressources pour les langues que nous allons traduire, dans notre cas,
Resources.resx
et Resources.ru.resx
dans le dossier Resources
( Ajouter -> Nouvel élément -> Fichier de ressources ). Assurez-vous que la valeur du modificateur d'accès pour les ressources est dans Public . - Ajouter au fichier d'action collective
using IlyaK.UiPath.Activities.TutorialForHabr.Properties;
Et définissez la classe et tous les paramètres avec les attributs appropriés
[LocalizedCategory(nameof(Resources.AppIntegrationExcel))] [LocalizedDisplayName(nameof(Resources.TutorialForHabrName))] [LocalizedDescription(nameof(Resources.TutorialForHabrDescription))] public class TutorialForHabr : CodeActivity { [LocalizedCategory(nameof(Resources.Input))] [LocalizedDisplayName(nameof(Resources.RowName))] [LocalizedDescription(nameof(Resources.RowDescription))] public InArgument<Int32> Row { get; set; } [LocalizedCategory(nameof(Resources.Input))] [LocalizedDisplayName(nameof(Resources.ColumnName))] [LocalizedDescription(nameof(Resources.ColumnDescription))] public InArgument<Int32> Column { get; set; } [LocalizedCategory(nameof(Resources.Output))] [LocalizedDisplayName(nameof(Resources.CellName))] [LocalizedDescription(nameof(Resources.CellDescription))] }
- Pour que la bibliothèque avec des ressources russes tombe dans le package NuGet, vous devez ajouter une autre ligne au groupe de fichiers dans le fichier .nuspec
<files> <file src="bin\Debug\IlyaK.UiPath.Activities.TutorialForHabr.dll" target="lib\net461\IlyaK.UiPath.Activities.TutorialForHabr.dll" /> <file src="bin\Debug\ru\**" target="lib\net461\ru\" /> </files>
Le designer
Pour rendre notre action plus belle dans le processus et permettre aux utilisateurs d'entrer des données sans explorer les propriétés, nous devons ajouter une interface utilisateur. Cela se fait via un fichier XAML qui, avec l'aide de Visual Studio, peut être édité dans une interface spéciale, mais une partie devra encore être corrigée manuellement. Je vais vous donner un modèle pour vous aider à démarrer, puis la documentation de Microsoft mérite le détour.
- Placez l'icône de l'action dans le dossier
Resources
. Dans les propriétés de l'action de génération définie sur Ressource (pas sur Ressource intégrée ) - Créez un nouveau Concepteur d'activités ( Ajouter -> Nouvel élément -> Concepteur d'activités ) dans le dossier
Designer
et appelez-le TutorialForHabr
TutorialForHabr.xaml <sap:ActivityDesigner x:Class="IlyaK.UiPath.Activities.TutorialForHabr.Designer.TutorialForHabrDesigner" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:resource="clr-namespace:IlyaK.UiPath.Activities.TutorialForHabr.Properties" xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation" xmlns:sapc="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation" xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"> <sap:ActivityDesigner.Resources> <ResourceDictionary> <sapc:ArgumentToExpressionConverter x:Key="ArgumentToExpressionConverter" /> </ResourceDictionary> </sap:ActivityDesigner.Resources> <DockPanel Width="200"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="70"></ColumnDefinition> <ColumnDefinition Width="130"></ColumnDefinition> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Text="{x:Static resource:Resources.RowName}" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,5,0"></TextBlock> <sapv:ExpressionTextBox Grid.Row="0" Grid.Column="1" OwnerActivity="{Binding Path=ModelItem}" ExpressionType="{x:Type s:Int32}" HintText="{x:Static resource:Resources.RowDescription}" Expression="{Binding Path=ModelItem.Row, Converter={StaticResource ArgumentToExpressionConverter},ConverterParameter=In, Mode=TwoWay}"/> <TextBlock Grid.Row="1" Grid.Column="0" Text="{x:Static resource:Resources.ColumnName}" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,5,0"></TextBlock> <sapv:ExpressionTextBox Grid.Row="1" Grid.Column="1" OwnerActivity="{Binding Path=ModelItem}" ExpressionType="{x:Type s:Int32}" HintText="{x:Static resource:Resources.ColumnDescription}" Expression="{Binding Path=ModelItem.Column, Converter={StaticResource ArgumentToExpressionConverter},ConverterParameter=In, Mode=TwoWay}"/> </Grid> </DockPanel> <sap:ActivityDesigner.Icon> <DrawingBrush> <DrawingBrush.Drawing> <ImageDrawing> <ImageDrawing.Rect> <Rect Location="0,0" Size="32,32" ></Rect> </ImageDrawing.Rect> <ImageDrawing.ImageSource> <BitmapImage UriSource="/IlyaK.UiPath.Activities.TutorialForHabr;component/Resources/Tutorial_32x32.png"></BitmapImage> </ImageDrawing.ImageSource> </ImageDrawing> </DrawingBrush.Drawing> </DrawingBrush> </sap:ActivityDesigner.Icon> </sap:ActivityDesigner>
Voici comment nous définissons le libellé localisé:
<TextBlock Grid.Row="0" Grid.Column="0" Text="{x:Static resource:Resources.RowName}" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,5,0" />
, et c'est le champ de saisie. ExpressionType
définit le type de champ, HintText
- un indice (texte gris), Expression
associe la valeur du champ à notre action
<sapv:ExpressionTextBox OwnerActivity="{Binding Path=ModelItem}" Grid.Row="0" Grid.Column="1" ExpressionType="{x:Type s:Int32}" HintText="{x:Static resource:Resources.RowDescription}" Expression="{Binding Path=ModelItem.Row, Converter={StaticResource ArgumentToExpressionConverter},ConverterParameter=In, Mode=TwoWay}" />
NB Remarquez la balise BitmapImage à la fin du fichier. Nous avons donc défini l'image de l'icône avec un lien vers le fichier de ressources. C'est une fonctionnalité très fragile et il faut parfois la bricoler.
selon les résultats, cela devrait se produire comme ceci:

- Créez la classe DesignerMetata dans le dossier Activités
DesignerMetata.cs using System.Activities.Presentation.Metadata; using System.ComponentModel; namespace IlyaK.UiPath.Activities.TutorialForHabr.Design { public class DesignerMetadata : IRegisterMetadata { public void Register() { AttributeTableBuilder attributeTableBuilder = new AttributeTableBuilder(); attributeTableBuilder.AddCustomAttributes(typeof(TutorialForHabr), new DesignerAttribute(typeof(Designer.TutorialForHabrDesigner))); MetadataStore.AddAttributeTable(attributeTableBuilder.CreateTable()); } } }
- Exécutez la construction
- Et mettez à jour le package dans UiPath Studio.
NB Pour que cela fonctionne pour vous, il est nécessaire que la version du nouveau package soit différente de la version de l'ancien. La façon la plus simple de le faire est d'utiliser un plug-in Visual Studio, tel que le complément Build Version Increment . Ou mettez à jour la version manuellement.
Voici la vue finale de notre action, avec une icône et des champs de saisie:

Conclusion
J'espère avoir pu montrer que la création d'actions même entièrement cadrées pour UiPath n'est pas si longue. J'aimerais vraiment que cet article vous soit utile et serve de bon début pour écrire de nouvelles et merveilleuses activités pour UiPath. Et lorsque vous le créez, n'oubliez pas de le publier sur UiPath Go!
Matériel supplémentaire