Pregunta

¿Es posible utilizar automatización para Outlook 2003 con Silverlight 4? O tal vez hay alguna manera diferente de utilizar MAPI Outlook 2003 en aplicación de Silverlight?

Estoy usando Silverlight 4 y estoy tratando de interactuar con Outlook de esta manera:

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

Para Outlook 2007/2010 todo funciona bien.

Pero cuando intento utilizar cualquier campo de instancia dinámica (por ejemplo outlook.Session) desde Outlook 2003 a continuación, he get NotSupportedException. No es más que un problema de Outlook 2003.

He encontrado el artículo http: // MSDN. microsoft.com/en-us/library/aa159619%28office.11%29.aspx pero es inútil para la aplicación de Silverlight (imposible conseguir referencia a la oficina de montaje o directamente COM).

Type.GetTypeFromProgID es inútil también, Silverlight no lo soporta.

¿Fue útil?

Solución

Por fin he encontrado una respuesta. La mayoría de las acciones se pueden realizar utilizando modelo de objetos estándar de Outlook 2003. Todas estas acciones descritas en este artículo Microsoft. La principal diferencia entre los ejemplos en el artículo y el código de Silverlight - que no puede referirse interoperabilidad de Outlook montaje, por lo que tenemos que utilizar la dinámica. Así que es bastante fácil de conseguir todos los contactos de la lista de contactos o todos los correos electrónicos de bandeja de entrada (ver artículo). La mayor parte difícil es la lista de las cuentas de usuario creado obtención. Perspectiva de modelo de objetos 2,003 proporcionar posibilidad de obtener sólo una (por defecto) cuenta:

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

Pero todavía no lo hace adecuado para mí. Es muy triste, pero no hay Session.Accounts propiedad en el modelo de objetos de Outlook 2003. Así que me he encontrado sólo una manera difícil de obtener lista de cuentas.

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; }
}

truco principal es en el uso de AutomationFactory.CreateObject ( "WScript.Shell"). Ahora es posible obtener información de la cuenta directamente desde el registro utilizando el método RegRead. Por cierto este código funciona bien incluso para Outlook 2007/2010. Y en cuanto a mí es la manera más preferible si las cuentas deben recogerse en silencio (no hay necesidad de lanzar Outlook antes de la recogida de datos).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top