开发Outlook插件:通过IMAP QUOTAROOT命令获取账户配额的官方方案
实现Outlook插件获取IMAP账户配额的官方方案
Outlook本身没有直接暴露已建立的IMAP连接供插件复用的官方API,但可以通过以下两种合规的官方途径实现需求,无需读取注册表:
方案1:获取Outlook账户设置 + 读取Windows凭据管理器中的凭据
步骤1:通过Outlook对象模型获取IMAP账户配置
利用Microsoft.Office.Interop.Outlook库遍历账户,提取IMAP服务器地址、端口、加密方式、用户名等关键配置:
using Outlook = Microsoft.Office.Interop.Outlook; public void FetchImapAccountConfigs() { var outlookApp = new Outlook.Application(); var accounts = outlookApp.Session.Accounts; foreach (Outlook.Account account in accounts) { if (account.AccountType == Outlook.OlAccountType.olImap) { string smtpAddress = account.SmtpAddress; string imapServer = account.IMAPServer; int imapPort = account.IMAPPort; bool useSsl = account.IMAPUseSSL; string userName = account.UserName; // 保存这些配置,用于后续建立IMAP连接 } } }
步骤2:从Windows凭据管理器读取账户凭据
Outlook会将IMAP账户的凭据存储在Windows凭据管理器中,可通过官方Windows API读取(无需注册表操作):
using System.Runtime.InteropServices; public static class CredentialHelper { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct Credential { public uint Flags; public uint Type; public string TargetName; public string Comment; public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten; public uint CredentialBlobSize; public IntPtr CredentialBlob; public uint Persist; public uint AttributeCount; public IntPtr Attributes; public string TargetAlias; public string UserName; } [DllImport("advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)] private static extern bool CredRead(string target, uint type, uint flags, out IntPtr credentialPtr); [DllImport("advapi32.dll", EntryPoint = "CredFree", SetLastError = true)] private static extern bool CredFree(IntPtr credentialPtr); public static (string UserName, string Password) GetImapCredential(string targetIdentifier) { IntPtr credPtr = IntPtr.Zero; try { // CRED_TYPE_GENERIC = 1 bool success = CredRead(targetIdentifier, 1, 0, out credPtr); if (!success) return (null, null); var cred = Marshal.PtrToStructure<Credential>(credPtr); string password = Marshal.PtrToStringUni(cred.CredentialBlob, (int)cred.CredentialBlobSize / 2); return (cred.UserName, password); } finally { if (credPtr != IntPtr.Zero) CredFree(credPtr); } } } // 使用示例:构造凭据目标标识(格式需根据Outlook版本调整,如"IMAP:{imapServer}:{imapPort}:{userName}") // var credential = CredentialHelper.GetImapCredential($"IMAP:{imapServer}:{imapPort}:{userName}");
步骤3:建立IMAP连接并发送QUOTAROOT命令
用第三方IMAP库(如MailKit)建立连接,发送命令并解析结果:
using MailKit.Net.Imap; public async Task<string> GetQuotaInfo(string server, int port, bool useSsl, string userName, string password) { using var client = new ImapClient(); await client.ConnectAsync(server, port, useSsl); await client.AuthenticateAsync(userName, password); // 发送QUOTAROOT命令并获取响应 var quotaResponse = client.Command("QUOTAROOT INBOX"); await client.DisconnectAsync(true); return quotaResponse.ToString(); }
方案2:使用Extended MAPI(官方底层API)
如果需要更底层的账户信息或尝试复用MAPI上下文,可使用Extended MAPI(Outlook的原生底层API)。C#中使用需通过COM互操作,或借助第三方包装库(如Redemption,基于官方MAPI实现,合规且简化开发):
- 通过Redemption的
RDOAccount对象可直接获取IMAP账户的完整配置 - 部分版本支持通过
RDOIMAPFolder发送原始IMAP命令,无需重新建立连接
注意:使用Extended MAPI需确保Outlook客户端已安装,且插件需具备相应权限。
内容的提问来源于stack exchange,提问作者Disti
相关产品推荐
相关产品推荐

