emailing from application lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- draggon · 2018-10-02 12:46 I am trying to send and e-mail from applcation. I found piece of code in one forum: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure send_email(r, s, b: String); const  olMailItem = 0;  olByValue = 1; var  OutlookApp, MailItem: OLEVariant; begin  try    begin      OutlookApp:= GetActiveOleObject('Outlook.Application');    end;  except    begin      OutlookApp:= CreateOleObject('Outlook.Application');    end;  end;   try    MailItem:= OutlookApp.CreateItem(olMailItem);    MailItem.Recipients:= 'my email address';  // or r    MailItem.Subject:= s;    MailItem.Body:= b;    MailItem.Send;  finally    //myAttachments:= VarNull;    OutlookApp:= VarNull;  end;end; procedure is called form another unit: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i send_email('e-mail adress', 'subject', 'body'); Message Exception of class 'EOleException' occurs, Property is read- only. If r variable is entered inside the procedure another message occurs: piece of assembler code. Thank you ---------------------------------------------------------------------- Remy Lebeau · 2018-10-02 18:14 Quote from: draggon on October 02, 2018, 02:46:35 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     MailItem:= OutlookApp.CreateItem(olMailItem);    MailItem.Recipients:= 'my email address';  // or r Message Exception of class 'EOleException' occurs, Property is read- only. Indeed, the Recipients property is read-only (its documentation even says so).  The Recipients is a collection, you need to call its Add() method to add individual entries to the collection, eg: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i MailItem.Recipients.Add('my email address');  // or r ---------------------------------------------------------------------- Thaddy · 2018-10-02 18:58 You may have added the solution is not a cross platform one, Remy. ---------------------------------------------------------------------- Remy Lebeau · 2018-10-02 19:19 Quote from: Thaddy on October 02, 2018, 08:58:50 pmYou may have added the solution is not a cross platform one, Remy. Why does it matter?  The OP is using ActiveX/COM, which is a Windows- specific technology, so the code is platform-specific anyway, so the solution will be, too. ---------------------------------------------------------------------- draggon · 2018-10-03 07:54 Thanks Remy, Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i MailItem.Recipients.Add('my email address'); works. There is one issue - when the procedure is called like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i send_email('e-mail adress', 'subject', 'body'); there is runtime error with some assembler code window displayed. Data from procedure call is OK as checked in ShowMessage: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i rocedure send_email(r, s, b: String); const  olMailItem = 0;  olByValue = 1; var  OutlookApp, MailItem: OLEVariant; begin  try    begin      OutlookApp:= GetActiveOleObject('Outlook.Application');    end;  except    begin      OutlookApp:= CreateOleObject('Outlook.Application');    end;  end;   try    MailItem:= OutlookApp.CreateItem(olMailItem);    ShowMessage(r + s + b);                                     //data OK    MailItem.Recipients.Add(r);    MailItem.Subject:= s;    MailItem.Body:= b;    MailItem.Send;  finally    //myAttachments:= VarNull;    OutlookApp:= VarNull;  end;end;   No runtime error and successfull e-mail sending occurs if recipient, subject, body strings are hard copied in procedure send_email, therefore data from outside are ignored. Thank you ---------------------------------------------------------------------- Remy Lebeau · 2018-10-03 17:39 Quote from: draggon on October 03, 2018, 09:54:29 amthere is runtime error with some assembler code window displayed. I can't answer that, as I don't use FreePascal myself.  You will just have to debug the code for yourself and find out why it is crashing.  However, I will say that COM expects BSTR strings, not Pascal strings, so try casting your strings to WideString (a wrapper for BSTR) when passing them to COM, eg: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure send_email(r, s, b: String);const  olMailItem = 0;  olByValue = 1;var  OutlookApp, MailItem: OLEVariant;begin  try    OutlookApp := GetActiveOleObject('Outlook.Application');  except    OutlookApp := CreateOleObject('Outlook.Application');  end;   try    MailItem := OutlookApp.CreateItem(olMailItem);    try      MailItem.Recipients.Add(WideString(r));      MailItem.Subject := WideString(s);      MailItem.Body := WideString(b);      MailItem.Send;    finally      MailItem := VarNull;    end;  finally  OutlookApp := VarNull;  end;end; On a side note, you do not need to explicitly set OLEVariant to null when you are done using it.  It is managed by the compiler and will be cleaned up automatically when it goes out of scope, eg: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure send_email(r, s, b: String);const  olMailItem = 0;  olByValue = 1;var  OutlookApp, MailItem: OLEVariant;begin  try    OutlookApp := GetActiveOleObject('Outlook.Application');  except    OutlookApp := CreateOleObject('Outlook.Application');  end;   MailItem := OutlookApp.CreateItem(olMailItem);  MailItem.Recipients.Add(WideString(r));  MailItem.Subject := WideString(s);  MailItem.Body := WideString(b);  MailItem.Send;end; ---------------------------------------------------------------------- Trenatos · 2018-10-03 21:12 Personally I use X-Mailer - https://github.com/MFernstrom/xmailer Unless you need to use Outlook specifically, I'd recommend that, and it's cross platform afaik. ---------------------------------------------------------------------- draggon · 2018-10-18 09:26 Hi, I am back with the same topic. e-mailing works, what does not work is how to treat the situation when Outlook is not running. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure send_email(r, s, b: ShortString); const  olMailItem = 0;  olByValue = 1; var  OutlookApp, MailItem: OLEVariant; begin  try      OutlookApp:= GetActiveOleObject('Outlook.Application');  except       //OutlookApp:= CreateOleObject('Outlook.Application');      // here I just want to use ShowMessage with information that Outlook is not available   end;   try    MailItem:= OutlookApp.CreateItem(olMailItem);    MailItem.Recipients.Add(WideString(r));    MailItem.Subject:= WideString(s);    MailItem.Body:= WideString(b);    MailItem.Send;  finally    OutlookApp:= VarNull;  end;end; Runtime error is generated instead of code execution in except section. Thanks ---------------------------------------------------------------------- minesadorada · 2018-10-18 17:03 Quote from: Trenatos on October 03, 2018, 11:12:05 pmPersonally I use X-Mailer - https://github.com/MFernstrom/xmailer Unless you need to use Outlook specifically, I'd recommend that, and it's cross platform afaik. Thanks for that link.  X-Mailer is simple to configure and works really well (tested with Gmail account) ---------------------------------------------------------------------- draggon · 2018-10-19 06:22 Unfortunately I need to use Outlook specifically since this is company choice. ---------------------------------------------------------------------- Remy Lebeau · 2018-10-22 21:31 Quote from: draggon on October 18, 2018, 11:26:27 amRuntime error is generated instead of code execution in except section. What kind of runtime error exactly? GetActiveOleObject() should be raising an exception that the 'except' can catch. ---------------------------------------------------------------------- draggon · 2018-10-24 10:42 Hi, the message is Exception of class EOleSySError, Operation unavailable. At the same time appears window for loggin to Outlook. Thank you ---------------------------------------------------------------------- Thaddy · 2018-10-24 10:53 Yeah, right, of course you or your application needs to be logged in to Outlook.... You can also do that is code. ---------------------------------------------------------------------- draggon · 2018-10-24 11:07 When I am logged in Outlook it is OK. I want to prevent crashing application when user forgets log to Outlook just give him info to do it instead. ---------------------------------------------------------------------- draggon · 2018-10-24 11:15 Thanks for support, I found on another forum that this happens only when running from IDE. Running compiled application is fine. ---------------------------------------------------------------------- Remy Lebeau · 2018-10-24 19:26 Quote from: draggon on October 24, 2018, 01:15:57 pmThanks for support, I found on another forum that this happens only when running from IDE. Running compiled application is fine. Makes sense, as the debugger displays raised exceptions before the app even sees them.  Just continue execution and the debugger will pass the exception to the app for normal handling.