Tworzenie akcji aplikacji klasycznej Power Automate przy użyciu zestawu SDK akcji
W tym artykule opisano, jak tworzyć akcje niestandardowe w aplikacji klasycznej Power Automate.
Tworzenie akcji niestandardowych
Ważne
Zastrzeżonych słów kluczowych nie można używać jako nazw akcji i/lub właściwości akcji. Użycie zastrzeżonych słów kluczowych jako nazw akcji i/lub właściwości akcji powoduje błędne zachowanie. Więcej informacji: Zastrzeżone słowa kluczowe w przepływach pulpitu
Rozpocznij od utworzenia nowego projektu biblioteki klas (.NET Framework). Wybierz program .NET Framework w wersji 4.7.2.
Aby utworzyć akcję w utworzonym module niestandardowym:
- Usuń automatycznie wygenerowany plik Class1.cs.
- Utwórz nową klasę w projekcie, aby reprezentować akcję niestandardową, nadaj jej odrębną nazwę.
- Dołącz przestrzeń nazw Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK i Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes.
- Wszystkie klasy reprezentujące akcje powinny mieć atrybut [Akcja] wyższy niż twoje klasy.
- Klasa powinna mieć dostęp publiczny i dziedziczyć po klasie 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();
}
}
}
Akcje mogą mieć parametry (wejściowe lub wyjściowe). Parametry wejściowe i wyjściowe są reprezentowane przez klasyczne właściwości języka C#.
Każda właściwość powinna mieć odpowiedni atrybut C# [InputArgument]
lub [OutputArgument]
,który określa jej typ i sposób prezentowania na pulpicie Power Automate.
Argumenty wejściowe mogą także mieć wartości domyślne.
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}";
}
}
}
Dodawanie opisów do akcji niestandardowych
Dodaj opis i przyjazną nazwę modułów i akcji, aby deweloperzy RPA wiedzieli, jak najlepiej z nich korzystać.
Power Automate projektanta pulpitu pokazuje przyjazne nazwy i opisy.
Możesz utworzyć plik Resources.resx w folderze Właściwości projektu modułu. Nowy plik .resx powinien mieć nazwę Resources.resx.
Format opisów modułów i akcji powinien być następujący:
Odpowiednio w polu nazwy Moduł_Opis lub Akcja_Opis i Moduł_PrzyjaznaNazwa lub Akcja_PrzyjaznaNazwa. Opis w polu wartość.
Zalecamy również podanie opisów i przyjaznych nazw parametrów. Ich format powinien mieć następujący format: Akcja_Parameter_Opis, Akcja_Parameter_PrzyjaznaNazwa.
Porada
Zaleca się określenia, co on opisuje w polu komentarza (np. Moduł, Akcja itp.).
Można je również ustawić za pomocą właściwości PrzyjaznaNazwa i Opis atrybutów [InputArgument]
[OutputArgument]
i [Action]
.
Oto przykład pliku moduł niestandardowego Resources.resx.
Innym sposobem na szybkie dodanie przyjaznych nazw i opisów do akcji i parametrów jest dodanie właściwości PrzyjaznaNazwa i Opis w atrybutach [Action] [InputArguement] i [OutputArguement].
Uwaga
Aby dodać przyjazną nazwę i opis do modułu, należy zmodyfikować odpowiedni plik RESX lub dodać odpowiednie atrybuty C#.
Dodawanie obsługi błędów do akcji niestandardowych
Aby zdefiniować niestandardowe wyjątki w akcji, użyj atrybutu [Throws("ActionError")]
powyżej niestandardowej klasy akcji. Każdy przypadek wyjątku, który chcesz zdefiniować, powinien mieć swój własny atrybut.
W bloku catch użyj następującego kodu:
throw new ActionException("ActionError", e.Message, e.InnerException);
Upewnij się, że nazwa ActionException
jest zgodna z nazwą podaną w atrybucie Throws
. Użyj throw new ActionException
dla każdego przypadku wyjątku i dopasuj go do odpowiedniej nazwy atrybutu Throws
. Wszystkie wyjątki zdefiniowane za pomocą atrybutu Throws
są widoczne w zakładce obsługi błędów akcji projektanta.
Przykład tego można znaleźć w sekcji Akcje warunkowe.
Lokalizacja zasobów
Domyślnym językiem modułów dla pulpitu Power Automate jest język angielski.
Plik Resources.resx powinien być w języku angielskim.
Wszystkie inne języki można dodać z dodatkowymi plikami Resources.{locale}.resx w celu lokalizacji. Na przykład: Resources.fr.resx
Niestandardowe kategorie modułu
Moduły mogą zawierać kategorie i podkategorie, aby poprawić organizację akcji.
Aby oddzielić akcje niestandardowe w kategoriach i podkategoriach zmodyfikuj atrybut [Akcja], który poprzedza klasę reprezentującą akcję niestandardową w następujący sposób:
[Action(Category = "category.subcategory")]
Uwaga
Moduł może mieć wiele kategorii. Podobnie kategorie mogą się składać z podkategorii. Ta struktura może być nieokreślona.
Właściwość Kolejność określa kolejność, według której akcje są oglądane przez projektanta.
Action1
należy do kategorii „TestCategory” i jest to pierwsza akcja modułu (w ten sposób objaśniasz kolejność i kategorię z przykładem).
[Action(Id = "Action1", Order = 1, Category = "TestCategory")]
Akcje warunkowe
Akcje warunkowe to akcje, które zwróciły wartość "Prawda" lub "Fałsz". Akcja pulpitu Power Automate „Jeśli plik istnieje” standardowej biblioteki jest dobrym przykładem akcji warunkowej.
Przykład akcji warunkowej:
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
}
}
Należy zwrócić uwagę, że Wynik jest zmienną logiczną.
Akcja Jeśli plik istnieje, nie ma argumentu wyjściowego. Wartość zwracana przez nią to Prawda lub Fałsz, w zależności od wartości logicznej zmiennej Wynik.
Niestandardowe selektory akcji
Istnieją konkretne przypadki, w których akcja niestandardowa może wymagać więcej niż jednej wersji.
Przykładem jest akcja „Launch Excel” z standardowej biblioteki akcji.
Użycie selektora "z pustym dokumentem" oznacza, że przepływ uruchamia pusty dokument programu Excel, podczas gdy użycie selektora „i otwórz następujący dokument" wymaga ścieżki pliku do otwarcia.
Dwie wymienione powyżej akcje to dwa selektory akcji podstawowej "Launch Excel".
Podczas tworzenia akcji niestandardowych nie trzeba już przepisywać funkcji.
Można utworzyć jedną akcję "podstawową", ustawić jej parametry wejściowe i wyjściowe, a następnie wybrać to, co będzie widoczne w poszczególnych wersjach, przez korzystanie z selektorów akcji.
Za pośrednictwem selektorów akcji można dodać poziom streszczenie dla jednej akcji, co pozwala na pobranie określonej funkcji z pojedynczej akcji podstawowej bez konieczności ponownego przepisywania kodu, aby za każdym razem utworzyć nową odmianę tej samej akcji.
Selektory można rozumieć jako wybory filtrujące pojedynczą akcję i prezentujące tylko wymagane według nich informacje.
Aby utworzyć nowy selektor akcji, należy najpierw utworzyć akcję podstawową, która będzie wykorzystywana przez selektory.
Akcja centralna wymaga jako argumentu wejściowego C# właściwości logicznej lub wyliczanej.
Wartość tej właściwości określa, który selektor będzie wykorzystany.
Najczęstszym sposobem jest użycie wyliczania. Szczególnie gdy jest potrzebnych więcej niż dwa selektory, jedyną opcją jest wyliczanie.
W przypadku dwóch selektorów można używać wartości logicznych.
Ta właściwość, znana również jako argument ograniczenia, musi mieć wartość domyślną.
Akcja centralna jest deklarowana jako klasyczne działanie.
Należy zauważyć, że pierwsza właściwość (argument wejściowy) jest typu wyliczanego. Na podstawie wartości tej właściwości aktywny staje się odpowiedni selektor.
Uwaga
Aby argumenty były uporządkowane w żądany sposób, należy ustawić wartość Order (Kolejność) obok atrybutu 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
}
Niestandardowe selektory akcji z zastosowaniem wyliczania
W tym przykładzie należy utworzyć trzy selektory. Proste wyliczanie określa za każdym razem odpowiedni selektor:
public enum SelectorChoice
{
Selector1,
Selector2,
Selector3
}
Selektory są reprezentowane przez klasy.
Te klasy muszą dziedziczyć klasę ActionSelector<TBaseActionClass>
.
Uwaga
TBaseActionClass to nazwa klasy akcji podstawowej.
W metodzie UseName() deklarowana jest nazwa selektora akcji. Jest ona używana jako nazwa akcji służącej do rozwiązywania zasobów.
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);
}
}
Uwaga
Klasy Selektor nie powinny być deklarowane jako akcje. Jedyną akcją jest akcja centralna. Selektory działają jako filtry.
W tym konkretnym przykładzie chcemy wyświetlić tylko jeden z argumentów, w związku z tym pozostałe są odfiltrowane. Podobnie jest w przypadku Selektor2:
public class Selector2 : ActionSelector<CentralCustomAction>
{
public Selector2()
{
UseName("DisplayFullName");
Prop(p => p.Selector).ShouldBe(SelectorChoice.Selector2);
ShowAll();
Hide(p => p.Age);
}
}
Oraz klas Selector3 :
public class Selector3 : ActionSelector<CentralCustomAction>
{
public Selector3()
{
UseName("DisplayFullDetails");
Prop(p => p.Selector).ShouldBe(SelectorChoice.Selector3);
ShowAll();
}
}
Końcowe wykonanie odbywa się za pomocą metody Execute(ActionContext context) rezydującej w akcji centralnej. Na podstawie selektora zostaną wyświetlone odpowiednie wartości filtrowane.
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}";
}
}
Niestandardowe selektory akcji z zastosowaniem wartości logicznych
Poniżej przedstawiono przykład użycia wartości logicznych zamiast wyliczania.
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);
}
}
}
Ustawianie opisów niestandardowych selektorów akcji
Aby utworzyć opis i podsumowanie selektorów, w pliku RESX niestandardowego moduł należy użyć następującego formatu.
SelectorName_Description
SelectorName_Summary
Można to również zrobić w selektorze za pomocą metod WithDescription i WithSummary.
Ważne
Pliki dll opisujące akcje niestandardowe, zależności dll i plik .cab zawierający to wszystko, powinny być poprawnie podpisane zaufanym certyfikatem cyfrowym przez organizację. Certyfikat powinien być również zainstalowany na każdej maszynie, na której przepływ pulpitu z zależnościami akcji niestandardowych jest tworzony/modyfikowany/wykonywany w obrębie zaufanych głównych urzędów certyfikacji.
Niestandardowe identyfikatory modułów
Każdy moduł ma własny identyfikator (nazwę zestawu). Podczas tworzenia niestandardowych modułów należy się upewnić, że są ustawione unikatowe identyfikatory modułów. Aby ustawić nazwę zestawu dla moduły, należy zmodyfikować właściwość Nazwa zestawu w sekcji Ogólne właściwości projektu C#.
Ostrzeżenie
Włączenie modułów o tym samym identyfikatorze w przepływie spowoduje konflikty
Konwencja niestandardowych nazw modułów
Aby niestandardowe moduły były czytelne na pulpicie Power Automate, nazwa_pliku musi mieć nazwę pliku według poniższego wzorca:
?*.Modules.?*
Modules.?*
Na przykład Moduły .ContosoActions.dll
Nazwa AssemblyTitle w ustawieniach projektu określa identyfikator moduło. Może ona zawierać tylko znaki alfanumeryczne oraz znaki podkreślenia i musi zaczynać się od litery.
Zarejestruj wszystkie biblioteki DLL wewnątrz modułu niestandardowego
Ważne
Wymagane jest, aby wszystkie pliki DLL zawierały moduł niestandardowy (wygenerowany zestaw i wszystkie jego zależności) podpisane z zaufanym certyfikatem
Aby można było sfinalizować utworzenie modułu niestandardowego, należy podpisać wszystkie wygenerowane pliki DLL, które znajdują się w folderze bin/release lub bin/Debug projektu.
Zarejestruj wszystkie pliki DLL przy użyciu zaufanego certyfikatu, uruchamiając następujące polecenie (dla każdego pliku DLL) w wierszu polecenia dla deweloperów dla Visual Studio:
Zarejestruj wszystkie pliki DLL przy użyciu zaufanego certyfikatu, uruchamiając następujące polecenie (dla każdego pliku DLL) w wierszu polecenia dla deweloperów dla 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
lub uruchamiając następujące polecenie (przez utworzenie skryptu programu Windows PowerShell.ps1), które iteruje przez wszystkie pliki DLL i rejestruje każdy z nich z dostarczonym certyfikatem:
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
}
Uwaga
Certyfikat cyfrowy musi mieć możliwości eksportowania podpisu klucza prywatnego i kodu
Spakuj wszystko w pliku cabinet
Plik DLL zawierający akcje niestandardowe i wszystkie zależności (pliki DLL) muszą znajdować się w pliku cabinet (CAB).
Uwaga
Podczas nazywania pliku .cab należy postępować zgodnie z konwencją nazewnictwa plików i folderów dla systemu operacyjnego Windows. Nie należy używać pustych spacji ani znaków specjalnych, takich jak < > : " / \ | ? *
.
Utwórz skrypt Windows PowerShell (.ps1) zawierający następujące wiersze:
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
Ten skrypt Windows PowerShell może być następnie używany do tworzenia pliku .cab przez wywołanie go w Windows PowerShell i podanie:
- Katalog zawierający pliki dll do skompresowania.
- Docelowy katalog, w którym ma się umieścić wygenerowany plik .cab.
Wywoływanie skryptu przy użyciu następującej składni:
.\{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
Przykład:
.\makeCabFile.ps1 "C:\Users\Username\source\repos\MyCustomModule\bin\Release\net472" "C:\Users\Username\MyCustomActions" MyCustomActions.cab
Uwaga
- Upewnij się, że rzeczywisty plik DLL akcji niestandardowych znajduje się na poziomie głównym docelowej ścieżki podczas tworzenia pliku CAB, a nie w podfolderze.
- Plik .cab musi być również podpisany. Niepodpisane pliki .cab i/lub niepodpisane biblioteki .dll zawarte w nich nie będą używane w przepływach pulpitów i będą powodować błędy podczas włączenia.