Однажды встала необходимость написания программы, которая бы отправляла письма организациям без участия пользователя. Требовалось создать «экзешник», который бы все делал и не требовал установки NET.Framework. Единственным инструментом, который был под рукой и подходил для этого стал RAD Studio 2009 C++ Builder.
Т.к до этого я ничего подобного не писал, да и с Indy работать как-то не приходилось, то полез в Интернет, в надежде найти ответ на мой вопрос. Но, порыскав в нем и прочитав огромное количество постов на многочисленных форумах, стало ясно, что ни один из приведенных там примеров мне не подходит, готового решения нет. Было необходимо, чтобы программа могла отправить файл, а так же чтобы тема и тело письма были написаны русским текстом. Т.е получалось, что мне нужно было решить две проблемы, отправка файла и русский текст в письме. Их нужно было решать и как можно скорее.
Решились они многочасовым «гуглением» и собиранием по кусочкам из всего, что только можно.
Привожу рабочий исходник того, что у меня получилось.
Комментарии к коду, я думаю, излишни, т.к он и без того очень прост в понимании.
Надеюсь, что мои старания кому-нибудь, да пригодятся.
Т.к до этого я ничего подобного не писал, да и с Indy работать как-то не приходилось, то полез в Интернет, в надежде найти ответ на мой вопрос. Но, порыскав в нем и прочитав огромное количество постов на многочисленных форумах, стало ясно, что ни один из приведенных там примеров мне не подходит, готового решения нет. Было необходимо, чтобы программа могла отправить файл, а так же чтобы тема и тело письма были написаны русским текстом. Т.е получалось, что мне нужно было решить две проблемы, отправка файла и русский текст в письме. Их нужно было решать и как можно скорее.
Решились они многочасовым «гуглением» и собиранием по кусочкам из всего, что только можно.
Привожу рабочий исходник того, что у меня получилось.
//---------------------------------------------------------------------------
#include <vcl.h>
#include <IdText.hpp> // чтобы работал TIdText
#pragma hdrstop
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "IdBaseComponent"
#pragma link "IdComponent"
#pragma link "IdExplicitTLSClientServerBase"
#pragma link "IdMessage"
#pragma link "IdMessageClient"
#pragma link "IdSMTP"
#pragma link "IdSMTPBase"
#pragma link "IdTCPClient"
#pragma link "IdTCPConnection"
#pragma resource "*.dfm"
#pragma link "crypt32.lib" // чтобы работал base64
#include "IdAttachmentFile.hpp" // чтобы работал TIdAttachmentFile
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//--Base64-------------------------------------------------------------------
AnsiString Base64Encode(AnsiString s)
{
DWORD sz;
AnsiString res;
CryptBinaryToString((unsigned char*)s.c_str(), s.Length(), CRYPT_STRING_BASE64, NULL, &sz);
char *r;
r = (char*)GlobalAlloc(GPTR, sz);
CryptBinaryToString((unsigned char*)s.c_str(), s.Length(), CRYPT_STRING_BASE64, r, &sz);
res = AnsiString( r );
GlobalFree( r );
res = res.Delete(sz-1, 2);
return res;
}
AnsiString Base64Decode(AnsiString s)
{
DWORD sz;
AnsiString res;
CryptStringToBinary(s.c_str(), s.Length(), CRYPT_STRING_BASE64, NULL, &sz, NULL, NULL);
char *r;
r = (char*)GlobalAlloc(GPTR, sz);
CryptStringToBinary(s.c_str(), s.Length(), CRYPT_STRING_BASE64, r, &sz, NULL, NULL);
res = AnsiString( r );
res.SetLength(sz);
GlobalFree( r );
return res;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::ButtonClick(TObject *Sender)
{
IdSMTP->Disconnect();
//****Авторизация****
IdSMTP->Host="smtp.bank.ru";
IdSMTP->Username="user@bank.ru";
IdSMTP->Password="ahgk*3iHFAJgal";
IdSMTP->Port=25;
IdSMTP->MailAgent="BankMailSender";
IdSMTP->UseTLS=utNoTLSSupport;
IdSMTP->AuthType=satDefault;
IdSMTP->ConnectTimeout=10000;
//****Адреса****
IdMessage->Clear();
IdMessage->OnInitializeISO=IdMessageInitializeISO;
IdMessage->From->Address="user@bank.ru";
AnsiString name="Банк";
IdMessage->From->Name="=?windows-1251?B?"+Base64Encode(name)+"?=";
IdMessage->ReplyTo->Clear();
IdMessage->ReplyTo->EMailAddresses="recipient@bank.ru";
IdMessage->Recipients->EMailAddresses="recipient@bank.com";
IdMessage->ReceiptRecipient->Text="";
IdMessage->CharSet="windows-1251";
AnsiString subj="Русский текст темы";
AnsiString att="c:\\test.txt";
AnsiString body="Русский текст письма";
IdMessage->Subject="=?windows-1251?B?"+Base64Encode(subj)+"?=";
IdMessage->ContentType="multipart/mixed";
IdMessage->Encoding=meMIME;
if (att !="")
{
//****Вложение****
TIdAttachmentFile *attachment = new TIdAttachmentFile(IdMessage->MessageParts, att);
attachment->ContentTransfer="base64";
attachment->ContentDisposition = "attachment";
attachment->ContentType="application/octet-stream;";
attachment->FileName="=?windows-1251?B?"+Base64Encode(ExtractFileName(att))+"?=";;
TIdText *TextPart = new TIdText(IdMessage->MessageParts, NULL);
TextPart->ContentType="text/plain";
TextPart->ContentTransfer="base64";
TextPart->CharSet="windows-1251";
TextPart->Body->Add(body);
TextPart->ParentPart=-1;
}
else
{
IdMessage->ContentType="text/plain";
IdMessage->Body->Add("=?windows-1251?B?"+Base64Encode(body)+"?=");
}
IdSMTP->Connect();
try
{
IdSMTP->Send(IdMessage);
}
__finally
{
IdSMTP->Disconnect();
}
}
//---------------------------------------------------------------------------
void __fastcall TForm2::IdMessageInitializeISO(wchar_t &VHeaderEncoding, UnicodeString &VCharSet)
{
VCharSet="windows-1251";
}
//---------------------------------------------------------------------------
Комментарии к коду, я думаю, излишни, т.к он и без того очень прост в понимании.
Надеюсь, что мои старания кому-нибудь, да пригодятся.