VSTO Outlook插件:无需重启获取新增账户及StoreID的技术求助
可行解决方案
强制刷新MAPI会话缓存
先通过IMAPISession::Advise注册账户变更通知,当捕获到新增账户事件后,不要复用之前的账户对象,重新调用IMAPISession::GetAccountsTable获取最新账户列表。另外,调用IMAPISession::OpenMsgStore时传入MDB_NO_CACHE标志,绕过缓存直接打开存储,再通过存储对象获取ID关联到对应账户。尝试Outlook对象模型同步后读取
虽然原生C#属性无法即时获取新增账户,但可以触发同步后再读取:调用Namespace.SendAndReceive(true)强制同步所有账户,等待几秒确保数据更新,然后遍历Namespace.Accounts集合,通过Account.DeliveryStore.StoreID获取StoreID。调用MAPI原生刷新函数
部分MAPI版本提供HrRefreshAllAccounts函数(需链接Mapi32.lib),可以强制刷新账户缓存,调用成功后再重新读取账户的PROP_ACCT_DELIVERY_STORE属性。示例代码:HRESULT hRes = HrRefreshAllAccounts(lpSession); if (SUCCEEDED(hRes)) { // 重新获取账户实例并读取目标属性 hRes = lpAccount->GetProp(PROP_ACCT_DELIVERY_STORE, &pProp); }注册表解析(备选方案)
Outlook账户配置存储在注册表HKEY_CURRENT_USER\Software\Microsoft\Office\<Outlook版本>\Outlook\Profiles\<配置文件名>\9375CFF0413111d3B88A00104B2A6676的子项中,可解析对应二进制项提取StoreID,但该方式依赖Outlook版本和配置,兼容性较差,仅作为兜底方案。
注意事项
- 操作MAPI COM对象时务必正确释放,避免内存泄漏。
- 优先使用MAPI原生方法,注册表解析仅在其他方案失效时尝试。
- 需在不同Outlook版本(2016/2019/365)中测试,确保兼容性。
内容的提问来源于stack exchange,提问作者Dmitry Kosovets

