代码之家  ›  专栏  ›  技术社区  ›  Chris

打开电子邮件时Outlook Interop“RPC服务器不可用”

  •  2
  • Chris  · 技术社区  · 13 年前

    使用Outlook Interop,我创建了一个小应用程序,连接到我的Outlook收件箱,收集30封电子邮件,然后将它们显示在网格中。当您双击网格中的电子邮件时,它将在Outlook中打开该电子邮件。

    在应用程序中: -打开一封电子邮件,将其最小化。然后打开另一封,它会很好地打开。 -打开一封电子邮件,关闭它。然后打开另一封,你会得到一个“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
    
    1 回复  |  直到 13 年前
        1
  •  4
  •   Chris    12 年前

    经过几个小时的调查,当一封邮件被关闭时,它会随之关闭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
    
    推荐文章