Creați Power Automate acțiuni pentru desktop folosind SDK-ul Actions
Acest articol descrie cum să creați acțiuni personalizate în Power Automate pentru desktop.
Crearea de acțiuni personalizate
Important
Cuvintele cheie rezervate nu pot fi folosite ca nume de acțiuni și/sau proprietăți de acțiune. Utilizarea cuvintelor cheie rezervate ca nume de acțiuni și/sau proprietăți de acțiune are ca rezultat un comportament eronat. Mai multe informații: Cuvinte cheie rezervate în fluxurile desktop
Începeți prin a crea un nou proiect Bibliotecă de clasă (.NET Framework). Selectați .NET Framework versiunea 4.7.2.
Pentru a forma o acțiune în modulul personalizat creat:
- Ștergeți fișierul Class1.cs generat automat.
- Creați o nouă clasă în interiorul proiectului pentru a reprezenta acțiunea personalizată, oferindu-i un nume distinct.
- Includeți spațiile de nume Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK și Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes.
- Toate clasele care reprezintă acțiuni ar trebui să aibă un atribut [Acțiune] deasupra clasei dvs.
- Clasa ar trebui să aibă acces public și să moștenească din clasa 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();
}
}
}
Majoritatea acțiunilor au parametri (Input sau Output). Parametrii de intrare și de ieșire sunt reprezentați de proprietățile clasice C#.
Fiecare proprietate ar trebui să aibă un atribut C# adecvat, fie [InputArgument]
sau [OutputArgument]
pentru a-i dicta tipul și modul în care sunt prezentate în Power Automate pentru desktop.
Argumentele de intrare pot avea și valori implicite.
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}";
}
}
}
Adăugarea de descrieri la acțiunile personalizate
Adăugați o descriere și un nume prietenos pentru module și acțiuni, astfel încât dezvoltatorii RPA să știe cum să le utilizeze cel mai bine.
Power Automate pentru desktop designerul arată nume și descrieri prietenoase.
Puteți crea un fișier „Resources.resx” în folderul Proprietăți al proiectului modulului. Noul fișier „.resx” ar trebui să fie numit „Resources.resx”.
Formatul descrierilor pentru module și acțiuni ar trebui să fie după cum urmează:
„Module_Description” sau „Action_Description” și „Module_FriendlyName” sau, respectiv, „Action_FriendlyName” în câmpul de nume. Descrierea în câmpul de valoare.
De asemenea, vă recomandăm să furnizați descrieri și nume prietenoase pentru parametri. Formatul lor ar trebui să fie după cum urmează: „Action_Parameter_Description”, „Action_Parameter_FriendlyName”.
Sfat
Este recomandat să indicați ceea ce descrieți în câmpul de comentarii (de exemplu, Modul, Acțiune etc.)
Acestea pot fi setate și cu proprietățile FriendlyName și Description ale atributelor [InputArgument]
, [OutputArgument]
și [Action]
.
Iată un exemplu de fișier Resources.resx pentru un modul personalizat.
O altă modalitate de a adăuga rapid nume și descrieri prietenoase la acțiuni și parametri este cu proprietățile FriendlyName și Description din [Acțiune], [InputArguement] și [OutputArguement] atribute.
Notă
Pentru a adăuga un nume prietenos și o descriere unui modul, trebuie să modificați fișierul .resx respectiv sau să adăugați atributele C# respective.
Adăugarea gestionării erorilor la acțiunile personalizate
Pentru a defini excepții personalizate în acțiunea dvs., utilizați atributul [Throws("ActionError")]
de deasupra clasei de acțiune personalizată. Fiecare caz de excepție pe care doriți să îl definiți ar trebui să aibă propriul său atribut.
În blocul catch, utilizați următorul cod:
throw new ActionException("ActionError", e.Message, e.InnerException);
Asigurați-vă că ActionException
numele se potrivește cu numele pe care l-ați furnizat în atributul Throws
. Folosiți throw new ActionException
pentru fiecare caz de excepție și potriviți-l cu numele atributului Throws
corespunzător. Toate excepțiile definite cu atributul Throws
sunt vizibile în fila de gestionare a erorilor de acțiune a designerului.
Un exemplu în acest sens poate fi găsit în secțiunea Acțiuni condiționate .
Localizarea resurselor
Se presupune că limba implicită pentru modulele din Power Automate pentru desktop este engleza.
Resources.resx Fișierul trebuie să fie în engleză.
Orice alte limbi pot fi adăugate cu Resurse suplimentare.{locale}Fișiere .resx pentru localizare. De exemplu, Resources.fr.resx.
Categorii de module personalizate
Modulele pot include categorii și subcategorii pentru o mai bună organizare a acțiunii.
Pentru a separa acțiunile personalizate în categorii, subcategorii, modificați atributul [Action] care precede clasa care reprezintă acțiunea personalizată în felul următor:
[Action(Category = "category.subcategory")]
Notă
Un modul poate avea mai multe categorii. În mod similar, categoriile pot fi cuprinse în subcategorii. Această structură poate fi nedefinită.
Proprietatea Order dictează ordinea în care acțiunile sunt previzualizate în designer.
Action1
aparține categoriei „TestCategory” și este prima acțiune a modulului (în acest fel explicați Ordinea și categoria cu un exemplu).
[Action(Id = "Action1", Order = 1, Category = "TestCategory")]
Acțiuni condiționate
Acțiunile condiționate sunt acțiuni care returnează fie „adevărat”, fie „fals”. „Dacă fișierul există” Power Automate pentru acțiunea de pe desktop a bibliotecii standard este un bun exemplu de acțiune condiționată.
Exemplu de acțiune condiționată:
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
}
}
Observați variabila Rezultat Boolean.
Acțiunea Dacă există fișierul nu are un argument de ieșire. Ceea ce returnează este fie adevărat, fie fals, în funcție de ceea ce conține variabila Boolean Rezultat .
Selectoare de acțiuni personalizate
Există cazuri particulare, în care o acțiune personalizată ar putea fi necesară pentru a avea mai multe variante.
Un exemplu este acțiunea „Launch Excel”, din biblioteca standard de acțiuni.
Folosind selectorul „cu un document gol”, fluxul lansează un document Excel gol, în timp ce utilizarea selecției „și deschideți următorul document” necesită deschiderea căii fișierului.
Cele două acțiuni menționate mai sus sunt două selectoare ale acțiunii de bază „Launch Excel”.
Când creați acțiuni personalizate, nu trebuie să rescrieți funcționalitatea.
Puteți crea o singură acțiune „de bază”, setându-i parametrii de intrare și de ieșire și apoi alegeți ce ar fi vizibil în fiecare variantă utilizând selectoare de acțiune.
Prin intermediul selectoarelor de acțiuni se poate adăuga un nivel de abstractizare peste o singură acțiune, permițând regăsirea unei funcționalități specifice din acțiunea „de bază” unică fără a fi nevoie să rescrie codul pentru a forma o nouă variație a aceleiași acțiuni de fiecare dată.
Gândiți-vă la selectori ca la alegeri, filtrarea unei singure acțiuni și prezentând doar informațiile cerute în funcție de selectorii respectivi.
Pentru a forma un nou selector de acțiuni, creați mai întâi o acțiune de bază care să fie utilizată de selectori.
Acțiunea centrală necesită fie o proprietate Boolean, fie o proprietate enumerare ca argument C# de intrare.
Valoarea acestei proprietăți determină ce selector este utilizat.
Cea mai obișnuită modalitate este utilizarea unui enumerare. Mai ales când sunt necesare mai mult de doi selectoare, enumerarea este singura opțiune.
Pentru două cazuri de selecție, pot fi utilizați valori boolean.
Această proprietate, cunoscută și ca argument de constrângere, trebuie să aibă o valoare implicită.
Acțiunea centrală este declarată ca acțiune clasică.
Observați că prima proprietate (argument de intrare) este un enumerare. Pe baza valorii proprietății respective, selectorul corespunzător devine activ.
Notă
Pentru a avea argumentele ordonate în modul dorit, setați valoarea Order de lângă atributul 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
}
Selectoare de acțiuni personalizate folosind enumerari
În acest exemplu, creați trei selectoare. Un simplu enumerare dictează selectorul corespunzător de fiecare dată:
public enum SelectorChoice
{
Selector1,
Selector2,
Selector3
}
Selectorii sunt reprezentați prin clase.
Aceste clase trebuie să moștenească clasa ActionSelector<TBaseActionClass>
.
Notă
TBaseActionClass este numele clasei de acțiune de bază.
În metoda UseName() , numele selectorului de acțiuni este declarat. Acesta este folosit ca nume al acțiunii de rezolvare a resurselor.
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);
}
}
Notă
Clasele Selector nu trebuie declarate ca acțiuni. Singura acțiune este cea centrală. Selectoarele acționează ca filtre.
În acest exemplu specific dorim să afișăm doar unul dintre argumente, astfel celelalte sunt filtrate. În mod similar, pentru Selector2:
public class Selector2 : ActionSelector<CentralCustomAction>
{
public Selector2()
{
UseName("DisplayFullName");
Prop(p => p.Selector).ShouldBe(SelectorChoice.Selector2);
ShowAll();
Hide(p => p.Age);
}
}
Și Selector3 clase:
public class Selector3 : ActionSelector<CentralCustomAction>
{
public Selector3()
{
UseName("DisplayFullDetails");
Prop(p => p.Selector).ShouldBe(SelectorChoice.Selector3);
ShowAll();
}
}
Execuția finală se realizează prin metoda Execute(ActionContext context) care rezidă în acțiunea centrală. Pe baza selectorului sunt afișate valorile respective filtrate.
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}";
}
}
Selectoare de acțiuni personalizate folosind Boolean
Următorul este un exemplu de utilizare a Boolean în loc de enumerari.
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);
}
}
}
Setarea descrierilor pentru selectoare de acțiuni personalizate
Pentru a crea o descriere și un rezumat pentru selectori, utilizați următorul format în fișierul .resx al modulului personalizat.
SelectorName_Description
SelectorName_Summary
Acest lucru se poate face și în selector cu metodele WithDescription și WithSummary.
Important
Fișierele .DLL care descriu acțiunile personalizate, dependențele lor .DLL și fișierul .cab care conține totul ar trebui să fie semnate corespunzător cu un certificat digital de încredere de către organizația dvs. Certificatul ar trebui să fie, de asemenea, instalat pe fiecare mașină pe care este creat/modificat/executat un flux pentru desktop cu dependențe de acțiuni personalizate, prezent sub Autoritățile de certificare rădăcină de încredere.
ID-uri personalizate ale modulelor
Fiecare modul are propriul ID (numele ansamblului). Când creați module personalizate, asigurați-vă că setați ID-uri unice pentru module. Pentru a seta numele ansamblului modulului dvs., modificați proprietatea Nume ansamblu din secțiunea General a proprietăților proiectului C#.
Avertisment
Includerea modulelor cu același ID într-un flux va duce la conflicte
Convenții personalizate de nume ale modulelor
Pentru ca modulele personalizate să poată fi citite prin Power Automate pentru desktop, AssemblyName trebuie să aibă un nume de fișier care urmează modelul de mai jos:
?*.Modules.?*
Modules.?*
De exemplu, Module.ContosoActions.DLL
AssemblyTitle din setările proiectului specifică ID-ul modulului. Poate avea doar caractere alfanumerice și caractere de subliniere și trebuie să înceapă cu o literă.
Semnează toate DLL-urile în interiorul modulului personalizat
Important
Este obligatoriu să aveți toate fișierele .DLL care cuprind un modul personalizat (ansamblul generat și toate dependențele acestuia) semnate cu un certificat de încredere
Pentru a finaliza crearea modulului personalizat, toate fișierele .DLL generate, care pot fi găsite în folderul bin/release sau bin/Debug al proiectului, trebuie să fie semnate.
Semnează toate fișierele .DLL folosind un certificat de încredere, rulând următoarea comandă (pentru fiecare fișier .DLL) într-un prompt de comandă pentru dezvoltatori pentru Visual Studio:
Semnează fișierele .dlls folosind un certificat de încredere, rulând următoarea comandă (pentru fiecare DLL) într-un prompt de comandă pentru dezvoltatori pentru 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
Sau rulând următoarea comandă (prin crearea unui script Windows PowerShell .ps1) care iterează prin toate fișierele .DLL și semnează fiecare cu certificatul furnizat:
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
}
Notă
Certificatul digital trebuie să aibă o cheie privată exportabilă și capabilități de semnare a codului
Ambalarea totul într-un fișier cabinet
.DLL care conține acțiunile personalizate și toate dependențele sale (fișiere .DLL) trebuie să fie împachetate într-un fișier cabinet (.cab).
Notă
Când denumiți fișierul .cab, urmați convenția de denumire a fișierelor și folderelor pentru sistemul de operare Windows. Nu utilizați spații goale sau caractere speciale, cum ar fi < > : " / \ | ? *
.
Creați un script Windows PowerShell (.ps1) care să conțină următoarele linii:
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
Acest script Windows PowerShell poate fi folosit apoi pentru a crea fișierul .cab, invocându-l în Windows PowerShell și oferind:
- Directorul pentru fișierele .DLL care urmează să fie comprimate.
- Directorul țintă pentru a plasa fișierul .cab generat.
Invocați scriptul folosind următoarea sintaxă:
.\{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
Exemplu:
.\makeCabFile.ps1 "C:\Users\Username\source\repos\MyCustomModule\bin\Release\net472" "C:\Users\Username\MyCustomActions" MyCustomActions.cab
Notă
- Asigurați-vă că fișierul .DLL cu acțiuni personalizate efective se află la nivelul rădăcină al căii vizate atunci când creați fișierul .cab și nu într-un subdosar.
- Trebuie semnat și fișierul .cab. Fișierele .cab nesemnate și/sau .dll-urile nesemnate conținute în ele nu vor putea fi utilizate în fluxurile desktop și vor avea ca rezultat o eroare în timpul includerii.
Pașii următori
Încărcați acțiuni personalizate