2014-04-22 2 views
0

WinForm에있는 보내기 단추를 클릭하면 Outlook을 통해 전자 메일을 보낼 수있는 하위 프로그램을 작성했습니다. Outlook이 닫히면 코드가 올바르게 작동합니다. Outlook을 이미 열 때, 나는 'System.InvalidCastException'형식의 처리되지 않은 예외가 OfficeAutomation.exe에서 발생 OutMail = oApp.CreateItem (0)Outlook 메일 자동화 - Outlook이 이미 실행 중일 때만 오류가 발생합니다.

에 오류를 받고

추가 정보를 보관 : COM을 캐스팅 할 수 없습니다 'Microsoft.Office.Interop.Outlook.Application'인터페이스 유형에 'Microsoft.Office.Interop.Outlook.ApplicationClass'유형의 개체입니다. 다음 오류로 인해 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 

답변

1

GetActiveObject를 사용하지 마십시오. Outlook은 싱글 톤이며, CreateInstance는 이미 실행중인 인스턴스에 대한 포인터를 반환합니다.

+0

줄 바꾸기 : oApp = TryCast (Activator.CreateInstance (Type.GetTypeFromProgID ("Outlook.Application")), Outlook.Application) 행운을 함께 시도해보십시오. Activator.CreateInstance의 MSDN 페이지는 프로세스를 처리 할 때 막연합니다. 제발 좀 더 자세히 설명해 주실 수 있습니까? – mschmidt9026

+0

같은 오류가 발생합니까? 앱과 Outlook이 모두 동일한 보안 컨텍스트에서 실행되고 있습니까? 어느 앱이 관리자로 실행 중입니까? 귀하의 응용 프로그램이 Windows 탐색기 또는 VS 디버거에서 실행되고 있습니까? –

+0

나는 이러한 세부 사항을 조사하면서이 문제를 해결했다. 조금 더 간단하게 코드 수정 작업을 마쳤습니다. 도와 줘서 고마워. – mschmidt9026

0

실행 중인지 여부에 관계없이 Outlook의 새 인스턴스를 만들어야합니다. 나는 실행중인 인스턴스를 잡으려고 할 필요가 없다고 생각합니다. (가능하다면, 그렇지 않은 것처럼 보입니다.)

편집 : 나는 드미트리의 말을 내 마음대로 취할 것입니다.

관련 문제