Windows联系人API已弃用,.NET 6+中唯一可靠方案是调用Outlook COM接口,前提是安装匹配位数的Microsoft Outlook;其他如WAB或旧注册表路径在Win10 1903后基本失效。
Windows联系人API已弃用,别再找ContactManager
windows 10/11 的“联系人”app 底层用的是 windows.applicationmodel.contacts 命名空间,但它从 windows 10 version 1809 开始被标记为 deprecated,且在 .net 5+ 中完全不可用。你用 visual studio 新建一个 .net 6 或 .net 8 项目,直接引用这个命名空间会报错:the type or namespace name 'contacts' does not exist。这不是你环境没配好,是微软真关了这扇门。
真正能走通的路径只有两条:读取 Outlook PST/OST(如果用户装了 Outlook),或解析系统级的 WAB(Windows Address Book)旧文件 —— 但后者仅限传统桌面应用,且 Win10 之后默认不启用。
.NET 6+ 里唯一靠谱的方式:调用 Outlook COM 接口
前提是目标机器已安装 Microsoft Outlook(不是 Outlook Web 或 Outlook for Mac),且是 32/64 位匹配的版本(比如你的 C# 程序编译为 x64,Outlook 也得是 x64)。这是目前最稳定、权限可控、数据完整的方案。
- 添加 COM 引用:
Microsoft Outlook xx.0 Object Library(xx 取决于 Office 版本,如 16 表示 Office 2016/365) - 必须用
dynamic或早期绑定方式访问Application.Session.GetDefaultFolder(olFolderContacts),硬转ContactsFolder类型容易崩 - 遍历联系人时,字段名是字符串索引:
contact["FirstName"]、contact["Email1Address"],不是强类型属性;不存在的字段返回null,别直接.ToString() - 记得在 finally 里调用
Marshal.ReleaseComObject()释放 COM 对象,否则 Outlook 进程会卡死不退出
读不到联系人?先检查这三个地方
常见错误不是代码写错,而是环境卡在前置条件上:
-
System.Runtime.InteropServices.COMException: 拒绝访问→ 当前用户没登录 Outlook,或 Outlook 正以管理员身份运行(而你的程序没提权) - 返回空集合,但 Outlook 里明明有联系人 → 检查 Outlook 是否设定了默认配置文件(
Application.DefaultProfileName),多账户用户常踩这个坑 - 只读到部分联系人 → Outlook 联系人分“此计算机上的联系人”和“Exchange 联系人”,后者需额外权限,且
Items.Restrict()过滤时要用 DASL 语法,比如@SQL="http://schemas.microsoft.com/mapi/proptag/0x39FE001E" = 'SMTP'
别碰 WAB(wab32.dll)和旧注册表路径
网上很多博客教你怎么 P/Invoke WABOpen 或读 HKEY_CURRENT_USER\Software\Microsoft\WAB\WAB4\Wab File Name,这些在 Win10 1903 后基本失效。WAB 服务默认禁用,注册表项可能根本不存在;即使存在,返回的也是加密或结构不兼容的二进制块,没有公开文档能安全解析。
如果你的应用必须支持无 Outlook 环境,唯一现实的选择是引导用户导出为 CSV,或接入 Microsoft Graph API(需要 Azure AD 配置、用户授权、网络可达),而不是硬啃本地遗留接口。
真正的难点从来不在怎么写那几行 C#,而在搞清「谁拥有这些数据」「谁允许你读」「格式是否还在有效生命周期内」——Windows 联系人这块,系统层面早就把路收窄了。


















