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

如何在C#中获取Outlook中未知收件人的所有共享文件夹

好问题!我之前做Outlook集成的时候也遇到过这个需求——不用指定收件人就能获取所有共享文件夹。其实可以通过遍历Outlook的存储和文件夹树,结合所有者判断来实现,下面是具体的思路和代码示例:

实现思路

Outlook里的共享文件夹主要分两种:一种是完整的共享邮箱(会作为独立的Store挂载),另一种是单个共享的子文件夹(挂在你自己的邮箱文件夹下)。我们可以分两步处理:

  • 遍历所有Store,筛选出不属于当前用户的共享邮箱,直接递归获取其下所有文件夹
  • 遍历当前用户邮箱的文件夹树,检查每个文件夹的所有者是否为他人,以此判断是否是共享子文件夹
完整代码示例

首先要确保你引用了Microsoft.Office.Interop.Outlook程序集,然后可以用以下代码实现:

using System.Collections.Generic;
using System.Runtime.InteropServices;
using Outlook = Microsoft.Office.Interop.Outlook;

public class OutlookSharedFolderHelper
{
    public List<Outlook.Folder> GetAllSharedFolders()
    {
        List<Outlook.Folder> sharedFolders = new List<Outlook.Folder>();
        Outlook.Application outlookApp = new Outlook.Application();
        Outlook.NameSpace mapiNamespace = outlookApp.GetNamespace("MAPI");

        // 遍历所有存储容器(包括主邮箱和共享邮箱)
        foreach (Outlook.Store store in mapiNamespace.Stores)
        {
            // 处理完整的共享邮箱:判断是否是Exchange邮箱且所有者不是当前用户
            if (store.ExchangeStoreType == Outlook.OlExchangeStoreType.olExchangeMailbox && 
                store.Owner?.Name != mapiNamespace.CurrentUser.Name)
            {
                var rootFolder = store.GetRootFolder() as Outlook.Folder;
                if (rootFolder != null)
                {
                    AddAllSubfolders(rootFolder, sharedFolders);
                }
            }
            else
            {
                // 处理当前邮箱下的共享子文件夹
                var rootFolder = store.GetRootFolder() as Outlook.Folder;
                if (rootFolder != null)
                {
                    CheckSharedSubfolders(rootFolder, sharedFolders);
                }
            }
            Marshal.ReleaseComObject(store);
        }

        // 清理COM对象,避免内存泄漏
        mapiNamespace.Logoff();
        Marshal.ReleaseComObject(mapiNamespace);
        Marshal.ReleaseComObject(outlookApp);

        return sharedFolders;
    }

    // 递归添加共享邮箱下的所有子文件夹
    private void AddAllSubfolders(Outlook.Folder parentFolder, List<Outlook.Folder> sharedFolders)
    {
        sharedFolders.Add(parentFolder);

        foreach (Outlook.Folder subFolder in parentFolder.Folders)
        {
            AddAllSubfolders(subFolder, sharedFolders);
            Marshal.ReleaseComObject(subFolder);
        }
    }

    // 递归检查当前邮箱下的文件夹是否为共享文件夹
    private void CheckSharedSubfolders(Outlook.Folder parentFolder, List<Outlook.Folder> sharedFolders)
    {
        // 判断条件:文件夹所有者存在且不是当前用户
        if (parentFolder.Owner != null && 
            parentFolder.Owner.Name != parentFolder.Session.CurrentUser.Name)
        {
            sharedFolders.Add(parentFolder);
        }

        foreach (Outlook.Folder subFolder in parentFolder.Folders)
        {
            CheckSharedSubfolders(subFolder, sharedFolders);
            Marshal.ReleaseComObject(subFolder);
        }
    }
}
注意事项
  • COM对象释放:Outlook是COM组件,使用后必须手动释放对象,否则会导致Outlook进程残留内存泄漏,代码里已经用Marshal.ReleaseComObject处理了。
  • 权限判断:如果需要更精确的权限筛选(比如只获取有编辑权限的共享文件夹),可以结合Folder.PermissionSet属性来进一步判断。
  • 类型筛选:如果只需要特定类型的共享文件夹(比如日历、联系人),可以在添加时检查parentFolder.DefaultItemType,比如筛选日历可以判断parentFolder.DefaultItemType == Outlook.OlItemType.olAppointmentItem。
  • Outlook版本兼容:这段代码在Outlook 2016及以上版本测试有效,旧版本可能需要调整部分属性的判断逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:16:48