一文讲透为Power Automate for Desktop (PAD) 实现自定义模块 - 附完整代码
概述
Power Automate for Desktop (以下简称PAD)是微软推出的一款针对Windows桌面端的免费RPA(机器人流程自动化)工具,它目前默认会随着Windows 11安装,但也可以通过单独下载安装。
PAD 目前仅支持Windows 11和 Windows 10系统安装使用。
我在 "全民RPA之微软PAD入门培训" 中的分享过,PAD 与其他RPA工具相比,有如下的一些优势:
关于 PAD 的常规使用和入门指南,请参考官方文档 https://docs.microsoft.com/zh-cn/learn/paths/pad-get-started/, PAD 默认自带了几十个模块(module),数以百计的功能(action),可以满足不同用户在不同场景下的需求。值得注意的是,使用 PAD 并不需要计算机本科毕业,只要你具备一定的业务知识,以及基本的逻辑思维即可。
声明
由于PAD这个产品还在不断地发展中,目前官方并没有公开的文档对自定义模块开发进行描述。这几篇文章所基于的经验是技术社区摸索和交流所得,不代表官方意见和任何承诺。
目前国内有一个PAD爱好者的技术社区,QQ群号是 610-576-550,有需要的朋友也可以添加。这个是完全由以潘淳老师为核心的一群热心爱好者运营的,潘老师在某银行的科技与创新中心供职,在PAD等多个方面的造诣,以及他研究问题的方法,都让我惊叹和折服。
基本概念
本文演示环境是在 Windows 10 中文版,通过 单独下载安装PAD 的环境。
默认情况下,启动PAD 后你会看到下面这个界面,这是所谓的控制台(console),用来显示你当前所有的PAD流程,然后可以新建流程、修改环境和设置等。
点击 新建流
或点击某个流程后会进入设计器(designer)界面。
上图的左边面板区域就是目前内置的模块(module)和操作(action),模块相当于是一个分类,用来组织一个或多个操作。
你可以拖动这些操作(action)到中间的设计器区域,用来设计你的流程。每个功能,都有一定的设置界面,用来帮助你设定输入和输出参数,例如
到这里为止,你已经了解了PAD中主要的几个核心概念
- 控制台 (Console)
- 设计器 (Designer)
- 模块 (Module)
- 操作 (Action)
- 流(Flow)
本文所提到的自定义PAD模块,就是开发符合业务需要的 模块
(包括一个或多个操作
),用来在设计器
里面提供给用户使用,它们可以和内置的模块和操作一起来构成你的流程
。
准备开发环境
具体来说,我们将采用Visual Studio
和 C#
语言,根据 PAD 所提供的 SDK
(软件开发工具包)进行开发。 请按照如下的提示准备开发环境。
Visual Studio 2022 社区版
这是完全免费的,你可以通过 https://visualstudio.microsoft.com/zh-hans/thank-you-downloading-visual-studio/?sku=Community&channel=Release&version=VS2022&source=VSLandingPage&cid=2030&passive=false 下载安装。
安装Visual Studio 必要的组件
请至少确保安装了下面两个功能组件,.NET 桌面开发
这个组件会提供我们需要的项目模板,而 通用 Windows 平台开发
这个组件,你要选项至少一个 Windows 10 SDK
(如果你看到多个的话),这个是为了得到一系列的工具,主要是一个我们后续用来做代码签名的工具 signtool.exe
。
检查 signtool
这个工具是否安装正确
在磁盘上面搜索 signtool.exe
或者直接到这个目录(C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64)中去找,请确保有这个工具。
创建并编辑项目
启动Visual Studio 2022后,请选择如下的模板来创建项目
⚠️ 经过测试发现,如果使用
.NET Core
或.NET Standard
类库来创建项目,也能成功部署,甚至能测试成功,但无法保存流程,会产生错误。所以请一定要用.NET Framework
的类库。
给你的项目起一个合适的名字,请注意,名称中需要包含 Modules
这几个字符,下图中的命名规范是推荐的。
项目创建好之后,我们来做一点最基本的修改,以确保实现一个最简单的操作 action
。首先,修改 AssemblyInfo.cs
这个文件,将 AssemblyTitle
修改得更短一点。
PAD 在在加载自定义模块时尝试以这个 AssemblyTitle
的值作为模块的标识符(id),作为规范之一,它规定这个标识符不能包含标点符号。
接下来我们添加 PAD SDK
的引用,其实说是SDK, 本质上就是两个特殊的dll 而已,你可以在PAD 的安装目录(C:\Program Files (x86)\Power Automate Desktop
)下面找到它们。你可以通过 添加引用
窗口来添加它们
点击 浏览...
按钮去找到它们,然后选中,最后点击 确定
按钮
接下来就可以修改一下 Class1.cs
这个文件了。我建议将其重命令成 HelloAction.cs
(选中文件,然后按 F2 键重命名),任何时候保持一个好的命名规范都会让你事半功倍。
最后,修改代码如下
using Microsoft.Flow.RPA.Desktop.Modules.SDK;
using Microsoft.Flow.RPA.Desktop.Modules.SDK.Attributes;
using Microsoft.Flow.RPA.Desktop.Modules.SDK.Extended.Attributes;
using System;
namespace Xizhang.Modules.Helloworld.Actions
{
[Action(Id = "Hello")]
[Icon(Code = "EEE7")]
public class HelloAction : ActionBase
{
[InputArgument]
public string Name { get; set; }
[OutputArgument]
public string Result { get; set; }
public override void Execute(ActionContext context)
{
Result = String.Format("Hello,{0}", Name);
}
}
}
这个代码很简洁,我们让 HelloAction
继承 ActionBase
类,然后实现了它的 Execute
方法。在这个操作(action)中,我们定义了一个输入参数和一个输出参数。另外还用到了几个 Attribute
来自操作进行描述,例如它的id, 和Icon。
值得注意的是,这里的Icon是一个字符串,据说是PAD 有一个内置的图标文件,有一系列的图标,每个图标都有一个自己的编号。由于图标在本例中也不是很重要,这里先用 EEE7
吧。
准备签名证书
PAD 规定所有的自定义模块源代码必须要进行数字签名,以确保不被滥用。正常情况下,你需要拥有一个真正合法的证书(每年要花一定的银子续费),但在开发测试阶段,或者小范围使用的话,你可以利用自签名证书来实现。
通过Windows 自带的PowerShell 可以轻松地生成自签名证书,请在管理员模式下打开PowerShell,并执行下面的命令
$cert = New-SelfSignedCertificate -Subject Xizhang.PAD.Actions.Cert -Type CodeSigningCert
然后将这个证书导出私钥
$cert | Export-PfxCertificate `
-Password (ConvertTo-SecureString -AsPlainText -Force "password") `
-FilePath Xizhang.PAD.Actions.Cert.pfx
最后,你需要把这个证书安装到本地电脑的信任根颁发机构中去。找到这个pfx文件,双击即可安装。
点击两次 下一步
,在下面界面输入密码
点击下一步,将证书安装到 受信任的根证书颁发机构
然后点击下一步,完成安装,在下图中点击 是
即可。
对项目进行签名
有了证书,接下来就可以对我们开发好的自定义模块进行签名了。你可以通过在项目属性中添加 生成事件
来自动化完成这个工作。
这个命令大致如下,你要修改的是其中的证书路径部分,请用你的实际路径替换 c:/users/chenxizhang/Xizhang.PAD.Actions.Cert.pfx
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe" sign /tr http://timestamp.digicert.com /f c:/users/chenxizhang/Xizhang.PAD.Actions.Cert.pfx /p password $(AssemblyName).dll
按下 CTRL+SHIFT+B
对解决方案进行生成,然后到生成目录中去找到对应的程序集
查看这个程序集的属性,来确认它是否已经正确地被签名
选中签名信息,点击 详细信息
按钮的话,可以进一步查看证书
部署到PAD的自定义模块目录
到现在为止,我们基本上准备就绪了。其实就是按照SDK提供的基础类型(ActionBase
),以及遵守一些规范,少量的代码,另外就是要对程序集签名而已。
接下来我们看看把这个程序集部署到自定义模块目录中去,这个过程也很简单,首先复制如下的文件(包括主程序集文件,以及它的依赖程序集)
然后转到PAD的 安装目录,通常是 C:\Program Files (x86)\Power Automate Desktop
,在里面创建一个子目录 custom-modules
(如果该目录不存在的话),然后把你的文件粘贴进去即可。请注意,此时最好把PAD完全关闭。
验证功能
接下来就是最激动人心的时刻了。你现在可以重新打开PAD的控制台,然后新建一个流程,进入设计器界面。
我们果然看到了左侧的操作栏面板,出现了一个新的分类 自定义操作
,而我刚才自定义开发的模块和操作也出现在这里了。下面我把 HelloAction
拖到设计器中间区域,它也会弹出了一个对话框,让我输入参数(这里是 Name
)。
看起来不错,我保存后运行一下,确实能看到它正确地输出了内容。
为自定义组件实现多语言支持
我们的自定义组件已经能正确工作了。但美中不足的是,它在中文版上面可能不是很友好,它的名称,描述,参数等文字信息,如果能也显示中文就更好了吧。下面看看如何添加这个能力。
回到Visual Studio 项目属性界面中来,请点击下图中央位置的链接创建资源文件。
你会看到如下的界面
我们需要为模块名称、描述,操作名称、描述,输入输出参数名称、描述等定义资源。它们遵守一定的规范,那就是在相应对象
的后面用 _FriendlyName
表示名称,用 _Description
表示描述。
那么,到底用什么来表示模块对象呢?其实就是刚才我们提到的在 AssemblyInfo.cs
文件中定义的 AssemblyTitle
这个信息,还记得吗?
操作的名称,就是它的类名称。例如本例中的 HelloAction
。操作的输入输出参数名称,需要以 操作名称_属性名称
来定义,例如本例中的 Name
这个输入参数,我们在定义资源文件时就用 HelloAction_Name
来表示它。
掌握了如上的规范,你就可以很轻松地定义不同语言的资源文件了,例如下图所示是默认的资源文件(也就是英文)。实际上,即便不提供资源文件,我们的自定义模块都已经正常工作了,那个情况下,它会直接使用上述对象的字面文字作为资源。
然后添加另外一个资源文件。你将看到如下这样的界面,请注意名称也是Resources
, 但是加了一个 zh-Hans
的限定符,这表示它是用来为简体中文提供支持的资源文件。
根据英文版那个资源文件依葫芦画瓢,你可以定义如下的一个简体中文版
这里有一个实用技巧就是,你可以选中英文版资源文件的左上角的区域(下图中的红色区域),复制全部,然后在简体中文版的资源文件,同样选中左上角的区域,粘贴,就可以快速地把所有定义好的资源复制过来,然后直接修改即可。
再次编译一下解决方案,你可以看到输出目录中的 zh-Hans
子目录中会多出来几个文件
需要注意的是,这个文件中只包含了资源定义,并且它同样是要进行签名的,所以我可以修改一下生成事件
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe" sign /tr http://timestamp.digicert.com /f c:/users/chenxizhang/Xizhang.PAD.Actions.Cert.pfx /p password $(AssemblyName).dll
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe" sign /tr http://timestamp.digicert.com /f c:/users/chenxizhang/Xizhang.PAD.Actions.Cert.pfx /p password "zh-Hans/$(AssemblyName).resources.dll"
你可以同样的方式确认一下这个新的资源文件程序集也同样被签名了
接下来我们重新部署一下,这次要复制的文件需要包含 zh-Hans
目录哦,请注意必须把PAD关闭才能完成复制。
复制过去后的目录结构如下
你现在可以重新打开PAD的控制台,然后新建一个流程,进入设计器界面。
你会发现,现在我们的自定义模块已经全部用中文了。这样对于中文用户的体验就很好了。
⚠️ 请注意,经测试发现,有时候直接替换程序集,可能因为PAD有缓存的原因(也可以是一个bug),看不到效果。需要等一段时间,或者干脆把custom-modules目录的内容复制出来,清空一下,然后开一下PAD,这样可以刷新一下缓存,然后把内容复制回来,再开PAD就可以了。
多语言高级技巧
其实还有两个高级技巧,一个是为操作(action)添加一个更加直观的汇总信息(Summary),这个的好处是同一个操作,在不同地方使用时,根据参数不同,可以在界面上显示不同的内容。另外一个问题,在代码中,可能也需要有输出文本信息,这个信息也需要做多语言。下面分别讲解这两个问题如何解决。
添加操作的汇总信息
这个也不难,我们需要在资源文件中添加一个特殊的键值:操作名称_Summary
,例如本例为 HelloAction_Summary
,另外值得注意的是,在这个文字中,可以引用输入输出参数名,以便显示更加相关的信息。引用的方式是 <参数名>
, 但要求参数名全部大写 ,例如本例为 <NAME>
或 <RESULT>
。
重新部署后,我们可以看到如下的效果
为代码中的文本做多语言处理
我们来看一下目前这个代码的逻辑,下图所示关键代码就是对输入参数(Name)做了一个格式化,然后将其赋值给输出变量(Result)
很显然,这个字符串也应该做多语言处理。那么我们来看一下怎么处理吧。首先,我们仍然是需要在两个资源文件中分别定义在不同语言应该怎么输出这个消息。
然后,用如下的代码替换掉原先的代码
Result = String.Format(Properties.Resources.Messages_SayHello, Name);
完美,这样就可以自动根据当前的语言版本用不同的消息给用户打招呼了。请看下面的例子
总结
本文完整地给大家介绍了PAD自定义模块开发的全过程,包括创建项目,修改功能,代码签名,部署测试,以及多语言处理等,希望对大家有所帮助。
本文随附代码,请通过 https://github.com/chenxizhang/pad-custom-module-quickstart 进行访问,可以自行克隆在本地编译,按照步骤在你的电脑上面安装和部署。