如何在 Silverlight 4 应用程序中获取 Outlook 2003 数据

发布于 2024-09-07 04:47:40 字数 714 浏览 6 评论 0原文

是否可以将 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 不支持它。

Is it possible to use Automation for Outlook 2003 with Silverlight 4? Or maybe there are some different way to use Outlook 2003 MAPI in Silverlight application?

I'm using Silverlight 4 and I'm trying interact with Outlook in this way:

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

For Outlook 2007/2010 all works fine.

But when I try use any field of dynamic instance (for example outlook.Session) from Outlook 2003 then I've get NotSupportedException. It's only Outlook 2003 problem.

I found article http://msdn.microsoft.com/en-us/library/aa159619%28office.11%29.aspx but it's useless for Silverlight application (impossible to get reference to office assembly or COM directly).

Type.GetTypeFromProgID is useless too, Silverlight doesn't support it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

美羊羊 2024-09-14 04:47:40

我终于找到答案了。
大多数操作都可以使用标准 Outlook 2003 对象模型来执行。 这篇 Microsoft 文章中描述了所有这些操作。
文章中的示例与 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)。

I’ve finally found an answer.
Most of actions can be performed using standard Outlook 2003 object model. All these actions described in this Microsoft article.
Main difference between examples in article and Silverlight code – we can’t refer Interop Outlook assembly, so we need to use dynamics.
So it’s pretty easy to get all contacts from contact list or all inbox emails (see article). Most difficult part is obtaining list of created user’s accounts. Outlook 2003 object model provide possibility to obtain only one (default) account:

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

But it’s still doesn’t suitable for me. It’s very sad, but there is no Session.Accounts property in Outlook 2003 object model. So I’ve found only one tricky way to obtain list of 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; }
}

Main trick is in use of AutomationFactory.CreateObject("WScript.Shell"). Now it’s possible to get account information directly from registry using RegRead method. By the way this code works well even for Outlook 2007/2010. And as for me it’s most preferable way if accounts should be collected silently (there is no need to launch Outlook before data collecting).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文