Как я могу получить данные Outlook 2003 в приложении Silverlight 4 - PullRequest
0 голосов
/ 25 июня 2010

Можно ли использовать Automation for Outlook 2003 с Silverlight 4?Или, может быть, есть другой способ использовать Outlook 2003 MAPI в приложении Silverlight?

Я использую Silverlight 4 и пытаюсь взаимодействовать с Outlook следующим образом:

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

ДляOutlook 2007/2010 все отлично работает.

Но когда я пытаюсь использовать любое поле динамического экземпляра (например, outlook.Session) из Outlook 2003, я получаю NotSupportedException.Это только проблема Outlook 2003.

Я нашел статью http://msdn.microsoft.com/en-us/library/aa159619%28office.11%29.aspx, но она бесполезна для приложения Silverlight (невозможно получить ссылку на офисную сборку или COM непосредственно).

Type.GetTypeFromProgIDбесполезно, Silverlight не поддерживает его.

1 Ответ

1 голос
/ 07 июля 2010

Я наконец нашел ответ.Большинство действий может быть выполнено с использованием стандартной объектной модели 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 перед сбором данных).

...