UiPath中通过Invoke Code操作共享邮箱创建文件夹的技术疑问
环境信息
- UiPath Studio版本:2021.10.3
- 开发语言:C#
需求目标
需要在共享邮箱的收件箱同级位置创建新文件夹及子文件夹,通过UiPath的Invoke Code活动实现该功能。
实现思路
由于未找到UiPath官方活动支持该需求,因此选择通过Invoke Code开发,基于Exchange Server实现。已在Azure云平台创建AppId,参考《通过OAuth验证EWS应用》文档编写了如下C#代码:
class Program { static async System.Threading.Tasks.Task Main(string[] args) { // 使用Microsoft.Identity.Client 4.22.0版本 // 配置MSAL客户端获取令牌 var pcaOptions = new Microsoft.Identity.Client.PublicClientApplicationOptions { // 应用注册门户中注册的客户端ID(即App ID) ClientId = args[3] }; var pca = Microsoft.Identity.Client.PublicClientApplicationBuilder.CreateWithApplicationOptions(pcaOptions).Build(); // EWS访问所需的权限范围 var ewsScopes = new string[] { "https://outlook.office365.com/EWS.AccessAsUser.All" }; try { // 发起交互式令牌请求 var authResult = await pca.AcquireTokenInteractive(ewsScopes).ExecuteAsync(); // 用访问令牌配置ExchangeService var ewsClient = new ExchangeService(ExchangeVersion.Exchange2013_SP1); ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"); ewsClient.Credentials = new OAuthCredentials(authResult.AccessToken); FolderView fv = new FolderView(100); // 设置共享邮箱的根文件夹ID System.Console.WriteLine(WellKnownFolderName.Root); FolderId SharedMailboxFolderId = new FolderId(WellKnownFolderName.Root, args[0]); // 设置父文件夹ID FolderId parentFolderID = null; if(!string.IsNullOrEmpty(args[1])) { var findParentFolder = ewsClient.FindFolders( SharedMailboxFolderId, new SearchFilter.SearchFilterCollection( Microsoft.Exchange.WebServices.Data.LogicalOperator.Or, new SearchFilter.ContainsSubstring(FolderSchema.DisplayName, args[1])), fv); parentFolderID = findParentFolder.ElementAt(0).Id; System.Console.WriteLine("父文件夹已存在"); } else { parentFolderID = SharedMailboxFolderId; } var findChildFolder = ewsClient.FindFolders( parentFolderID, new SearchFilter.SearchFilterCollection( Microsoft.Exchange.WebServices.Data.LogicalOperator.Or, new SearchFilter.ContainsSubstring(FolderSchema.DisplayName, args[2])), fv); FolderId childFolderID = findChildFolder.Count > 0 ? findChildFolder.ElementAt(0).Id : null; // 如果未找到子文件夹,则创建 if (childFolderID == null) { // 创建通用文件夹 Folder folder = new Folder(ewsClient); // 设置文件夹名称 folder.DisplayName = args[2]; // 在指定父文件夹下保存新文件夹 folder.Save(parentFolderID); System.Console.WriteLine("子文件夹已创建"); } else { System.Console.WriteLine($"子文件夹已存在"); } } catch (Microsoft.Identity.Client.MsalException ex) { System.Console.WriteLine($"获取访问令牌出错: {ex.Message}"); } catch (Exception ex) { System.Console.WriteLine($"出错: {ex.Message}"); } } }
疑问点
- 如何在Invoke Code中调用上述Main方法?
- 如何向该静态方法传递参数?已创建对应参数,但尝试
Main({sharedMailboxAddress,parentFolderName,childFolderName,appId})的调用方式无效。 - 是否需要在Invoke Code中添加命名空间?
- 如何从catch块中获取错误信息并赋值给变量“Fehlermeldung”?
问题解答
1. Invoke Code中调用方法的正确方式
在UiPath的Invoke Code中不需要保留Program类的Main方法结构,建议将逻辑封装为一个普通异步静态方法,直接在代码最外层调用并使用await等待执行完成:
- 将原
Main方法重命名为CreateMailboxFolders - 删除代码中多余的类包裹(或者保留类,但直接调用内部方法)
- 在Invoke Code的最顶部添加调用:
await CreateMailboxFolders(sharedMailboxAddress, parentFolderName, childFolderName, appId);
2. 参数传递的正确操作
- 打开Invoke Code活动的Arguments面板,添加4个输入参数:
sharedMailboxAddress(类型String):共享邮箱地址parentFolderName(类型String):父文件夹名称(空字符串表示根目录)childFolderName(类型String):子文件夹名称appId(类型String):Azure注册的AppId
- 修改方法的参数列表,直接接收单个参数而非数组:
static async System.Threading.Tasks.Task CreateMailboxFolders(string sharedMailboxAddress, string parentFolderName, string childFolderName, string appId) { // 原代码逻辑,将所有args[index]替换为对应的参数名 } - 在Invoke Code最外层调用方法:
await CreateMailboxFolders(sharedMailboxAddress, parentFolderName, childFolderName, appId);
3. 命名空间的添加要求
必须添加所需命名空间,否则代码会因找不到类而报错。在Invoke Code的最顶部添加:
using Microsoft.Identity.Client; using Microsoft.Exchange.WebServices.Data; using System; using System.Linq;
4. 捕获错误并赋值给Fehlermeldung变量
- 在Invoke Code的Arguments面板中添加一个输出参数:
Fehlermeldung(类型String,方向设为Out)
- 修改catch块,直接将错误信息赋值给该变量:
catch (MsalException ex) { Fehlermeldung = $"获取访问令牌出错: {ex.Message}"; } catch (Exception ex) { Fehlermeldung = $"操作出错: {ex.Message}"; }
注意:变量名必须和Arguments面板中定义的完全一致,无需在代码中重新声明。
内容的提问来源于stack exchange,提问作者sergioMoreno
相关产品推荐
相关产品推荐

