You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

疑问点

  1. 如何在Invoke Code中调用上述Main方法?
  2. 如何向该静态方法传递参数?已创建对应参数,但尝试Main({sharedMailboxAddress,parentFolderName,childFolderName,appId})的调用方式无效。
  3. 是否需要在Invoke Code中添加命名空间?
  4. 如何从catch块中获取错误信息并赋值给变量“Fehlermeldung”?

问题解答

1. Invoke Code中调用方法的正确方式

在UiPath的Invoke Code中不需要保留Program类的Main方法结构,建议将逻辑封装为一个普通异步静态方法,直接在代码最外层调用并使用await等待执行完成:

  • 将原Main方法重命名为CreateMailboxFolders
  • 删除代码中多余的类包裹(或者保留类,但直接调用内部方法)
  • 在Invoke Code的最顶部添加调用:await CreateMailboxFolders(sharedMailboxAddress, parentFolderName, childFolderName, appId);

2. 参数传递的正确操作

  1. 打开Invoke Code活动的Arguments面板,添加4个输入参数:
    • sharedMailboxAddress(类型String):共享邮箱地址
    • parentFolderName(类型String):父文件夹名称(空字符串表示根目录)
    • childFolderName(类型String):子文件夹名称
    • appId(类型String):Azure注册的AppId
  2. 修改方法的参数列表,直接接收单个参数而非数组:
    static async System.Threading.Tasks.Task CreateMailboxFolders(string sharedMailboxAddress, string parentFolderName, string childFolderName, string appId)
    {
        // 原代码逻辑,将所有args[index]替换为对应的参数名
    }
    
  3. 在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变量

  1. 在Invoke Code的Arguments面板中添加一个输出参数:
    • Fehlermeldung(类型String,方向设为Out)
  2. 修改catch块,直接将错误信息赋值给该变量:
    catch (MsalException ex)
    {
        Fehlermeldung = $"获取访问令牌出错: {ex.Message}";
    }
    catch (Exception ex)
    {
        Fehlermeldung = $"操作出错: {ex.Message}";
    }
    

注意:变量名必须和Arguments面板中定义的完全一致,无需在代码中重新声明。

内容的提问来源于stack exchange,提问作者sergioMoreno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 00:24:58