Dela via


Skapa Power Automate för datoråtgärder med Actions SDK

Den här artikeln beskriver hur du skapar anpassade åtgärder i Power Automate för dator.

Skapa anpassade åtgärder

Viktigt!

Reserverade sökord kan inte användas som åtgärdsnamn och/eller åtgärdsegenskaper. Användning av reserverade nyckelord som åtgärdsnamn och/eller åtgärdsegenskaper resulterar i felaktigt beteende. Mer information: Reserverade sökord i datorflöden

Börja med att skapa ett projekt för klassbibliotek (.NET Framework). Välj .NET framework version 4.7.2.

Så här skapar du en åtgärd i den anpassade modulen:

  • Ta bort den autogenererade Class1.cs filen.
  • Skapa en ny klass i projektet så att den anpassade åtgärden får ett tydligt namn.
  • Inkludera Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK och Microsoft.PowerPlatform.PowerAutomate.Desktop.Actions.SDK.Attributes namnutrymme.
  • Alla klasser som representerar åtgärder ska ha ett [Action]-attribut ovanför klassen.
  • Klassen ska ha offentlig åtkomst och ärver från ActionBase-klassen.
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();
        }
    }
}

De flesta åtgärder kan ha parametrar (Indata eller Utdata). Indata- och utdataparametrar representeras av klassiska egenskaper för C#. Varje egenskap bör ha ett lämpligt C#-attribut, [InputArgument] eller [OutputArgument] för att ange typ och hur de visas på Power Automate för dator. Indataargument kan också ha standardvärden.

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

Lägga till beskrivningar för anpassade åtgärder

Lägg till en beskrivning och ett eget namn för modulerna och åtgärderna så att RPA-utvecklare vet hur de bäst kan användas.

Power Automate för dator designer visar användarvänliga namn och beskrivningar.

Du kan skapa en "Resources.resx" fil i mappen Egenskaper för modulprojektet. Den nya .resx-filen ska ha namnet "Resources.resx".

Formatet för beskrivningarna för moduler och åtgärder bör vara som följer:

"Module_Description" eller "Action_Description" och "Module_FriendlyName" eller "Action_FriendlyName" i namnfältet. Beskrivning i värdefältet.

Vi rekommenderar också att du tillhandahåller beskrivningar och användarvänliga namn för parametrar. Formatet ska vara: "Action_Parameter_Description", "Action_Parameter_FriendlyName".

Skärmbild av resurser för en enkel åtgärd

Dricks

Vi rekommenderar att du anger vad det är du beskriver i kommentarsfältet (t.ex. modul, åtgärd osv.)

Dessa kan också anges med egenskaperna FriendlyName och Beskrivning för attributen [InputArgument], [OutputArgument] och [Action].

Här är ett exempel på en fil Resources.resx för en anpassad modul.

Skärmbild av resurser

Ett annat sätt att snabbt lägga till användarvänliga namn och beskrivningar i åtgärder och parametrar är med egenskaperna FriendlyName och Beskrivning [Åtgärd], [InputArguement] och [OutputArguement] attribut.

Kommentar

Om du vill lägga till ett användarvänligt namn och en beskrivning i en modul måste du ändra respektive .resx-fil eller lägga till respektive C#-attribut.

Lägga till felhantering i anpassade åtgärder

Om du vill definiera anpassade undantag i åtgärden använder du attributet [Throws("ActionError")] ovanför den anpassade åtgärdsklassen. Varje undantagsfall som du vill definiera ska ha ett eget attribut.

Använd följande kod i catch-blocket:

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

Kontrollera att namnet ActionException matchar det namn som du angav i attributet Throws . Använd throw new ActionException för varje undantagsfall och matcha det med motsvarande Throws attributnamn. Alla undantag som definieras med attributet Throws visas på designerns flik för hantering av åtgärdsfel.

Ett exempel på detta finns i avsnittet Villkorsstyrda åtgärder.

Resurslokalisering

Standardspråket för moduler i Power Automate för dator är engelska.

Filen Resources.resx ska vara på engelska.

Andra språk kan läggas till med extra resurser {locale} .resx-filer för lokalisering. Till exempel Resources.fr.resx.

Anpassade modulkategorier

Moduler kan innehålla kategorier och underkategorier för bättre åtgärdsorganisation.

För att separera anpassade åtgärder i kategorier, underkategorier, ändra attributet [Action] som föregår den klass som representerar den anpassade åtgärden på följande sätt:

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

Kommentar

En modul kan ha flera kategorier. Kategorier kan också bestå av underkategorier. Strukturen kan vara obestämd.

Egenskapen Order avgör i vilken ordning åtgärder förhandsgranskas i designern.

Action1 tillhör kategorin "TestCategory" och det är den första åtgärden i modulen (på så sätt förklarar du Order och kategori med ett exempel).

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

Villkorsåtgärder

Villkorliga åtgärder är åtgärder som returnerar antingen Sant eller Falskt. Åtgärd "Om det finns en fil" Power Automate för dator i standardbiblioteket är ett bra exempel på en villkorsstyrd åtgärd.

Exempel på villkorsstyrd åtgärd:

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

Observera booleska variabeln Resultat.

Åtgärden Om filen existerar har inget utdataargument. Vad som returneras är antingen sant eller falskt, beroende på vad den booleska variabeln Resultat innehåller.

Anpassade åtgärdsväljare

Det finns särskilda fall där en anpassad åtgärd kan krävas för att ha mer än en variant.

Ett exempel är åtgärden "Starta Excel" från det vanliga åtgärdsbiblioteket.

Om du använder väljaren "med ett tomt dokument" startas ett tomt Excel-dokument i flödet, medan du måste öppna filens sökväg för att öppna och öppna följande dokument.

Skärmbild av åtgärden väljare Starta Excel

De två åtgärder som beskrivs ovan används som två urvalsväljare för grundåtgärden "Starta Excel".

När du skapar anpassade åtgärder behöver du inte skriva om funktioner.

Du kan skapa en enda "basåtgärd" och ange indata- och utdataparametrarna och sedan välja vad som ska visas i varje läge genom att ange åtgärdsväljare.

Med åtgärdsväljarna kan du lägga till en sammanfattningsnivå över en enskild åtgärd, vilket gör det möjligt att hämta specifika funktioner från den enskilda "basåtgärden" utan att behöva skriva om kod för att skapa en ny åtgärd varje gång.

Tänk på väljarna som val, filtrera en enskild åtgärd och presentera endast den information som krävs enligt respektive väljare.

Skärmbild av diagram över åtgärdsväljare

Om du vill skapa en ny åtgärdsväljare skapar du först en grundåtgärd som ska användas av väljarna.

För den centrala åtgärden krävs antingen en boolesk egenskap eller en uppräkningsegenskap som ett indata-C#-argument.

Värdet på den här egenskapen avgör vilken väljare som används.

Den vanligaste är att använda en uppräkning. Särskilt när det behövs fler än två väljare är uppräkning det enda alternativet.

I två urvalsfall kan booleska användas.

Den här egenskapen, som även kallas begränsningsargument, måste ha ett standardvärde.

Den centrala åtgärden anses vara en klassisk åtgärd.

Lägg märke till att den första egenskapen (indataargument) är en uppräkning. Beroende på egenskapens värde aktiveras lämplig väljare.

Kommentar

Om du vill att argumenten ska beställas på önskat sätt anger du ordervärdet bredvid Attributet 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
}

Anpassade åtgärdsväljare med uppräkningar

I det här exemplet skapar du tre urvalsväljare. En enkel uppräkning avgör lämplig väljare varje gång:

public enum SelectorChoice
{
    Selector1,
    Selector2,
    Selector3
}

Selectors representeras av klasser.

De klasserna måste ärver ActionSelector<TBaseActionClass> klassen.

Kommentar

TBaseActionClass är namnet på basåtgärdsklassen.

I metoden UseName() används namnet på åtgärdsväljaren. Det används som ett namn på åtgärden för att matcha resurserna.

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

Kommentar

Klasserna Väljare bör inte anses vara åtgärder. Den enda åtgärden är den centrala åtgärden. Väljare fungerar som filter.

I det här exemplet vill vi bara visa ett av argumenten, så de andra filtreras bort. På samma sätt för Selector2:

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

Och Selector3 klasser:

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

Det slutliga utförandet uppnås genom metoden Execute(ActionContext context) som finns i den centrala åtgärden. Utifrån väljaren visas respektive filtrerade värden.

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

Anpassade åtgärdsväljare med boolesk

Följande är ett exempel som används för booleska istället för uppräkningar.

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

Ange beskrivningar för anpassade åtgärdsväljare

Om du vill skapa en beskrivning och en sammanfattning för väljarna använder du följande format i .resx-filen i den anpassade modulen.

SelectorName_Description
SelectorName_Summary

Detta kan även göras i väljaren med metoderna WithDescription och WithSummary.

Viktigt!

.dll-filer som beskriver de anpassade åtgärderna, deras .dll-beroenden och .cab-filen som innehåller allt bör vara korrekt signerade med ett digitalt certifikat som organisationen är betrodda på. Certifikatet bör också installeras på varje dator där ett datorflöde med anpassade åtgärdsberoenden skapas/modifieras/körs, som finns under den betrodda rotcertifikatutfärdaren.

Anpassade modul-ID

Varje modul har sitt eget ID (sammansättningsnamn). När du skapar anpassade moduler ska du ange unika modul-ID. Om du vill ange sammansättningsnamnet för modulen ändrar du egenskapen för sammansättningsnamn under avsnittet Allmänt i C#-projektets egenskaper.

Varning

Om du inkluderar moduler med samma ID i ett flöde uppstår konflikter

Anpassade konventioner för modulnamn

För att de anpassade modulerna ska kunna läsas igenom Power Automate för dator måste AssemblyName ha ett filnamn som följer följande mönster:

?*.Modules.?*
Modules.?*

Till exempel Moduler.ContosoActions.dll

AssemblyTitle i projektinställningarna anger modul-ID. Den kan endast ha alfanumeriska tecken och understreck och måste börja med en bokstav.

Logga alla URL:er i den anpassade modulen

Viktigt

"Det är obligatoriskt att alla .dll-filer som utgör en anpassad modul (genererad sammansättning och alla dess beroenden) är signerade med ett betrott certifikat

För att slutföra skapandet av en anpassad modul måste alla genererade .dll-filer som finns under mappen lagerplats/version eller lagerplats/felsöka i projektet vara signerade.

Logga alla .dll-filer med hjälp av ett betrott certifikat genom att köra följande kommando (för varje .dll-fil) i kommandotolken utvecklare för Visual Studio:

Logga alla .dlls-filer med hjälp av ett betrott certifikat genom att köra följande kommando (för varje .dll-fil) i kommandotolken utvecklare för 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

eller genom att köra följande kommando (genom att skapa ett Windows PowerShell-skript .ps1) som iterates genom .dll-filer och signera var och en med det medföljande certifikatet:

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
}

Kommentar

Det digitala certifikatet måste ha en exporterbar privat nyckel och kodsigneringsfunktioner

Paketera allt i en kabinettfil

.dll-filen som innehåller de anpassade åtgärderna och alla dess beroenden (.dll-filer) måste paketeras i en kabinettfil (.cab).

Kommentar

När du ger cab-filen ett namn följer du fil- och mappnamnkonventionerna för Windows-operativsystemet. Använd inte tomma blanksteg eller specialtecken som < > : " / \ | ? * .

Skapa ett Windows PowerShell-skript (.ps1) som innehåller följande rader:

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

Det här Windows PowerShell-skriptet kan sedan användas för att skapa .cab-filen genom att skapa den i Windows PowerShell och tillhandahålla:

  • Katalogen till .dll-filerna som ska komprimeras.
  • Målkatalogen som ska placera den genererade .cab-filen.

Anropa skriptet med följande syntax:

.\{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

Exempel:

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

Kommentar

  • Se till att den faktiska .dll-filen för anpassade åtgärder finns i rotnivån för den riktade sökvägen när du skapar .cab-filen och inte i en undermapp.
  • Filen .cab måste också vara signerad. Osignerade .cab-filer och/eller osignerade .dlls-filer som finns i dem kan inte användas i datorflöden och resulterar i fel vid inkludering.

Gå vidare

Ladda upp anpassade åtgärder