2010-06-25 13 views
0

Est-il possible d'utiliser Automation pour Outlook 2003 avec Silverlight 4? Ou peut-être il existe une façon différente d'utiliser Outlook 2003 MAPI dans l'application Silverlight?Comment puis-je obtenir des données Outlook 2003 dans l'application Silverlight 4

J'utilise Silverlight 4 et je suis en train d'interagir avec Outlook ainsi:

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

Pour Outlook 2007/2010 tout fonctionne très bien. Mais quand j'essaie d'utiliser n'importe quel champ d'instance dynamique (par exemple outlook.Session) à partir d'Outlook 2003, alors j'ai obtenu NotSupportedException. C'est seulement le problème d'Outlook 2003.

J'ai trouvé l'article http://msdn.microsoft.com/en-us/library/aa159619%28office.11%29.aspx mais il est inutile pour l'application Silverlight (impossible de faire référence à l'assemblage de bureau ou COM directement).

Type.GetTypeFromProgID est également inutile, Silverlight ne le supporte pas.

Répondre

1

J'ai enfin trouvé une réponse. La plupart des actions peuvent être effectuées à l'aide du modèle d'objet Outlook 2003 standard. Toutes ces actions décrites dans this Microsoft article. Différence principale entre les exemples dans l'article et le code Silverlight - nous ne pouvons pas référencer l'assemblage Interop Outlook, nous devons donc utiliser la dynamique. Il est donc assez facile d'obtenir tous les contacts de la liste de contacts ou de tous les e-mails de la boîte de réception (voir l'article). La partie la plus difficile est l'obtention de la liste des comptes de l'utilisateur créé. modèle objet Outlook 2003 offre la possibilité d'obtenir un seul (par défaut) compte:

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

Mais il est ne toujours pas convenable pour moi. C'est très triste, mais il n'y a pas de propriété Session.Accounts dans le modèle d'objet Outlook 2003. Donc, j'ai trouvé un seul moyen difficile d'obtenir la liste des comptes.

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

astuce principale est en cours d'utilisation de AutomationFactory.CreateObject ("WScript.Shell"). Maintenant, il est possible d'obtenir des informations de compte directement à partir du registre en utilisant la méthode RegRead. Par ailleurs, ce code fonctionne bien même pour Outlook 2007/2010. Et pour moi, il est préférable que les comptes soient collectés en silence (il n'est pas nécessaire de lancer Outlook avant la collecte des données).