【问题标题】:How can I get Outlook 2003 data in Silverlight 4 application如何在 Silverlight 4 应用程序中获取 Outlook 2003 数据
【发布时间】:2013-05-11 04:15:32
【问题描述】:

是否可以将 Automation for Outlook 2003 与 Silverlight 4 一起使用?或者也许有一些不同的方法可以在 Silverlight 应用程序中使用 Outlook 2003 MAPI?

我正在使用 Silverlight 4,并尝试以这种方式与 Outlook 交互:

dynamic outlook = AutomationFactory.GetObject("Outlook.Application"); 

对于 Outlook 2007/2010,一切正常。

但是当我尝试使用 Outlook 2003 中的任何动态实例字段(例如 Outlook.Session)时,我得到了 NotSupportedException。这只是 Outlook 2003 的问题。

我找到了文章http://msdn.microsoft.com/en-us/library/aa159619%28office.11%29.aspx,但它对 Silverlight 应用程序毫无用处(无法直接引用 office 程序集或 COM)。

Type.GetTypeFromProgID 也无用,Silverlight 不支持。

【问题讨论】:

    标签: c# silverlight silverlight-4.0 outlook-2003


    【解决方案1】:

    我终于找到了答案。 大多数操作都可以使用标准 Outlook 2003 对象模型来执行。 this Microsoft article 中描述的所有这些操作。 文章中的示例和 Silverlight 代码之间的主要区别 - 我们不能引用 Interop Outlook 程序集,因此我们需要使用动态。 因此,从联系人列表或所有收件箱电子邮件中获取所有联系人非常容易(参见文章)。最困难的部分是获取已创建用户帐户的列表。 Outlook 2003 对象模型提供了仅获取一个(默认)帐户的可能性:

    dynamic outlook = AutomationFactory.CreateObject("Outlook.Application");
    var ns = outlook.GetNamespace("MAPI");
    var defaultAccount = ns.CurrentUser;
    

    但它仍然不适合我。很遗憾,但 Outlook 2003 对象模型中没有 Session.Accounts 属性。所以我只找到了一种获取帐户列表的棘手方法。

    public class Ol11ImportStrategy 
        {
            const string registryPath = @"HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6676\{0}\{1}";
            const string constAccountName = "Account Name";
            const string constEmail = "Email";
            const string constSMTPServer = "SMTP Server";
            const string constName = "Display Name";
            const string constIMAPServer = "IMAP Server";
            const string constPOP3Server = "POP3 Server";
            const string constValueClsid = "clsid";
            const string constContentsAccountClsid_POP3 = "{ED475411-B0D6-11D2-8C3B-00104B2A6676}";
            const string constContentsAccountClsid_IMAP = "{ED475412-B0D6-11D2-8C3B-00104B2A6676}";
    
            public IEnumerable<AccountEntity> GetAccountsInFriendlyFormat()
            {
                List<AccountEntity> accounts = new List<AccountEntity>();
    
                using (dynamic WShell = AutomationFactory.CreateObject("WScript.Shell"))
                {
                    for (int i = 1; i < 1000; i++)
                    {
                        try
                        {
                            string classId = WShell.RegRead(String.Format(registryPath, i.ToString().PadLeft(8, '0'), constValueClsid));
    
                            if (StringComparer.InvariantCultureIgnoreCase.Compare(classId, constContentsAccountClsid_POP3) == 0)
                            {
                                accounts.Add(new AccountEntity
                                {
                                    FriendlyName = GetRegisterElementValue(WShell, i.ToString(), constAccountName),
                                    IncomingMailServer = GetRegisterElementValue(WShell, i.ToString(), constPOP3Server),
                                    Email = GetRegisterElementValue(WShell, i.ToString(), constEmail),
                                    UserName = GetRegisterElementValue(WShell, i.ToString(), constName)
                                });
                                continue;
                            }
    
                            if (StringComparer.InvariantCultureIgnoreCase.Compare(classId, constContentsAccountClsid_IMAP) == 0)
                            {
                                accounts.Add(new AccountEntity
                                {
                                    FriendlyName = GetRegisterElementValue(WShell, i.ToString(), constAccountName),
                                    IncomingMailServer = GetRegisterElementValue(WShell, i.ToString(), constIMAPServer),
                                    Email = GetRegisterElementValue(WShell, i.ToString(), constEmail),
                                    UserName = GetRegisterElementValue(WShell, i.ToString(), constName)
                                });
                                continue;
                            }
    
                            //it isn't POP3 either IMAP
                        }
                        catch (FileNotFoundException e)
                        {
                            //classId isn't found - we can break iterations because we already iterate through all elements
                            break;
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show("Unknown exception");
                        }
                    }
                }
    
                return accounts;
            }
    
            private string GetRegisterElementValue(object scriptShell, string elementNumber, string elementName)
            {
                dynamic shell = scriptShell;
                string currentElement = elementNumber.PadLeft(8, '0');
    
                object[] currentElementData = shell.RegRead(String.Format(registryPath, currentElement, elementName));
    
                byte[] dataBytes = currentElementData.Cast<byte>().ToArray();
                return Encoding.Unicode.GetString(dataBytes, 0, dataBytes.Count()).Trim('\0');
            }
        }
    
    public class AccountEntity
    {
        public string FriendlyName { get; set; }
        public string UserName { get; set; }
        public string Email { get; set; }
        public string AccountType { get; set; }
        public string IncomingMailServer { get; set; }
    }
    

    主要技巧是使用 AutomationFactory.CreateObject("WScript.Shell")。现在可以使用 RegRead 方法直接从注册表中获取帐户信息。顺便说一句,即使对于 Outlook 2007/2010,此代码也能正常工作。对于我来说,最好的方式是静默收集帐户(在收集数据之前无需启动 Outlook)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-19
      • 2019-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多