2017-08-17 127 views
5

我們開發了一個C#Office VSTO加載項,與正在運行的Outlook實例進行通信(或啓動一個新的實例),並顯示有一些客戶的電腦權限問題,而試圖創建Outlook任務或約會......Office VSTO加載可能的權限問題 - HRESULT 0x80004004(E_ABORT)

異常消息是:

操作中止(從HRESULT異常:0x80004004(E_ABORT))

Th是發生在這裏:

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]"; 

與用戶取得聯繫後,他們告訴我們,他們正在下實在有限權限集和網絡中運行。

奇怪的是,該代碼片段實際上運行平穩對他們來說,這證明,該連接是Outlook和其他Office插件之間的工作:

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

IT部門已經嘗試調整受影響PC上Outlook的安全策略。他們允許編程訪問。

他們無法以管理員權限啓動工具,但不應該有必要。那些過去的3行代碼的工作(其中獲取帳戶類型)證明該應用程序啓動確實正確,但是看起來它只能運行某些功能的事實...

我也想說明,他們使用Exchange,但顯然他們沒有同步問題(如果這些可能會影響任何東西,根本...)

編輯: 這裏是GetAccountForFolder的實現,它獲取默認的Outlook.Account對象。這是我發現的一段代碼片段,並且發現它工作得很好。

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

你的GetAccountForFolder的實現是什麼?你在OutlookSpy中使用相同的問題嗎? (單擊名稱空間按鈕,選擇帳戶,單擊瀏覽,轉至IEnumVariant選項卡,雙擊相關帳戶)。 –

+0

嗨德米特里!感謝您積極解決與Outlook有關的任何問題,我發現很多意見/答案都很有幫助!你的意思是我應該讓用戶安裝OutlookSpy,並將其用於此調查? – Laureant

回答

1

的問題是,你有race condition in a COM Add-In object。你應該在你的方法中進行人爲延遲。簡單地重試直到你成功,像這樣:

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

我明白了。所以我得到錯誤0x80004004,因爲其中一個對象不能通過我的加載項訪問。我認爲這裏重要的是,我們正在從Outlook之外與Outlook進行通信。 – Laureant

0

您可能需要在獲取帳戶後允許稍微延遲。

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

夭折0x80004004錯誤通常在Interop.Outlook顯示出來,由於這一點,看到Can only send email via Outlook if Outlook is open