Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: sending emails


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 17 - Last Post: Aug 22, 2017 1:44 AM Last Post By: David Ayre Threads: [ Previous | Next ]
David Ayre

Posts: 34
Registered: 10/11/00
sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 15, 2017 2:42 AM
Probably a question for Remy.
I use XE2 and idSMTP which works fine on Win XE but seems to stick on Win 7.
Any ideas?

David
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 15, 2017 9:25 AM   in response to: David Ayre in response to: David Ayre
David Ayre wrote:

Probably a question for Remy.
I use XE2 and idSMTP which works fine on Win XE but seems to stick on
Win 7. Any ideas?

TIdSMTP works the same on all Windows versions. Need more details
about your setup before a diagnosis can be made. What does your code
look like? What property values are you assigning? What email
provider are you using? What connection settings does it require?

--
Remy Lebeau (TeamB)
David Ayre

Posts: 34
Registered: 10/11/00
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 15, 2017 11:21 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
David Ayre wrote:

Probably a question for Remy.
I use XE2 and idSMTP which works fine on Win XE but seems to stick on
Win 7. Any ideas?

TIdSMTP works the same on all Windows versions. Need more details
about your setup before a diagnosis can be made. What does your code
look like? What property values are you assigning? What email
provider are you using? What connection settings does it require?

--
Remy Lebeau (TeamB)

I think it might be my virus protection or firewall.
These things are getting to the stage where they
won't let anything work.
I'll get back to you if I have no luck.

Cheers,

David
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 15, 2017 11:40 AM   in response to: David Ayre in response to: David Ayre
David Ayre wrote:

I think it might be my virus protection or firewall.

That is very unlikely, given how popular email is.

These things are getting to the stage where they
won't let anything work.

They usually don't block outgoing connections by default, especially on
standardized ports like the SMTP port. So, unless you have email
scanning enabled and are sending an email that looks malicious, they
are likely not blocking you. More likely, you are simply not
configuring TIdSMTP correctly to communicate with your SMTP server.

--
Remy Lebeau (TeamB)
David Ayre

Posts: 34
Registered: 10/11/00
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 17, 2017 3:04 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
David Ayre wrote:

I think it might be my virus protection or firewall.

That is very unlikely, given how popular email is.

These things are getting to the stage where they
won't let anything work.

They usually don't block outgoing connections by default, especially on
standardized ports like the SMTP port. So, unless you have email
scanning enabled and are sending an email that looks malicious, they
are likely not blocking you. More likely, you are simply not
configuring TIdSMTP correctly to communicate with your SMTP server.

--
Remy Lebeau (TeamB)

Hello Remy,
I think I have found the cause of the problem but can't find a way of correcting it.
The email has an attachment but seems unable to access the file which is
in the c:\email folder. I get a message that it is unable to access this file.

David
David Ayre

Posts: 34
Registered: 10/11/00
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 17, 2017 8:23 AM   in response to: David Ayre in response to: David Ayre
David Ayre wrote:
Remy Lebeau (TeamB) wrote:
David Ayre wrote:

I think it might be my virus protection or firewall.

That is very unlikely, given how popular email is.

These things are getting to the stage where they
won't let anything work.

They usually don't block outgoing connections by default, especially on
standardized ports like the SMTP port. So, unless you have email
scanning enabled and are sending an email that looks malicious, they
are likely not blocking you. More likely, you are simply not
configuring TIdSMTP correctly to communicate with your SMTP server.

--
Remy Lebeau (TeamB)

Hello Remy,
I think I have found the cause of the problem but can't find a way of correcting it.
The email has an attachment but seems unable to access the file which is
in the c:\email folder. I get a message that it is unable to access this file.

David
I've tracked it down to the routine before the TIdSMTP is called.
I rename the file c:\email\output.pdf but before I do this I check that it exists
using if(FileExists(acFileName)) where acFileName = c:\email\output.pdf.
The file is there but it returns false.

David
Antonio Estevez

Posts: 665
Registered: 4/12/00
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 17, 2017 10:23 AM   in response to: David Ayre in response to: David Ayre
El 17/08/2017 a las 17:23, David Ayre escribió:
I've tracked it down to the routine before the TIdSMTP is called.
I rename the file c:\email\output.pdf but before I do this I check that it exists
using if(FileExists(acFileName)) where acFileName = c:\email\output.pdf.
The file is there but it returns false.

I guess you know that the backslash should be escaped in C++ literal strings:

acFileName= "c:\\email\\output.pdf";
David Ayre

Posts: 34
Registered: 10/11/00
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 17, 2017 10:28 AM   in response to: Antonio Estevez in response to: Antonio Estevez
Antonio Estevez wrote:
El 17/08/2017 a las 17:23, David Ayre escribió:
I've tracked it down to the routine before the TIdSMTP is called.
I rename the file c:\email\output.pdf but before I do this I check that it exists
using if(FileExists(acFileName)) where acFileName = c:\email\output.pdf.
The file is there but it returns false.

I guess you know that the backslash should be escaped in C++ literal strings:

acFileName= "c:\\email\\output.pdf";

Yes, the filename has been entered correctly. This works fine on an XP computer
but returns false on the Win 7 computer even though the file exists.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 17, 2017 10:20 AM   in response to: David Ayre in response to: David Ayre
David Ayre wrote:

I think I have found the cause of the problem but can't find a way of
correcting it. The email has an attachment but seems unable to
access the file

That would not cause a hang in TIdSMTP. That would cause an exception
to be thrown by TIdMessage when it tries to open the file while
encoding the email.

--
Remy Lebeau (TeamB)
David Ayre

Posts: 34
Registered: 10/11/00
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 17, 2017 10:33 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
David Ayre wrote:

I think I have found the cause of the problem but can't find a way of
correcting it. The email has an attachment but seems unable to
access the file

That would not cause a hang in TIdSMTP. That would cause an exception
to be thrown by TIdMessage when it tries to open the file while
encoding the email.

--
Remy Lebeau (TeamB)

It hangs in TidSMTP because it has been passed an attachment filename
that doesn't exist. This is because FileExists(Filename) returns false when it should
return true.

David
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 17, 2017 10:43 AM   in response to: David Ayre in response to: David Ayre
David Ayre wrote:

It hangs in TidSMTP because it has been passed an attachment filename
that doesn't exist.

Again, that CANNOT cause a hang in TIdSMTP. TIdAttachmentFile doesn't
use FileExists(), it simply opens the filename as-is, and throws an
exception if the file cannot be opened for any reason. Any exception
that is thrown would simply abort the current SMTP operation. You
would then to catch the exception so you can Disconnect() the SMTP
connection.

--
Remy Lebeau (TeamB)
David Ayre

Posts: 34
Registered: 10/11/00
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 17, 2017 11:34 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
David Ayre wrote:

It hangs in TidSMTP because it has been passed an attachment filename
that doesn't exist.

Again, that CANNOT cause a hang in TIdSMTP. TIdAttachmentFile doesn't
use FileExists(), it simply opens the filename as-is, and throws an
exception if the file cannot be opened for any reason. Any exception
that is thrown would simply abort the current SMTP operation. You
would then to catch the exception so you can Disconnect() the SMTP
connection.

--
Remy Lebeau (TeamB)

Here is my code:-

data
void __fastcall TFormEmail::SendEmail(TObject *Sender)
{
//Send Email
char acLine[16];
IdSMTP1->Host = Edit1->Text;

TIniFile *Ini = new TIniFile(".
paths.ini");
IdSMTP1->Port = Ini->ReadInteger("EMAIL", "PORT", 25);
delete Ini;

if (CheckBox1->Checked)
{
IdSMTP1->AuthType = satDefault;
IdSMTP1->Username = Edit6->Text;
IdSMTP1->Password = Edit5->Text;
}
else IdSMTP1->AuthType = satNone;

IdMessage1->Clear();
IdMessage1->From->Address = Edit2->Text;
IdMessage1->Recipients->EMailAddresses = Edit3->Text;
IdMessage1->Subject = acHeader;
IdMessage1->From->Name = Edit4->Text;

TIdMessageBuilderHtml *MsgBuilder = new TIdMessageBuilderHtml();
try
{
MsgBuilder->PlainText->Text = acBody;

char acHtml[5500];
sprintf(acHtml,"<html>%s</html>", acBody);
ConvertToHTML(Sender,acHtml);// converts to HTML format
MsgBuilder->Html->Text = acHtml;

MsgBuilder->Attachments->Add(acAttachment);
MsgBuilder->FillMessage(IdMessage1);
}
__finally
{
delete MsgBuilder;
}

try
{
IdSMTP1->ConnectTimeout = 10000; //adjust as required
IdSMTP1->Connect();
try {
IdSMTP1->Send(IdMessage1);
}
__finally {
IdSMTP1->Disconnect();
}
}
catch(...)
{
Memo1->Lines->Add(String().sprintf(_D("%hs - Not sent"), acAttachment));
strcpy(acHeader,"NOT");
}
IdMessage1->ClearBody();
if(strcmp(acHeader,"NOT"))
{
Memo1->Lines->Add(String().sprintf(_D("%hs - sent"), acAttachment));
strcpy(acHeader,"OK");
}
}
data
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 17, 2017 12:34 PM   in response to: David Ayre in response to: David Ayre
David Ayre wrote:

Here is my code:-

You dd not indicate where in that code the problem is actually occuring.

char acHtml[5500];
sprintf(acHtml,"<html>%s</html>", acBody);

I would use AnsiString::sprintf() instead:

AnsiString acHtml;
acHtml.sprintf("<html>%s</html>", acBody);


Or better, System::String:

String acHtml;
acHtml.sprintf(_D("<html>%hs</html>"), acBody);


IdSMTP1->Connect();

You are not specifying anything for the UseTLS property. Does the
server require SSL/TLS?

catch(...)

You should be using 'catch (const Exception &)' instead.

--
Remy Lebeau (TeamB)
David Ayre

Posts: 34
Registered: 10/11/00
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 18, 2017 1:49 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
David Ayre wrote:

Here is my code:-

You dd not indicate where in that code the problem is actually occuring.

char acHtml[5500];
sprintf(acHtml,"<html>%s</html>", acBody);

I would use AnsiString::sprintf() instead:

AnsiString acHtml;
acHtml.sprintf("<html>%s</html>", acBody);


Or better, System::String:

String acHtml;
acHtml.sprintf(_D("<html>%hs</html>"), acBody);


IdSMTP1->Connect();

You are not specifying anything for the UseTLS property. Does the
server require SSL/TLS?

catch(...)

You should be using 'catch (const Exception &)' instead.

--
Remy Lebeau (TeamB)

I don't know whether the server requires SSL or TLS but it is
quite happy when emails are sent from Win XP.
I take your point about all the other recommendations.
It gets to IdSMTP1->Connect(); and then sticks. I will change
the catch statement as you suggested, but the problem seems
to arise before the IdSMTP1 is called. I have to rename a pdf
file C:\email\output.pdf before sending the details to the IdSMTP1 unit.
I check to see if the file is present using FileExists(FilePath) and
this seems to return false even if the file is present. This only
happens on my Win 7 computer but is OK on the Win XP computer.

Thanks for you patience.

David
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 18, 2017 12:51 PM   in response to: David Ayre in response to: David Ayre
David Ayre wrote:

I don't know whether the server requires SSL or TLS

You need to know that. It affects how you connect and communicate with
the server. If you don't use the correct SSL/TLS setup, that can
easily cause hangs, if not exceptions.

but it is quite happy when emails are sent from Win XP.

The OS plays no part in the SMTP protocol at all. The presence of XP
is irrelevant. What is relevant is which SMTP client you use when the
sending is successful, and how that client is configured to communicate
with the SMTP server.

It gets to IdSMTP1->Connect(); and then sticks.

That means you are not configuring TIdSMTP correctly.

The most common culprit is if you connect to a SMTP port that requires
an SSL/TLS handshake immediately upon opening the socket connection,
before the SMTP greeting can then be sent (encrypted) from the server
to the client, but you don't have the TIdSMTP.UseTLS property set to
utUseImplictTLS. In that scenario, Connect() would not send the
handshake and end up waiting for a greeting that never arrives. To
account for this possibility, you woould have to set the
TIdSMTP.ReadTimeout property to a non-infinite timeout (Indy uses
infinite timeouts by default).

Unless otherwise stated by your SMTP provider, you should be setting
the UseTLS property as follows:

- port 25: use utNoTLSSupport or utUseEmplicitTLS

- port 465: use utUseImplicitTLS

- port 587: use utUseExplicitTLS

the problem seems to arise before the IdSMTP1 is called. I have to
rename a pdf file C:\email\output.pdf before sending the details to
the IdSMTP1 unit.

I check to see if the file is present using FileExists(FilePath) and
this seems to return false even if the file is present. This only
happens on my Win 7 computer but is OK on the Win XP computer.

I guarantee you that has ABSOLUTELY NOTHING to do with
TIdSMTP.Connect() freezing, since the PDF file is not even being
touched by TIdMessage until TIdSMTP.Send() is called. If
TIdSMTP.Connect() freees, you would not get that far.

--
Remy Lebeau (TeamB)
David Ayre

Posts: 34
Registered: 10/11/00
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 19, 2017 1:53 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
I check to see if the file is present using FileExists(FilePath) and
this seems to return false even if the file is present. This only
happens on my Win 7 computer but is OK on the Win XP computer.

I guarantee you that has ABSOLUTELY NOTHING to do with
TIdSMTP.Connect() freezing, since the PDF file is not even being
touched by TIdMessage until TIdSMTP.Send() is called. If
TIdSMTP.Connect() freees, you would not get that far.

--
Remy Lebeau (TeamB)

I have stepped through more carefully and it actually connects OK
Then goes to TIdSMTP.Send() and I stepped through this to the point
where it tries to load the attachment, where it sticks and displays a message
saying that the attachment file doesn't exist. But it does,
so it must be locked, but I can't find any way of making it accessible.
When I run it on the Win XP machine (everything the same) it is OK and
the file is accessible.

David
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 21, 2017 11:20 AM   in response to: David Ayre in response to: David Ayre
David Ayre wrote:

I have stepped through more carefully and it actually connects OK
Then goes to TIdSMTP.Send() and I stepped through this to the point
where it tries to load the attachment, where it sticks and displays a
message saying that the attachment file doesn't exist.

What is the EXACT error message? Indy does not check for existence,
it checks for accessibility. Are you getting an "Access Denied"
error, or an actual "File not found" error?

The only way a popup message could be displayed is if an exception is
being raised (which it should be).

If you are running your app inside the debugger, the debugger will
display the exception message to you (unless you tell it not to). Just
press F9 to continue running, and the exception will be passed back to
the app for normal handling.

If you are not running your app inside the debugger, then the exception
message will only display if it reaches an exception handler that
displays the exception. For instance, if the exception happens inside
a VCL message-based event handler, like a button click, then the
message handler will display an exception that escapes the event
handler.

Either way, this is not a FREEZE. The exception jumps out of Indy
right into your own code. You are supposed to react to the exception
so you can Disconnect() the SMTP connection, at least, eg:

IdSMTP1->Connect();
try
{
    IdSMTP1->Send(IdMessage1);
}
__finally
{
    IdSMTP1->Disconnect();
}


Which you can wrap in your own exception handler so the VCL does not
display a default message popu:

try
{
    IdSMTP1->Connect();
    try
    {
        IdSMTP1->Send(IdMessage1);
    }
    __finally
    {
        IdSMTP1->Disconnect();
    }
}
catch (const Exception &e)
{
    // something went wrong, do something...
}


But again, that is not a FREEZE. THERE IS NO POSSIBLE WAY A FREEZE CAN
HAPPEN IN THIS SITUATION, unless you are doing something yourself in
your own code to cause a freeze.

But it does, so it must be locked, but I can't find any way of making
it accessible.

By default, TIdAttachmentFile attempts to open the file with
write-sharing disabled, to ensure nobody can write to the file while it
is being encoded. If someone else has the file open for writing, that
open will fail.

An alternative option would be to derive a new class from
TIdAttachmentFile and override its virtual OpenLoadStream() method to
open the file with less restrictive access rights (such as by using
TIdReadFileNonExclusiveStream instead of TIdReadFileExclusiveStream).

When I run it on the Win XP machine (everything the
same) it is OK and the file is accessible.

This is not an OS issue, it is an access/permissions issue.

--
Remy Lebeau (TeamB)
David Ayre

Posts: 34
Registered: 10/11/00
Re: sending emails  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Aug 22, 2017 1:44 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
David Ayre wrote:

I have stepped through more carefully and it actually connects OK
Then goes to TIdSMTP.Send() and I stepped through this to the point
where it tries to load the attachment, where it sticks and displays a
message saying that the attachment file doesn't exist.

What is the EXACT error message? Indy does not check for existence,
it checks for accessibility. Are you getting an "Access Denied"
error, or an actual "File not found" error?

The only way a popup message could be displayed is if an exception is
being raised (which it should be).

If you are running your app inside the debugger, the debugger will
display the exception message to you (unless you tell it not to). Just
press F9 to continue running, and the exception will be passed back to
the app for normal handling.

If you are not running your app inside the debugger, then the exception
message will only display if it reaches an exception handler that
displays the exception. For instance, if the exception happens inside
a VCL message-based event handler, like a button click, then the
message handler will display an exception that escapes the event
handler.

Either way, this is not a FREEZE. The exception jumps out of Indy
right into your own code. You are supposed to react to the exception
so you can Disconnect() the SMTP connection, at least, eg:

IdSMTP1->Connect();
try
{
    IdSMTP1->Send(IdMessage1);
}
__finally
{
    IdSMTP1->Disconnect();
}


Which you can wrap in your own exception handler so the VCL does not
display a default message popu:

try
{
    IdSMTP1->Connect();
    try
    {
        IdSMTP1->Send(IdMessage1);
    }
    __finally
    {
        IdSMTP1->Disconnect();
    }
}
catch (const Exception &e)
{
    // something went wrong, do something...
}


But again, that is not a FREEZE. THERE IS NO POSSIBLE WAY A FREEZE CAN
HAPPEN IN THIS SITUATION, unless you are doing something yourself in
your own code to cause a freeze.

Thanks for your help Remy. I have now discovered that the
file was saved as output.pdf.pdf instead of output.pdf, so
couldn't be found. However, all the extra info you have
given me will be extremely useful.

Cheers,

David
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02