Partilhar via


Criar Power Automate para ações de ambiente de trabalho através do SDK de Ações

Este artigo descreve como criar ações personalizadas no Power Automate para ambiente de trabalho.

Criar ações personalizadas

Importante

Palavras-chave reservadas não podem ser usadas como nomes de ações e/ou propriedades de ações. O uso de palavras-chave reservadas como nomes de ações e/ou propriedades de ações resulta em comportamento erróneo. Mais informações: Palavras-chave reservadas em fluxos de ambiente de trabalho

Comece por criar um novo projeto Biblioteca de Classes (.NET Framework). Selecione .NET framework versão 4.7.2.

Para formar uma ação no módulo personalizado criado:

  • Elimine o ficheiro Class1.cs gerado automaticamente.
  • Crie uma nova classe dentro do projeto para representar a ação personalizada e dê-lhe um nome diferente.
  • Inclua os espaços de nomes Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK e Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes.
  • Todas as classes que representam ações devem ter um atributo [Ação] acima da sua classe.
  • A classe deve ter acesso público e herdar da classe ActionBase.
using System;
using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK;
using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes;

namespace Modules.MyCustomModule
{
    [Action(Id = "CustomAction")]
    public class CustomAction : ActionBase
    {
        public override void Execute(ActionContext context)
        {
            throw new NotImplementedException();
        }
    }
}

A maioria das ações têm parâmetros (Entrada e Saída). Os parâmetros de Entrada e Saída são representados pelas propriedades C# clássicas. Cada propriedade deve ter um atributo C# adequado, quer seja [InputArgument] ou [OutputArgument] para ditar o tipo e a forma como são apresentadas no Power Automate para ambiente de trabalho. Os argumentos de entrada também podem ter valores predefinidos.

using System.ComponentModel;
using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK;
using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes;

namespace Modules.MyCustomModule
{
    [Action(Id = "CustomAction")]
    public class CustomAction : ActionBase
    {
        [InputArgument, DefaultValue("Developer")]
        public string InputName { get; set; }

        [OutputArgument]
        public string DisplayedMessage { get; set; }

        public override void Execute(ActionContext context)
        {
            DisplayedMessage = $"Hello, {InputName}";
        }
    }
}

Adicionar descrições a ações personalizadas

Adicione uma descrição e um nome amigável aos módulos e ações, para que os programadores da RPA saibam como os utilizar da melhor forma.

O estruturador do Power Automate para ambiente de trabalho mostra nomes amigáveis e descrições.

Pode criar um ficheiro "Resources.resx" dentro da pasta Propriedades do projeto do módulo. O novo ficheiro ".resx" deve ter o nome "Resources.resx".

O formato das descrições para Módulos e Ações deve ter o seguinte aspeto:

"Module_Description" ou "Action_Description" e "Module_FriendlyName" ou "Action_FriendlyName" respetivamente no campo de nome. A descrição no campo valor.

Também recomendamos que forneça descrições e nomes amigáveis aos parâmetros. O seu formato deve ser o seguinte: "Action_Parameter_Description", "Action_Parameter_FriendlyName".

Captura de ecrã de Recursos para uma ação simples

Gorjeta

Recomenda-se que denote aquilo que está a descrever no campo comentário (por ex.: Módulo, Ação, etc.)

Estas também podem ser definidas com as propriedades FriendlyName e Descrição dos atributos [InputArgument], [OutputArgument] e [Action].

Eis um exemplo de um ficheiro Resources.resx para um módulo personalizado.

Captura de ecrã de Recursos

Outra forma de adicionar rapidamente nomes amigáveis e descrições a ações e parâmetros é com as propriedades FriendlyName e Descrição nos atributos [Ação], [InputArguement] e [OutputArguement].

Nota

Para adicionar um nome amigável e uma descrição a um módulo, deve modificar o respetivo ficheiro .resx ou adicionar os respetivos atributos C#.

Localização de recursos

O idioma predefinido dos módulos no Power Automate para ambiente de trabalho é o inglês.

O ficheiro Resources.resx deve estar em inglês.

Quaisquer outros idiomas podem ser adicionados com ficheiros Resources.{locale}.resx para localização. Por exemplo, Resources.fr.resx.

Categorias de módulo personalizado

Os módulos podem incluir categorias e subcategorias para uma melhor organização de ação.

Para separar ações personalizadas em categorias, subcategorias,modifique o atributo [Ação] , que precede a classe que representa a a ação personalizada da seguinte forma:

[Action(Category = "category.subcategory")]

Nota

Um Módulo pode ter várias categorias. Do mesmo modo, as categorias podem ser compostas por subcategorias. Esta estrutura pode ser indefinida.

A propriedade Ordem dita a ordem pela qual as ações são pré-visualizadas no estruturador.

Action1 pertence à categoria "TestCategory" e é a primeira ação do módulo (desta forma pode explicar Ordem e categoria com um exemplo).

[Action(Id = "Action1", Order = 1, Category = "TestCategory")]

Ações condicionais

As ações condicionais são ações que devolvem "Verdadeiro" ou "Falso". A ação "Se o ficheiro existir" do Power Automate para ambiente de trabalho da biblioteca padrão, é um bom exemplo de uma ação condicional.

Exemplo de ação condicional:

using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK;
using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes;
using System;
using System.ComponentModel;

namespace Modules.CustomModule
{
    [ConditionAction(Id = "ConditionalAction1", ResultPropertyName = nameof(Result))]
    [Throws("ActionError")] // TODO: change error name (or delete if not needed)
    public class ConditionalAction1 : ActionBase
    {
        #region Properties

        public bool Result { get; private set; }

        [InputArgument]
        public string InputArgument1 { get; set; }

        #endregion

        #region Methods Overrides

        public override void Execute(ActionContext context)
        {
            try
            {
                //TODO: add action execution code here
            }
            catch (Exception e)
            {
                if (e is ActionException) throw;

                throw new ActionException("ActionError", e.Message, e.InnerException);
            }
        }

        #endregion
    }
}

Repare na variável booleana Resultado.

A ação Se o ficheiro existir não tem um argumento de saída. O que devolve é verdadeiro ou falso, dependendo do que contém a variável booleana Resultado.

Seletores de ação personalizados

Existem casos específicos nos quais pode ser necessária uma ação personalizada para ter mais de uma variação.

Um exemplo é a ação "Iniciar o Excel", a partir da biblioteca padrão de ações.

Utilizando o seletor "com um documento em branco", o fluxo inicia um documento do Excel em branco, enquanto que a utilização da seleção "e abrir o seguinte documento" requer o caminho de ficheiro do ficheiro a abrir.

Captura de ecrã dos seletores da ação Iniciar o Excel

As duas ações mencionadas acima são dois seletores da ação base "Iniciar o Excel".

Ao criar ações personalizadas, não tem de reescrever a funcionalidade.

Pode criar uma única Ação "base", definindo os parâmetros de entrada e saída e, em seguida, selecionando o que poderia ser visível em cada sabor ao usar seletores de ação.

Através de seletores de ação, pode ser adicionado um nível de abstração ao longo de uma única ação, permitindo a obtenção de funcionalidades específicas a partir da única ação "base" sem ter de reescrever código para formar sempre uma nova variação da mesma ação.

Pense nos seletores como opções, filtrando uma única ação e apresentando apenas a informação necessária de acordo com os respetivos seletores.

Captura de ecrã do diagrama de seletores de ação

Para formar um novo seletor de ação, crie primeiro uma ação base a ser utilizada pelos seletores.

A ação central necessita de uma propriedade booleana ou de enumeração como um argumento C# de entrada.

O valor desta propriedade determina o seletor que é utilizado.

A forma mais comum é utilizar uma enumeração. Especialmente quando são necessários mais de dois seletores, as enumerações são a única opção.

Para dois casos de seletor, é possível utilizar booleano.

Esta propriedade, também conhecida como argumento de restrição, deve ter um valor predefinido.

A ação central é declarada como uma ação clássica.

Note que a primeira propriedade (argumento de entrada) é uma enumeração. Com base no valor dessa propriedade, o seletor adequado fica ativo.

Nota

Para ter os argumentos ordenados da forma que pretende, deve definir o valor Ordem junto ao atributo InputArgument.

using System.ComponentModel;
using Microsoft.PowerPlatform.PowerAutomate.Desktop.Desktop.Actions.SDK;
using Microsoft.PowerPlatform.PowerAutomate.Desktop.Desktop.Actions.SDK.Attributes;

namespace Modules.CustomModule
{
    [Action(Id = "CentralCustomAction")]
    public  class CentralCustomAction : ActionBase
    {
        #region Properties

        [InputArgument, DefaultValue(SelectorChoice.Selector1)]
        public SelectorChoice Selector { get; set; }

        [InputArgument(Order = 1)]
        public string FirstName { get; set; }

        [InputArgument(Order = 2)]
        public string LastName { get; set; }

        [InputArgument(Order = 3)]
        public int Age { get; set; }

        [OutputArgument]
        public string DisplayedMessage { get; set; }

        #endregion

        #region Methods Overrides

        public override void Execute(ActionContext context)
        {
            if (Selector == SelectorChoice.Selector1)
            {
                DisplayedMessage = $"Hello, {FirstName}!";
            }
            else if (Selector == SelectorChoice.Selector2)
            {
                DisplayedMessage = $"Hello, {FirstName} {LastName}!";
            }
            else // The 3rd Selector was chosen 
            {
                DisplayedMessage = $"Hello, {FirstName} {LastName}!\nYour age is: {Age}";
            }
        }

        #endregion
    } // you can see below how to implement an action selector
}

Seletores de ação personalizados utilizando enumerações

Neste exemplo, são criado três seletores. Uma enumeração simples dita o seletor apropriado de cada vez que:

public enum SelectorChoice
{
    Selector1,
    Selector2,
    Selector3
}

Os seletores são representados por classes.

Essas classes têm de herdar a ActionSelector<TBaseActionClass> classe.

Nota

TBaseActionClass é o nome da classe da ação base.

No método UseName(), é declarado o nome do seletor da ação. É utilizado como nome da ação para resolver os recursos.

public class Selector1 : ActionSelector<CentralCustomAction>
{
    public Selector1()
    {
        UseName("DisplayOnlyFirstName");
        Prop(p => p.Selector).ShouldBe(SelectorChoice.Selector1);
        ShowAll();
        Hide(p => p.LastName);
        Hide(p => p.Age);
        // or 
        // Show(p => p.FirstName); 
        // Show(p => p.DisplayedMessage);
    }
}

Nota

As classes do Seletor não devem ser declaradas como ações. A única ação é a central. Os seletores agem como filtros.

Neste exemplo específico, pretendemos apresentar apenas um dos argumentos, pelo que os outros são filtrados para fora. O mesmo acontece com o Seletor2:

public class Selector2 : ActionSelector<CentralCustomAction>
{
    public Selector2()
    {
        UseName("DisplayFullName");
        Prop(p => p.Selector).ShouldBe(SelectorChoice.Selector2);
        ShowAll();
        Hide(p => p.Age);
    }
}

E classes do Seletor3 :

public class Selector3 : ActionSelector<CentralCustomAction>
{
    public Selector3()
    {
        UseName("DisplayFullDetails");
        Prop(p => p.Selector).ShouldBe(SelectorChoice.Selector3);
        ShowAll();
    }
}

A execução final é alcançada através do método Execute(ActionContext context) que reside na ação central. Com base no seletor, são apresentados os respetivos valores filtrados.

public override void Execute(ActionContext context)
{
    if (Selector == SelectorChoice.Selector1)
    {
        DisplayedMessage = $"Hello, {FirstName}!";
    }
    else if (Selector == SelectorChoice.Selector2)
    {
        DisplayedMessage = $"Hello, {FirstName} {LastName}!";
    }
    else // The 3rd Selector was chosen 
    {
        DisplayedMessage = $"Hello, {FirstName} {LastName}!\nYour age is: {Age}";
    }
}

Seletores de ação personalizados utilizando booleano

Em seguida, pode ver um exemplo utilizando booleano em vez enumerações.

using System.ComponentModel;
using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK;
using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.ActionSelectors;
using Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes;

namespace Modules.CustomModule
{
    [Action]
    public class CentralCustomActionWithBoolean : ActionBase
    {
        #region Properties

        [InputArgument, DefaultValue(true)]
        public bool TimeExpired { get; set; }

        [InputArgument]
        public string ElapsedTime { get; set; }

        [InputArgument]
        public string RemainingTime { get; set; }

        [OutputArgument]
        public string DisplayedMessage { get; set; }

        #endregion

        #region Methods Overrides

        public override void Execute(ActionContext context)
        {
            DisplayedMessage = TimeExpired ? $"The timer has expired. Elapsed time: {ElapsedTime}" : $"Remaining time: {RemainingTime}";
        }

        #endregion
    }

    public class NoTime : ActionSelector<CentralCustomActionWithBoolean>
    {
        public NoTime()
        {
            UseName("TimeHasExpired");
            Prop(p => p.TimeExpired).ShouldBe(true);
            ShowAll();
            Hide(p => p.RemainingTime);
        }
    }

    public class ThereIsTime : ActionSelector<CentralCustomActionWithBoolean>
    {
        public ThereIsTime()
        {
            UseName("TimeHasNotExpired");
            Prop(p => p.TimeExpired).ShouldBe(false);
            ShowAll();
            Hide(p => p.RemainingTime);
        }
    }
}

Definir descrições para seletores de ação personalizados

Para criar uma descrição e um resumo para seletores, utilize o seguinte formato no ficheiro .resx do módulo personalizado.

SelectorName_Description
SelectorName_Summary

Isto também pode ser feito no seletor com os métodos WithDescription e WithSummary.

Importante

Os ficheiros .dll que descrevem as ações personalizadas, as suas dependências .dll e o ficheiro .cab que contém tudo devem ser corretamente assinados com um certificado digital fidedigno pela sua organização. O certificado também deve ser instalado em todos os computadores em que um fluxo de ambiente de trabalho com dependências de ação personalizadas é criado/modificado/executado, presente sob as Autoridades de Certificação de Raiz Fidedigna.

ID de módulo personalizado

Cada módulo tem o seu próprio ID (nome do assemblagem). Quando criar módulos personalizados, certifique-se de que configura ID de módulo exclusivos. Para definir o nome da assemblagem do seu módulo, modifique a propriedade Nome da assemblagem na secção Geral das propriedades do projeto C#.

Aviso

A inclusão de módulos com o mesmo ID num fluxo irá resultar em conflitos

Convenções de nomes de módulos personalizados

Para que os módulos personalizados sejam legíveis através do Power Automate para ambiente de trabalho, o AssemblyName deve ter um nome de ficheiro que siga o padrão abaixo:

?*.Modules.?*
Modules.?*

Por exemplo, Módulos.ContosoActions.dll

O AssemblyTitle nas definições do projeto especifica o ID do módulo. Só pode ter carateres alfanuméricos e underscores e tem de começar por uma letra.

Assinar todas as DLLs dentro do módulo personalizado

Importante

É obrigatório ter todos os ficheiros .dll que compõem um módulo personalizado (assemblagem gerada e todas as suas dependências) assinados com um certificado fidedigno

Para finalizar a criação do módulo personalizado, todos os ficheiros .dll gerados, que podem ser encontrados na pasta bin/release ou bin/Debug do projeto, devem ser assinados.

Assine todos os ficheiros .dll usando um certificado fidedigno ao executar o seguinte comando (para cada ficheiro .dll) na Linha de comandos para programadores para o Visual Studio:

Assine os ficheiros .dlls usando um certificado fidedigno ao executar o seguinte comando (para cada ficheiro dll) na Linha de comandos para programadores para o Visual Studio:

Signtool sign /f {your certificate name}.pfx /p {your password for exporting the certificate} /fd 
SHA256 {path to the .dll you want to sign}.dll

ou executando o seguinte comando (criando um Script .ps1 do Windows PowerShell) que itera por todos os ficheiros .dll e assina cada um deles com o certificado fornecido:

Get-ChildItem {the folder where dll files of custom module exist} -Filter *.dll | 
Foreach-Object {
	Signtool sign /f {your certificate name}.pfx /p {your password for exporting the certificate} /fd SHA256 $_.FullName
}

Nota

O certificado digital deve ter uma chave privada exportável e capacidades de assinatura de código

Embalar tudo num ficheiro CAB

O .dll que contém as ações personalizadas e todas as suas dependências (ficheiros .dll) deve ser empacotado num ficheiro CAB (.cab).

Nota

Quando nomear o ficheiro .cab, siga a convenção de nomenclatura de ficheiros e pastas para o sistema operativo Windows. Não utilize espaços em branco ou caráteres especiais, como < > : " / \ | ? * .

Crie um Script de Windows PowerShell (.ps1) que contenha as seguintes linhas:

param(

    [ValidateScript({Test-Path $_ -PathType Container})]
	[string]
	$sourceDir,
	
	[ValidateScript({Test-Path $_ -PathType Container})]
    [string]
    $cabOutputDir,

    [string]
    $cabFilename
)

$ddf = ".OPTION EXPLICIT
.Set CabinetName1=$cabFilename
.Set DiskDirectory1=$cabOutputDir
.Set CompressionType=LZX
.Set Cabinet=on
.Set Compress=on
.Set CabinetFileCountThreshold=0
.Set FolderFileCountThreshold=0
.Set FolderSizeThreshold=0
.Set MaxCabinetSize=0
.Set MaxDiskFileCount=0
.Set MaxDiskSize=0
"
$ddfpath = ($env:TEMP + "\customModule.ddf")
$sourceDirLength = $sourceDir.Length;
$ddf += (Get-ChildItem $sourceDir -Filter "*.dll" | Where-Object { (!$_.PSIsContainer) -and ($_.Name -ne "Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.dll") } | Select-Object -ExpandProperty FullName | ForEach-Object { '"' + $_ + '" "' + ($_.Substring($sourceDirLength)) + '"' }) -join "`r`n"
$ddf | Out-File -Encoding UTF8 $ddfpath
makecab.exe /F $ddfpath
Remove-Item $ddfpath

Este Script de Windows PowerShell pode, em seguida, ser utilizado para criar o ficheiro .cab, invoindo-o em Windows PowerShell e fornecendo:

  • O diretório para os ficheiros .dll a comprimir.
  • O diretório de destino para colocar o ficheiro .cab gerado.

Invocar o script utilizando a seguinte sintaxe:

.\{name of script containing the .cab compression directions}.ps1 "{absolute path  to the source directory containing the .dll files}" "{target dir to save cab}" {cabName}.cab

Exemplo:

.\makeCabFile.ps1 "C:\Users\Username\source\repos\MyCustomModule\bin\Release\net472" "C:\Users\Username\MyCustomActions" MyCustomActions.cab

Nota

  • Certifique-se de que o ficheiro .dll de ações personalizadas reais está no nível raiz do caminho de destino ao criar o ficheiro .cab e não numa subpasta.
  • O ficheiro .cab também tem de ser assinado. Os ficheiros .cab não assinados e/ou .dlls não assinados contidos nos mesmos não serão usáveis nos fluxos de ambiente de trabalho e resultarão em erro durante a inclusão.

Próximos passos

Carregar ações personalizadas

Consulte também