2013-10-07 95 views
1

使用Outlook Interop,我創建了一個小應用程序連接到我的Outlook收件箱並收集30封電子郵件,然後將它們顯示在網格中。當您雙擊網格中的電子郵件時,它將在Outlook中打開電子郵件。Outlook Interop「RPC服務器不可用」當電子郵件打開

在應用程序中: - 打開一封電子郵件,儘量減少它。然後打開另一個,它會打開罰款。 - 打開電子郵件,關閉它。然後打開另一個,你會得到'RPC服務器不可用。 (來自HRESULT的例外: 0x800706BA)'錯誤。

我注意到發生這種情況時,系統托盤中的Outlook圖標消失。

我曾嘗試創建Microsoft.Office.Interop.Outlook.Application和命名空間的新實例,並添加註冊表設置在這裏找到:http://blogs.msdn.com/b/rgregg/archive/2008/10/27/application-shutdown-changes-in-outlook-2007-service-pack-2-beta.aspx

我正在運行的Office 2010

有誰知道如何解決這個問題?

Imports Microsoft.Office.Interop.Outlook 
Imports System.Runtime.InteropServices 
Imports System.Reflection 

Public Class Form1 
    Private m_outlookApplication As Application               'Outlook 
    Private m_nameSpace As Microsoft.Office.Interop.Outlook.NameSpace         'Outlook's namespace 
    Private WithEvents m_inboxItems As Items               'All Outlook inbox items 
    Private WithEvents m_calendarItems As Items               'All Outlook calendar items 
    Private m_outlookInstalled As Boolean = False              'indicates whether Outlook is installed on computer 
    Private m_emails As New List(Of OutlookInboxEmail)             'used to store inbox e-mail messages for grid view control 
    Private m_inboxFolder As MAPIFolder                 'Outlook inbox folder 
    Private m_calendarFolder As MAPIFolder                'Outlook calendar 
    Private m_explorer As Explorer                  'Outlook window explorer 
    Private m_name As String = String.Empty                'the name user who is connected 
    Public Sub New() 
     InitializeComponent() 

     connectToOutlook() 

     loadInbox() 
    End Sub 
    Private Sub connectToOutlook() 
     m_outlookApplication = New Microsoft.Office.Interop.Outlook.Application 
     m_nameSpace = m_outlookApplication.GetNamespace("MAPI") 
     m_nameSpace.Logon(Missing.Value, Missing.Value, False, True) 
     Dim connectionMode = m_nameSpace.ExchangeConnectionMode 
    End Sub 
    Private Sub loadInbox() 
     Try 

      'get inbox folder 
      m_inboxFolder = m_nameSpace.GetDefaultFolder(OlDefaultFolders.olFolderInbox) 
      'get inbox messages 
      m_inboxItems = m_inboxFolder.Items 
      m_emails.Clear() 
      'display recent messages first 
      m_inboxItems.Sort("ReceivedTime", True) 

      Dim numberOfEmailsToLoad As Integer = 30 
      'set displayed values for each message 
      For Each currentItem As Object In m_inboxItems 
       Dim emailItem = TryCast(currentItem, MailItem) 
       If Not emailItem Is Nothing Then 
        'check whether its e-mail 
        If emailItem.MessageClass = "IPM.Note" Then 
         'set email 
         Dim inboxEmail As New OutlookInboxEmail 
         inboxEmail.SenderName = emailItem.SenderName 
         inboxEmail.Subject = emailItem.Subject 
         inboxEmail.ReceivedTime = emailItem.ReceivedTime.ToString("dd MMMM HH:mm") 
         inboxEmail.Body = emailItem.Body 
         inboxEmail.Unread = emailItem.UnRead 
         inboxEmail.Email = emailItem 
         m_emails.Add(inboxEmail) 
         numberOfEmailsToLoad = numberOfEmailsToLoad - 1 
         If numberOfEmailsToLoad <= 0 Then 
          Exit For 
         End If 
        End If 
       End If 
      Next 

      If m_explorer Is Nothing Then 
       Try 
        m_explorer = m_outlookApplication.ActiveExplorer 
       Catch ex As System.Exception 

       End Try 
      End If 

      If GridControl1.DataSource Is Nothing Then 
       GridControl1.DataSource = Nothing 
       GridControl1.DataSource = m_emails 
      End If 
      GridControl1.RefreshDataSource() 
     Catch exception As System.Exception 

     End Try 
    End Sub 
    ''' <summary> 
    ''' Opens email in Outlook 
    ''' </summary> 
    ''' <remarks></remarks> 
    Private Sub openEmail() 
     If Not GridView1.GetFocusedDataSourceRowIndex < 0 Then 
      Dim selectedEmail = TryCast(m_emails(GridView1.GetFocusedDataSourceRowIndex), OutlookInboxEmail) 
      If Not selectedEmail Is Nothing Then 
       Try 

        If Process.GetProcessesByName("OUTLOOK").Count() = 0 Then 

        End If 

        selectedEmail.Email.Display() 
        selectedEmail.Unread = False 
        selectedEmail.EmailImage = My.Resources.Read_16 
       Catch exception As COMException 

       End Try 
       GridControl1.RefreshDataSource() 
      End If 
     End If 
    End Sub 
    Private Sub GridControlCalendar_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridControl1.DoubleClick 
     openEmail() 
    End Sub 
End Class 
+0

如果您看到任務欄圖標消失,則例外是預期結果。沒有任何暗示爲什麼它決定退出。在Windows應用程序日誌中查找麪包屑。 –

回答

2

經過幾個小時的調查,當消息被關閉時,它會關閉Outlook。

解決方案是在與Outlook進行交互之前檢查Outlook是否處於打開狀態。每隔2分鐘運行一次運行同一檢查的計時器,可確保我創建的Outlook收件箱視圖僅在Outlook關閉時過2分鐘過時。

Private Sub openEmail() 
     If Not GridViewInbox.GetFocusedDataSourceRowIndex < 0 Then 
      Dim selectedEmail = TryCast(m_emails(GridViewInbox.GetFocusedDataSourceRowIndex), OutlookInboxEmail) 
      If Not selectedEmail Is Nothing Then 
       Try 
        If Process.GetProcessesByName("OUTLOOK").Count() = 0 Then 
         'if outlook is not open.. open it 
         m_selectedEmail = selectedEmail 
         reconnectOutlook() 
        Else 
         'as outlook is open, open the email 
         selectedEmail.Email.Display() 
         selectedEmail.Unread = False 
         selectedEmail.EmailImage = ImageLibrary.My.Resources.Read_16 
         GridControlInbox.RefreshDataSource() 
         m_selectedEmail = Nothing 
        End If 
       Catch exception As COMException 
        EventLog.write(exception) 
        MessageBox.Show("Could not open email. Please start Outlook and try again.", "Opening Email", MessageBoxButtons.OK, MessageBoxIcon.Information) 
       End Try 
       GridControlInbox.RefreshDataSource() 
      End If 
     End If 
    End Sub 

的重新連接代碼...

Private Sub connectToOutlook() 
    Try 
     m_outlookApplication = New Microsoft.Office.Interop.Outlook.Application 
     m_nameSpace = m_outlookApplication.GetNamespace("MAPI") 
     'start Outlook 
     Dim connectionMode = m_nameSpace.ExchangeConnectionMode 
     m_nameSpace.Logon(Missing.Value, Missing.Value, False, True) 
     'get the name of user 
     m_name = m_outlookApplication.Session.CurrentUser.Name 
     m_outlookInstalled = True 
    Catch exception As System.Exception 
     If Not exception.Message.IndexOf("Class not registered") = -1 Then 
      'Outlook is not installed 
      m_outlookInstalled = False 
      EventLog.write(exception) 
     Else 
      EventLog.write(exception) 
     End If 
    End Try 
End Sub 
相關問題