PDA

Ver la Versión Completa : Enviar correos con adjuntos (Indy 10)


Angel.Matilla
09-05-2016, 12:38:05
Recuerdo a todos que uso BCB 6 e Indy 10.6.2.0

Sigo a vueltas con mis problemas con Indy 10. Si bien el problema que tenía de conexión para poder enviar los correos ya los he resuelto (creo) ahora tengo problemas a la hora de adjuntar ficheros al mensaje que creo, y el problema me lo da a la hora de compilar. Estoy tratando de usar este código de cunado utilizaba Indy 9:
Correo->Subject = "Socio núm. " + FormatFloat("###,##0", Query->FieldByName("Socio")->AsInteger) + " - " + fCarSoc->QRLabel5->Caption;
Correo->ClearBody();
Correo->MessageParts->Clear();
Correo->Recipients->Clear();
Correo->CCList->Clear();
Correo->BccList->Clear();

Correo->Recipients->Add();
Correo->Recipients->EMailAddresses = Query->FieldByName("Usuario")->AsString.Trim() + "@internautas.org";
if (!Query->FieldByName("Email")->AsString.IsEmpty())
{
Correo->CCList->Add();
Correo->CCList->EMailAddresses = Query->FieldByName("Email")->AsString.Trim();
}
Correo->BccList->Add();
Correo->BccList->EMailAddresses = Correo->From->Address;

Correo->Body->Text = "El fichero adjunto " + ExtractFileName(cPdfFile) + " contiene información importante sobre tu cuenta como miembro de la " + cInstala[0] + ". Por "
"favor: Leela con atención.\r\n\r\nAtentamente,\r\n\r\n\t" + cInstala[1] + "\r\n\tAdministración de Socios\r\n\t" + cInstala[0] +
"\r\n\thttp://www.internautas.org";
Correo->MessageParts->Add();
TIdAttachment(Correo->MessageParts, cPdfFile);Todos los campos y variables que se usan están definidos.

He estado mirando por foros y páginas y, al margen de que casi todo lo que he encontrado era para Delphi, no logro que me compile, ni bien ni mal:
Si lo pongo tal cual TIdAttachment(... me da un error E2352 Cannot create instance of abstract class 'TIdAttachment'.
Si adapto el código Delphi que he encontrado y uso TIdAttachment->Create(..., entonces me da un error E2108 Improper use of typedef 'TIdAttachment'.
Si trato de crear un objeto Adjunto así:TIdAttachment *Adjunto = new TIdAttachment(Correo)
Adjunto->Add(Correo->MessageParts, cPdfFile);
la creación de Adjunto no me da error pero entonces me da dos en la segunda línea: E2352 Cannot create instance of abstract class 'TIdAttachment' y E2353 Class 'TIdAttachment' is abstract because of 'TIdAttachment.OpenLoadStream()= 0'.
¿Puede alguien ayudarme o darme una pista?

Neftali [Germán.Estévez]
09-05-2016, 13:30:23
Yo en Delphi (Delphi7+Indy10) hago directamente esto (sin el Add); A ver si te sirve:


var
Mennsaje: TIdMessage;
...
begin
..

// recorer la lista y añadir los ficheros...
for i := 0 to (AListaAdjuntos.Count - 1) do begin
// si existe, lo añadimos...
if FileExists(AListaAdjuntos[i]) then begin
TIdAttachmentFile.Create(Mensaje.MessageParts, AListaAdjuntos[i]);
end;
end;

Angel.Matilla
09-05-2016, 18:25:44
Yo en Delphi (Delphi7+Indy10) hago directamente esto (sin el Add)
Gracias Neftalí. Lo he probado tal cual lo pones y me da error al compilar; me temo que lo que en Delphi ponéis como .Create(... en Builder es ->Add(.... No obstante he encontrado en otra web un método que al menos al compilar no me da error:
TIdAttachment *Adjunto = new TIdAttachmentFile(Correo->MessageParts, cPdfFile);
¿Cuál era el problema? Que hay que poner a mano un include (#include "IdAttachmentFile.hpp") en el .h del formulario y esto no lo hace automáticamente el sistema. Una vez puesto esa línea no me ha dado error de compilación; me falta probarlo, pero en cuanto lo haga pongo aquí el resultado.

juanelo
09-05-2016, 20:31:10
Que tal Angel,
Te mando una funcion de como lo hago (solo que uso Indy 9.014), espero te ayude.

bool __fastcall TFrmMail::EnviaMail() // Manda en silencio
{
int i=0,Intento=0;
bool Que=true;
AnsiString Archivo,Imagen,Temp;

TIniFile *Ini;
if(Admin)
{
Ini= new TIniFile( ModuloDeDatos->DirExe + "CorreoAdmin.ini");
Host=Ini->ReadString("Correo","Host","mail.correo.com");
Port=Ini->ReadInteger("Correo","Port",26);
UserID=Ini->ReadString("Correo","UserID","juanelo@correo.com");
Password=Ini->ReadString("Correo","Password","****");
FromAddress=Ini->ReadString("Correo","FromAddress","juanelo@correo.com");
FromName=Ini->ReadString("Correo","FromName","IDEA Sistemas");
PlantillaHTML=Ini->ReadString("Correo","PlantillaHTML","");
Logo=Ini->ReadString("Correo","Logo","");
TextoAdicional=Ini->ReadString("Correo","TextoAdicional","");
UsaSSL=Ini->ReadBool("Correo","UsaSSL",false);
UsaSTARTTLS=Ini->ReadBool("Correo","UsaSTARTTLS",false);
delete Ini;
}

BodyLines = new TStringList();

ModuloDeDatos->LlenaListas(ListaPara,CorreoDestino,false);
ModuloDeDatos->LlenaListas(ListaCC,CC,false);
ModuloDeDatos->LlenaListas(ListaBCC,BCC,false);

SMTP->Username = UserID;
SMTP->Password = Password;
SMTP->Host = Host;
SMTP->Port = Port;
SMTP->AuthenticationType = atLogin;

if(UsaSTARTTLS)
{
SSL->SSLOptions->Method = sslvTLSv1;
SSL->PassThrough = true;
}

if(UsaSSL)
SMTP->IOHandler=SSL;
// Creamos el contenido del mensaje
Mensaje = new TIdMessage(NULL);

Mensaje->Clear();

Mensaje->ContentType = "multipart/mixed";

Mensaje->From->Name = FromName;
Mensaje->From->Address = FromAddress;
Mensaje->Subject = Subject;
//Mensaje->Body->Add(EdtBody->Text);

BodyIndyText = new TIdText(Mensaje->MessageParts,NULL);
BodyIndyText->ContentType="text/plain";
BodyIndyText->Body->Text="";
if(Admin)
BodyLines->Add(Body);
else
{
Temp=EdtBody->Text;
EdtBody->Text=EdtTextAdicional->Text + " <BR> " + EdtBody->Text;
BodyLines->Add(EdtBody->Text);
Body=EdtBody->Text;
}
BodyIndyHtml = new TIdText(Mensaje->MessageParts,BodyLines);
BodyIndyHtml->ContentType="text/html";
BodyIndyHtml->Body->Clear();
BodyIndyHtml->Body->Add(Body);

if(FileExists(Logo))
{
Imagen=ExtractFileName(Logo);
LogoIndy = new TIdAttachment(Mensaje->MessageParts,Logo);
LogoIndy->ContentType = "image/jpeg";
LogoIndy->FileIsTempFile = false;
LogoIndy->ContentDisposition = "inline";
LogoIndy->ExtraHeaders->Values["content-id"] = Imagen;
LogoIndy->DisplayName = Imagen;
}

while(i< ListaCC->Count)
{
Mensaje->CCList->Add();
Mensaje->CCList->Items[i]->Address=ListaCC->Strings[i];
i++;
}

while(i< ListaBCC->Count)
{
Mensaje->BccList->Add();
Mensaje->BccList->Items[i]->Address=ListaBCC->Strings[i];
i++;
}

i=0;
while(i< ListaPara->Count)
{
Mensaje->Recipients->Add();
Mensaje->Recipients->Items[i]->Address=ListaPara->Strings[i];
i++;
}

if(FileExists(Attach1))
IndyAttach1 = new TIdAttachment( Mensaje->MessageParts, Attach1 );

if(FileExists(Attach2))
IndyAttach2 = new TIdAttachment( Mensaje->MessageParts, Attach2);


// Conectamos con el servidor SMTP
while(Intento < 2)
{

try
{
try
{
Application->ProcessMessages();
if(Barra != NULL)
Barra->Panels->Items[0]->Text="Conectando ... ";

if(UsaSTARTTLS)
SMTP->Connect(IdTimeoutDefault);
else
SMTP->Connect();

if(UsaSTARTTLS && SMTP->SendCmd("STARTTLS", 220) == 220)// se coloca PassThrough a false
SSL->PassThrough = false;

if(SMTP->Connected())
{
Application->ProcessMessages();

if(UsaSTARTTLS)
SMTP->Authenticate();
if(Barra != NULL)
Barra->Panels->Items[0]->Text="Enviando correo ... ";
SMTP->Send(Mensaje);
Application->ProcessMessages();
if(Barra != NULL)
Barra->Panels->Items[0]->Text="Desconectando ... ";
SMTP->Disconnect();
Application->ProcessMessages();
if(Barra != NULL)
Barra->Panels->Items[0]->Text="Correo Enviado ... ";

if(EsFactura || EsCPRN)
MarcaFacturaEnviadaPorMail(CveDocto,EnviaXML,-1,TipoDoc);
}
Intento=2;
PuedeCerrar=true;
//DeleteFile(ModuloDeDatos->ArchivoPDF);
}
catch(Exception &e)
{
Que=false;
if(e.Message.AnsiPos("load") == 0) // Por error de Indy
{
Intento=2;
Application->ProcessMessages();
Que=false;
if(Barra != NULL)
Barra->Panels->Items[0]->Text="Error en el envio";
Application->MessageBox(e.Message.c_str(),"Error",MB_OK);
}
else
Intento++;

PuedeCerrar=false;
}
}
__finally
{
if(SMTP->Connected())
SMTP->Disconnect();

if(Intento > 1)
{
if(IndyAttach1!=NULL)
delete IndyAttach1;

if(IndyAttach2!=NULL)
delete IndyAttach2;

if(IndyAttach3!=NULL)
delete IndyAttach3;

if(IndyAttach4!=NULL)
delete IndyAttach4;

if(LogoIndy!=NULL)
delete LogoIndy;


if(Mensaje!=NULL)
delete Mensaje;

EdtBody->Text=Temp;
}
}
}
return Que;
}

Angel.Matilla
10-05-2016, 12:04:11
Gracias por la respuesta juanelo. Ya logré solucionarlo. El código que me has mandado es, más o menos, como lo hacía yo con Indy 9; con Indy 10, como comentaba antes, es que hay que añadir un include en .h del formulario que no se hace de forma automática:
#include "IdAttachmentFile.hpp"y para añadir el adjunto se hace con:
TIdAttachment *Adjunto = new TIdAttachmentFile(IdMessage1->MessageParts, File);siendo File un AnsiString en el que se indica la vía de acceso y el nombre del fichero a adjuntar al mensaje. Ya he hecho varias pruebas y todas me han salido bien.