Todo tuyo: Tutorial sobre la creación de nuevas acciones para UiPath RPA

Este artículo es un material de capacitación que lo guía a través del proceso de creación y publicación de un nuevo componente para la plataforma UiPath RPA . Esto es conveniente en diferentes casos, por ejemplo, para una integración simple con los sistemas de la compañía o en situaciones en las que la compañía quiere ayudar a los empleados que no tienen un conocimiento particular en programación para crear sus propios procesos para robots. Pero, me parece, esta técnica funciona especialmente bien para los casos en que necesita integrar su producto en el ecosistema de la robótica, lo que permite a los usuarios configurar la integración de procesos internos en un par de clics. Un ejemplo es el conector escrito por Abbyy para su producto Abbyy Flexicapture Distributed . Otro ejemplo es el propio UiPath, que implementó la conexión a su nuevo módulo ML para visión por computadora (Computer Vision en el administrador de paquetes), acciones para trabajar con PDF, etc.


¡Ahora en la tienda de aplicaciones UiPath Go! Ya en pleno apogeo comenzaron a aparecer conectores para soluciones populares como Salesforce o ServiceNow, y lo más probable es que esta tendencia solo esté ganando popularidad.


Entonces, ¿cómo comienzas a desarrollar tu propia acción?


Nota: en inglés, una acción es una actividad, recuerde esto si necesita buscar algo en Google

Si no tiene ganas de hacer todas las configuraciones, puede probar el código de ejemplo que se tomó en los pasos de este tutorial. Se encuentra en GitLab . El código en el artículo se acorta y se simplifica, está disponible en Yandex Disk


Robot construye acción para UiPath


Lo que necesitamos antes de comenzar a trabajar:


  1. Visual Studio (la versión gratuita de VS Community Edition es perfecta. Durante la instalación, debe seleccionar .NET Desktop Development o especificar manualmente los siguientes paquetes:
    1. Administrador de paquetes Nuget
    2. Paquete de orientación de .NET Framework 4.6.1 (se necesita 4.6)
    3. C # y Visual Basic (las acciones se pueden escribir en cualquier lenguaje .NET, pero, tradicionalmente, se usa C # o VB.NET). Este tutorial usará C #.
    4. Windows Workflow Foundation
  2. UiPath Studio (y aquí lo mismo, CE gratuito, solo tiene que completar el formulario de solicitud de la edición de la comunidad UiPath ).
    NB Para el desarrollo de la acción en sí, no la necesitamos, pero, por supuesto, quiero ver qué haremos.
  3. NuGet Package Manager (incluido con VS 2017+ o descargado de Nuget.org

Comienza a crear


Crea un proyecto en VS


  1. Cree un proyecto de C# Class Library (.NET Framework) . Tenga en cuenta que las variaciones en el tema (por ejemplo , Biblioteca de clases C # (.NET Standard) ) no nos convienen.

Pantalla de creación de proyectos


  1. Elegimos un nombre significativo para él (el formato habitual <Developer> .UiPath.Activities. <Nombre del proyecto> ) e indicamos que queremos usar .NET Framework 4.6.1 .
    La identificación del paquete NuGet debe contener la palabra Actividades. Como queremos tomar todo de VS, es mejor nombrar el proyecto correctamente de inmediato para que pueda retomarlo en NuGet más adelante.

Pantalla de configuración del proyecto


  1. En el proyecto creado, creamos las siguientes subcarpetas (este es un paso opcional, pero es más conveniente trabajar con paquetes de acciones cuando desea proporcionar a los usuarios más de una acción a la vez y la cantidad de archivos comienza a acumularse):
    • Actividades (aquí tendremos un código de acción)
    • Diseñador (aquí tendremos la forma de ventanas de acción)
    • Recursos (aquí almacenaremos imágenes, íconos y otras cosas necesarias)
  2. Cambie el nombre del archivo Class1.cs que creamos en VS de acuerdo con el nombre de nuestra primera acción y muévalo a la carpeta Actividades.

Estructura de carpetas del proyecto


Fácil creación y publicación de acciones.


En este punto, tenemos un proyecto vacío compilado en .dll . Ahora pasemos a crear la acción misma.


Nota: dado que UiPath admite varios idiomas, al final necesitaremos agregar localización y cambiar ligeramente lo que estamos haciendo ahora, pero comencemos con lo que es necesario y suficiente.

  1. Necesitamos dos using :
     using System; using System.Activities; 
  2. CodeActivity nuestra clase de CodeActivity :
     public class TutorialForHabr: CodeActivity {} 
  3. Establecemos los parámetros de entrada y salida:
     public class TutorialForHabr: CodeActivity { public InArgument<Int32> Row { get; set; } public InArgument<Int32> Column { get; set; } public OutArgument<String> Cell { get; set; } } 

    NB Los parámetros de acción son InArgument< > entrada InArgument< > , OutArgument< > salida OutArgument< > y combinados, lo que permite recibir y recibir parámetros InOutArgument< >
  4. Y el método Execute , que es el único método que definitivamente debemos establecer:
     protected override void Execute(CodeActivityContext context) { string colstr = ""; //   Row Int32 row = Row.Get(context); //   Column Int32 column = Column.Get(context); //    Excel do { column--; //26    ,    Excel,      ,  Z  AA int modn = column % 26; colstr = (char)((int)'A' + modn) + colstr; //A     Excel column /= 26; } while (column > 0); //   Cell  Cell.Set(context, colstr + row.ToString()); } 

En esta etapa, tenemos una acción de trabajo para UiPath que implementa una funcionalidad simple pero necesaria.
Lo publicaremos, luego pasaremos a la segunda parte y retomaremos un poco las "decoraciones".


Publicar a través de NuGet


Puede crear un paquete NuGet a través de la GUI de NuGet Package Manager o mediante la línea de comandos llamando nuget.exe pack . El comando pack acepta dos parámetros principales como entrada: el nombre del archivo de proyecto .csproj o el nombre del archivo .nuspec que contiene la metainformación del paquete. La primera opción no nos permite, sin modificaciones manuales adicionales del archivo .json, establecer algunas propiedades del paquete que son importantes para nosotros, por ejemplo, etiquetas, licencia o URL del repositorio, además no nos permite establecer un icono para el proyecto que será visible en el administrador de paquetes.
En la segunda variante, duplicamos algunas propiedades del paquete, que, sin embargo, podrían tomarse automáticamente de Visual Studio.
Por lo tanto, iremos por la ruta 1.5 y crearemos un archivo con la extensión .nuspec en la raíz del proyecto (el nombre no importa, solo hay uno de esos archivos), que contendrá la información que no se puede obtener de .csproj y combinaremos estas dos fuentes de datos.


 <?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> 

Como puede ver, la estructura de .nuspec es bastante obvia. Si no quiere meterse con XML, puede crearlo a través del editor visual NuGet Package Manager y guardarlo en la carpeta del proyecto para usarlo en el futuro. Las variables como $copyright se toman de la información contenida en el archivo .dll, es decir de Visual Studio.
Ahora queremos usar nuestro .nuspec para que con cada compilación obtengamos un nuevo paquete. Para hacer esto, vamos a Propiedades y vamos a la pestaña Crear Eventos.
Escriba palabras mágicas en una línea de comando de evento posterior a la compilación

 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\" 

que, traducido al ruso, significa


  1. Eliminar paquetes antiguos en la carpeta donde se crea la compilación
  2. Cree un nuevo paquete utilizando archivos .csproj y .nuspec
  3. Póngalo en la carpeta C:\Program Files (x86)\UiPath\Studio\Packages\

¿Qué es esta carpeta? Este es el repositorio de paquetes local utilizado por UiPath Studio. Tan pronto como aparezca un nuevo paquete, estará disponible automáticamente a través del administrador de paquetes y será posible agregarlo a los procesos de robotización.


Ventana del administrador de paquetes de UiPath Studio


Nota : la ruta al repositorio local se puede cambiar a través de la configuración de UiPath Studio para que sea conveniente copiar archivos allí si hay un problema con los permisos.

Pantalla de UiPath Studio con la acción creada y su configuración


Eso es todo, en realidad, ¡felicidades!


Nota : tenga en cuenta que Smart Studio creó una categoría para nuestra acción, utilizando puntos como niveles de anidación, y coloca espacios delante de las letras mayúsculas en el nombre de la acción.

La siguiente parte del artículo será sobre "belleza": sobre cómo hacer una interfaz visual para una acción, asignar un icono y localizar textos.


Serio


Atributos


Para que nuestra acción funcione, la primera parte es suficiente. Pero quiero que podamos elegir una categoría, mostrar consejos, etc.
Para esto necesitamos atributos. Hay atributos que son adecuados para la acción en sí y para sus parámetros:


 [Category ("   ,     ")] [DisplayName ("    ")] [Description ("    ")] 

Y hay aquellos que solo son parámetros necesarios:


 [RequiredArgument] //    [DefaultValue(1)] //       

Localización


Desafortunadamente, hay una sutileza con los atributos: en la versión rusa de UiPath Studio, los nombres de las categorías de acción y las categorías de sus propiedades también se traducen. En consecuencia, si establecemos el atributo [Category("Input")] para el parámetro de entrada, se mostrará correctamente en la versión en inglés, pero en la versión en ruso caerá en su propia categoría de Entrada separada, y no en la categoría de Entrada estándar. Lo mismo ocurre con las acciones; en la versión rusa, la integración de aplicaciones se convierte en integración de aplicaciones .
Por lo tanto, debemos mover las constantes de texto a recursos dependientes del idioma y usarlas desde allí.
Para hacer esto, cree un archivo mágico Localization.cs que contenga funciones para localizar atributos


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

Nos permitirá reemplazar el diseño.


 [Category("Name") 

en


 [LocalizedCategory(nameof(Resources.CategoryName))] 

Para que este mecanismo funcione, debemos:


  1. Cree archivos de recursos para los idiomas que vamos a traducir, en nuestro caso, Resources.resx y Resources.ru.resx en la carpeta Resources ( Agregar -> Nuevo elemento -> Archivo de recursos ). Asegúrese de que el valor del Modificador de acceso para los recursos esté en Público .
  2. Agregar al archivo de acción de clase
     using IlyaK.UiPath.Activities.TutorialForHabr.Properties; //     + .Properties 
  3. Y establezca la clase y todos los parámetros con los atributos apropiados.


     [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))] } 

  4. Para que la biblioteca con recursos rusos caiga en el paquete NuGet, debe agregar otra línea al grupo de archivos en el archivo .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> 

El diseñador


Para hacer que nuestra acción se vea hermosa en el proceso y permitir que los usuarios ingresen datos sin arrastrarse a las propiedades, necesitamos agregar una IU. Esto se realiza a través de un archivo XAML, que, con la ayuda de Visual Studio, se puede editar en una interfaz especial, pero parte aún tendrá que repararse manualmente. Le daré una plantilla para comenzar, y luego vale la pena echarle un vistazo a la documentación de Microsoft .


  • Coloque el icono de la acción en la carpeta Resources . En las propiedades de la Acción de compilación establecida en Recurso (no Recurso incrustado )
  • Cree un nuevo Diseñador de actividades ( Agregar -> Nuevo elemento -> Diseñador de actividades ) en la carpeta Designer y llámelo 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> 

Así es como configuramos la etiqueta localizada:


 <TextBlock Grid.Row="0" Grid.Column="0" Text="{x:Static resource:Resources.RowName}" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,5,0" /> 

, y este es el campo de entrada. ExpressionType establece el tipo de campo, HintText : una pista (texto gris) para ello, Expression asocia el valor del campo con nuestra acción


 <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 Observe la etiqueta BitmapImage al final del archivo. Así que configuramos la imagen para el icono con un enlace al archivo de recursos. Esta es una funcionalidad muy frágil y a veces tienes que jugar con ella.

Según los resultados, debería ser así:


pantalla de diseñador de acción


  • Cree la clase DesignerMetata en la carpeta Actividades

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

  • Ejecute la compilación
  • Y actualice el paquete en UiPath Studio.
    Nota: para que esto funcione, es necesario que la versión del nuevo paquete sea diferente de la versión anterior. La forma más fácil de hacerlo es con algunos complementos de Visual Studio, como el Complemento Incremento de versión de compilación . O actualice la versión manualmente.

Aquí está la vista final de nuestra acción, con un icono y campos de entrada:
acción terminada


Conclusión


Espero haber podido demostrar que crear acciones incluso completamente enmarcadas para UiPath no es tan largo. Realmente me gustaría que este artículo sea útil para usted y sirva como un buen comienzo para escribir actividades nuevas y maravillosas para UiPath. Y cuando lo cree, ¡no olvide publicarlo en UiPath Go!


Materiales adicionales


Source: https://habr.com/ru/post/453510/


All Articles