Search code examples
delphioutlookole

Robustly sending emails through Outlook and OLE


I'm using OLE to send email through Outlook. The code I am using is:

procedure SendOutlookMail;
const
  olMailItem = 0;
var
  OKToUse: boolean;
  Outlook: OleVariant;
  vMailItem: variant;
begin
  OKToUse := false;
  try
    Outlook := GetActiveOleObject('Outlook.Application');
    OKToUse := true;
  except
    try
      Outlook := CreateOleObject('Outlook.Application');
      OKToUse := true;
    except
      on e: exception do begin
        ShowMessage(e.Message);
      end;
    end;
  end;

  if VarIsType(Outlook, varDispatch) then
    ShowMessage('Outlook is varDispatch')
  else
    ShowMessage('Outlook is ***NOT*** varDispatch');

  if OKToUse then begin
    vMailItem := Outlook.CreateItem(olMailItem);
    vMailItem.Recipients.Add('mike@example.com');
    vMailItem.Subject := 'What a wonderful test email';
    vMailItem.Body := 'This is a test --> how amazing';
    vMailItem.Send;
  end;

  VarClear(Outlook);
end;

Which has been unashamedly nicked from a couple of different SO questions - thanks to all.

The problem I have with the code is when Outlook is installed on the PC, but is closed. When Outlook is open I get a message box saying "Outlook is varDispatch" and a mail message is send and received. When Outlook is closed I get the same message box "Outlook is varDispatch", but then "An error occurred in the application" and my application closes abruptly.

So two questions:

1) How do I detect if Outlook is running? The fact that OKToUse gets set to true seems to not be the right way.

2) How do I start Outlook if it isn't running and close it after an email has been sent?

I'm using Delphi 10.1 Berlin and trying to connect to Outlook 2007.


Solution

  • Add the following before calling CreateItem

    vNS := Outlook.GetNamespace('MAPI');
    vNS.Logon;