如何使用Outlook Redemption获取共享日历组中的日历列表?
环境
- Redemption 6.3
- Windows 11
- Office 365
- Outlook版本2307(内部版本16626.2022)
需求与问题
我需要获取Outlook中「共享日历」组下的所有日历列表,但目前用Redemption编写的代码仅返回了几个不在「共享文件夹」组中的公开共享文件夹,代码如下:
RDOFolder calendar = rdoSession.GetSharedDefaultFolder("--mailbox name--", rdoDefaultFolders.olFolderCalendar); foreach( RDOFolder folder in calendar.Folders ) { System.Diagnostics.Debug.WriteLine(folder.Name); }
我能通过OutlookSpy在导航面板(NavigationPane)中找到目标内容,但不确定这是不是用Redemption获取信息的正确方式。(注:原内容配图显示Outlook导航面板里「共享日历」组下的多个共享日历条目)
我已经用Interop实现了可正常运行的代码,但想知道用Redemption实现是否更简便,Interop代码如下:
private static IEnumerable<string> ListSharedCalendars() { Outlook.Folder myCalendar = null; Outlook.Explorers myExplorers = null; Outlook.Explorer myCalendarExplorer = null; Outlook.CalendarModule calendarModule = null; Outlook.NavigationGroups navGroups = null; Outlook.NavigationFolders myNavigationFolders = null; Outlook.NavigationPane myNavigationPane = null; Outlook.NavigationModules myNavigationModules = null; List<string> calendarList = new List<string>(); try { application = new Outlook.Application(); nameSpace = application.GetNamespace("MAPI"); myCalendar = nameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar) as Outlook.Folder; myExplorers = application.Explorers; myCalendarExplorer = myExplorers.Add(myCalendar, Outlook.OlFolderDisplayMode.olFolderDisplayNormal); if (myExplorers.Count > 0) { try { myNavigationPane = myCalendarExplorer.NavigationPane; myNavigationModules = myNavigationPane.Modules; calendarModule = myNavigationModules["Calendar"] as Outlook.CalendarModule; navGroups = calendarModule.NavigationGroups; int groupCount = navGroups.Count; try { for (int x = 1; x <= groupCount; x++) { try { calendarList.Add(navGroups[x].Name); myNavigationFolders = navGroups[x].NavigationFolders; int navfolderCount = myNavigationFolders.Count; for (int y = 1; y <= navfolderCount; y++) { calendarList.Add("\t-" + myNavigationFolders[y].DisplayName); } } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } finally { if (myNavigationFolders != null) { Marshal.ReleaseComObject(myNavigationFolders); myNavigationFolders = null; } } } } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } finally { if (navGroups != null) { Marshal.ReleaseComObject(navGroups); navGroups = null; } } } catch (System.Exception otlEx) { System.Diagnostics.Debug.WriteLine(otlEx); } finally { if (navGroups != null) { Marshal.ReleaseComObject(navGroups); navGroups = null; } if (calendarModule != null) { Marshal.ReleaseComObject(calendarModule); calendarModule = null; } if (myNavigationModules != null) { Marshal.ReleaseComObject(myNavigationModules); myNavigationModules = null; } if (myNavigationPane != null) { Marshal.ReleaseComObject(myNavigationPane); myNavigationPane = null; } } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } finally { if (myExplorers != null) { Marshal.ReleaseComObject(myExplorers); myExplorers = null; } if (myCalendarExplorer != null) { Marshal.ReleaseComObject(myCalendarExplorer); myCalendarExplorer = null; } if (calendarModule != null) { Marshal.ReleaseComObject(calendarModule); calendarModule = null; } if (navGroups != null) { Marshal.ReleaseComObject(navGroups); navGroups = null; } if (myNavigationFolders != null) { Marshal.ReleaseComObject(myNavigationFolders); myNavigationFolders = null; } if (myNavigationPane != null) { Marshal.ReleaseComObject(myNavigationPane); myNavigationPane = null; } if (myNavigationModules != null) { Marshal.ReleaseComObject(myNavigationModules); myNavigationModules = null; } if (myCalendar != null) { Marshal.ReleaseComObject(myCalendar); myCalendar = null; } nameSpace.Logoff(); if (nameSpace != null) { Marshal.ReleaseComObject(nameSpace); nameSpace = null; } if (application != null) { Marshal.ReleaseComObject(application); application = null; } } return calendarList; }
Redemption实现方案
你可以通过Redemption的RDONavigationPane对象直接访问导航面板中的「共享日历」组,逻辑和Interop类似但代码更简洁,且无需手动释放COM对象(Redemption会自动处理资源):
private static IEnumerable<string> ListSharedCalendarsRedemption() { List<string> calendarList = new List<string>(); using (RDOSession rdoSession = new RDOSession()) { rdoSession.Logon(); // 获取日历对应的导航模块 RDONavigationModule calendarModule = rdoSession.NavigationPane.Modules.GetByType(rdoDefaultFolders.olFolderCalendar); if (calendarModule != null && calendarModule is RDOCalendarModule) { RDOCalendarModule rdoCalendarModule = (RDOCalendarModule)calendarModule; // 遍历导航组,定位到「共享日历」组 foreach (RDONavigationGroup group in rdoCalendarModule.NavigationGroups) { if (group.Name == "共享日历") // 英文环境需改为"Shared Calendars",需和界面显示一致 { calendarList.Add(group.Name); // 遍历组下所有共享日历 foreach (RDONavigationFolder navFolder in group.NavigationFolders) { calendarList.Add("\t-" + navFolder.DisplayName); // 如需获取实际日历文件夹对象,可使用: // RDOFolder targetCalendar = navFolder.Folder; } break; // 找到目标组后退出循环 } } } rdoSession.Logoff(); } return calendarList; }
关键说明
- 无需创建额外的Explorer窗口,直接通过
RDOSession.NavigationPane访问导航面板,效率更高。 - Redemption会自动管理COM对象资源,不用手动调用
Marshal.ReleaseComObject。 - 注意组名称要和Outlook界面显示完全匹配,不同语言环境需调整对应名称。
- 若要对日历进行读写操作,可通过
RDONavigationFolder.Folder获取对应的RDOFolder对象。
内容的提问来源于stack exchange,提问作者ezG
相关产品推荐
相关产品推荐

