2017-08-17 35 views
5

Opracowaliśmy dodatek VSTO do C# Office, który komunikuje się z działającą instancją programu Outlook (lub uruchamia nową), i wykazuje oznaki problemy z uprawnieniami na niektórych komputerach klientów, starając się tworzyć zadania Outlook lub spotkania ...Office VSTO add-in możliwe problemy z uprawnieniami - HRESULT 0x80004004 (E_ABORT)

komunikat wyjątkiem jest następujący:

Operacja przerwana (wyjątek od HRESULT: 0x80004004 (E_ABORT))

Th to dzieje się tutaj:

Outlook.Account DefaultAccount = null; 
Outlook.Application outlookApp = GetOutlookApp(); //returns Application object of running Outlook instance/creates a new instance - it works for them. 

DefaultAccount = GetAccountForFolder(outlookApp); //returns the default account of the user. Tried it with a simple setup, only one account etc. - it works for them 
String defaultemailaddress; 

//CODE RUNS UNTIL THIS POINT 
if (DefaultAccount == null) //if somehow this would end up NULL, which is not the case, because: see code snippet below! 
{ 
    defaultemailaddress = outlookApp.Session.CurrentUser.AddressEntry.Address; 
} 
else 
{ 
    defaultemailaddress = DefaultAccount.SmtpAddress; //this could be the problem, but I can't debug it further, and it works in the code block below, to get the AccountType, so I don't understand why I couldn't get the SmtpAddress without a hard exception 
} 
//FAILS BEFORE THIS LINE COULD RUN. 
String email = "[email protected]"; 

Po uzyskaniu kontaktu z użytkownikiem, ale powiedziano nam, że są one uruchomione pod bardzo ograniczony zestaw uprawnień i sieci.

Weird rzeczą jest, ten fragment kodu faktycznie działa płynnie na nich, co dowodzi, że połączenie działa między programami Outlook i drugiej Urzędu dodatek:

Outlook.Application oApp = GetOutlookApp(); 
Outlook.Account DefaultAccount = GetAccountForFolder(oApp); 
String AccountType = DefaultAccount.AccountType.ToString(); 

Dział IT już próbuje się dostosować polityki bezpieczeństwa programu Outlook na zagrożonym komputerze. Pozwoliły na programowy dostęp.

Nie można uruchomić narzędzi z uprawnieniami administratora, ale nie powinno to być konieczne. Fakt, że te ostatnie trzy linie kodu działają (które pobiera typ konta) dowodzi, że aplikacja faktycznie uruchamia się poprawnie, ale wygląda na to, że może uruchomić tylko niektóre funkcje ...

Chcę również zwrócić uwagę, że używają Exchange, ale najwyraźniej nie mają problemów z synchronizacją (jeśli mogą wpłynąć na wszystko, w ogóle ...)

EDYTOWANIE: Oto implementacja GetAccountForFolder, która pobiera domyślny obiekt Outlook.Account. To fragment kodu, który znalazłem w pobliżu i okazało się, że działa świetnie.

public static Outlook.Account GetAccountForFolder(Outlook.Application outlookApp) 
{ 
    // Obtain the store on which the folder resides. 
    Outlook.Store store = outlookApp.Session.DefaultStore; 

    // Enumerate the accounts defined for the session. 
    foreach (Outlook.Account account in outlookApp.Session.Accounts) 
    { 
     // Match the DefaultStore.StoreID of the account 
     // with the Store.StoreID for the currect folder. 
     if (account.DeliveryStore.StoreID == store.StoreID) 
     { 
      // Return the account whose default delivery store 
      // matches the store of the given folder. 
      return account; 
     } 
    } 
    // No account matches, so return null. 
    return null; 
} 
+0

Jaka jest twoja implementacja GetAccountForFolder? Czy używasz tego samego problemu w OutlookSpy? (kliknij przycisk Przestrzeń nazw, wybierz Konta, kliknij Przeglądaj, przejdź do zakładki IEnumVariant, dwukrotnie kliknij dane konto). –

+0

Cześć Dmitry! Dziękuję za aktywną pracę nad wszystkim, co dotyczy programu Outlook. Znalazłem wiele komentarzy/odpowiedzi, które są pomocne! Czy masz na myśli, że powinienem poprosić użytkownika o zainstalowanie OutlookSpy i użyć go do tego dochodzenia? – Laureant

Odpowiedz

1

Problemem jest to, że masz race condition in a COM Add-In object. Powinieneś zrobić sztuczne opóźnienie w swojej metodzie. Proste powtarzanie, dopóki ci się nie uda, tak:

bool isDone = false; 
while (!isDone) 
{ 
    try 
    { 
     // your action with Add-In here... 

     isDone = true; 
    } 
    catch (System.Runtime.InteropServices.COMException exception) 
    { 
     // small delay 
     Thread.Sleep(10); 
    } 
} 
+0

Rozumiem. Pojawia się błąd 0x80004004, ponieważ jeden z obiektów nie jest dostępny YET przez mój dodatek. Myślę, że ważną rzeczą jest to, że komunikujemy się z Outlookiem, spoza Outlooka. – Laureant

0

może być konieczne w celu umożliwienia lekkim opóźnieniem po pobraniu konta.

Outlook.Account DefaultAccount = null; 
Outlook.Application outlookApp = GetOutlookApp(); 
DefaultAccount = GetAccountForFolder(outlookApp); 
Thread.Sleep(5000); // a bit of startup grace time. 

Błąd Przerwano 0x80004004 często pojawia się w Interop.Outlook ze względu na to, patrz Can only send email via Outlook if Outlook is open

Powiązane problemy