【问题标题】:Outlook mail automation - error only when Outlook is already runningOutlook 邮件自动化 - 仅在 Outlook 已运行时出错
【发布时间】:2014-04-22 16:21:48
【问题描述】:

当我单击位于 WinForm 中的发送按钮时,我编写了一个子程序以通过 Outlook 发送电子邮件。如果 Outlook 关闭,我的代码可以正常工作。当 Outlook 已经打开时,我不断收到 OutMail = oApp.CreateItem(0) 的错误

OfficeAutomation.exe 中出现“System.InvalidCastException”类型的未处理异常

附加信息:无法将“Microsoft.Office.Interop.Outlook.ApplicationClass”类型的 COM 对象转换为接口类型“Microsoft.Office.Interop.Outlook._Application”。 此操作失败,因为 IID 为“{00063001-0000-0000-C000-000000000046}”的接口的 COM 组件上的 QueryInterface 调用因以下错误而失败:RPC 服务器不可用。 (来自 HRESULT 的异常:0x800706BA)。

Private Sub EmailOut_Click(sender As Object, e As EventArgs) Handles EmailOut.Click
    Dim oApp As Outlook.Application = Nothing

    ' Check whether there is an Outlook process running.
    Dim outlookRunning As Integer = Process.GetProcessesByName("OUTLOOK").Length
    If outlookRunning > 0 Then
        ' If Outlook is running, use the GetActiveObject method to obtain the 
        ' process and cast it to an Application object.
        Try
            oApp = TryCast(System.Runtime.InteropServices.Marshal.GetActiveObject("Outlook.Application"),  _
                Outlook.Application)
        Catch generatedExceptionName As System.Exception
            oApp = TryCast(Activator.CreateInstance(Type.GetTypeFromProgID("Outlook.Application")),  _
                Outlook.Application)
        Finally
            ' Kill Outlook and then restart it as a last resort.
            Dim workers As Process() = Process.GetProcessesByName("OUTLOOK")
            For Each worker As Process In workers
                worker.Kill()
                worker.WaitForExit()
                worker.Dispose()
            Next
        End Try
    Else
        ' If Outlook is not running, create a new instance of Outlook.
        oApp = New Outlook.Application()
        Dim ns As Outlook.NameSpace = oApp.GetNamespace("MAPI")
        Try
            ' try to use default profile and do not open a window
            ' if login fails, then we must pop up a window and let the 
            ' user choose a profile to allow access
            ns.Logon("", "", False, System.Reflection.Missing.Value)
        Catch generatedExceptionName As System.Exception
            ' use default profile and pop up a window
            ns.Logon("", "", True, True)
        End Try
        ns = Nothing
    End If
    Dim OutMail As Outlook.MailItem

    OutMail = oApp.CreateItem(0)

    With OutMail
        If Not String.IsNullOrEmpty(EmailAdr.Text) Then
            .To = EmailAdr.Text
        Else
            MessageBox.Show("Please enter an e-mail address", "Missing Recipient", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Exit Sub
        End If
        If Not String.IsNullOrEmpty(CcAdr.Text) Then
            .CC = CcAdr.Text
        End If
        .Subject = OutSubject.Text
        .Body = OutTextBox.Text
        System.Threading.Thread.Sleep(5000)
        .Send()
    End With
    System.Threading.Thread.Sleep(5000)
    oApp = Nothing
    Microsoft.VisualBasic.Shell("taskkill /F /IM outlook.exe", Microsoft.VisualBasic.vbHide)
End Sub

【问题讨论】:

    标签: vb.net winforms email outlook


    【解决方案1】:

    不要使用 GetActiveObject - Outlook 是一个单例,CreateInstance 将返回一个指向已运行实例的指针。

    【讨论】:

    • 我尝试将 If running try 行替换为:oApp = TryCast(Activator.CreateInstance(Type.GetTypeFromProgID("Outlook.Application")), Outlook.Application) 没有运气。 Activator.CreateInstance 上的 MSDN 页面在处理进程时含糊不清。能详细点吗?
    • 你得到同样的错误吗?您的应用程序和 Outlook 是否在相同的安全上下文中运行?任一应用程序是否以管理员身份运行?您的应用是从 Windows 资源管理器还是 VS 调试器运行的?
    • 我通过查看这些细节解决了这个问题。最终修改了我的代码以使其更简单。感谢您的帮助。
    【解决方案2】:

    您应该尝试创建一个新的 Outlook 实例,无论它是否正在运行。我认为没有必要尝试抓住正在运行的实例(如果有可能,但似乎不可能)。

    编辑:不过,我肯定会接受 Dmitry 的话。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 2015-05-10
      • 1970-01-01
      • 2021-07-02
      相关资源
      最近更新 更多