На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
Модераторы: Rouse_, jack128, Krid
  
    > при отправке письма используя Indy 10, получаются "крякозябры" в теме
      Многие кто когда либо отправлял или создавал письма используя Indy 10, получал совсем не читабельный вид темы письма
      Как не странно, но разработчики решили, что в России для писем используют в основном KOI8R кодировку а не WINDOWS-1251.
      Отсюда и такие "крякозябры" в теме письма.


      Кпримеру:
      ExpandedWrap disabled
        ...
        IdMessage1.CharSet := 'windows-1251'; //но это пока мы не исправим исходники роли не играет.
        ...
        IdMessage1.Subject := 'Тема письма';
        ...


      Для исправления этого потребуется правка исходников Indy.
      В модуле IdGlobalProtocols.pas находим функцию IdGetDefaultCharSet и меняем строку
      LANG_RUSSIAN: Result := idcsKOI8_R;
      на
      LANG_RUSSIAN: Result := idcsWINDOWS_1251;
      Ну и разумеется перекомпилируем.

      Мне помогло, надеюсь поможет и вам ;)
      Сообщение отредактировано: User32 -
      Незнание некоторых фактов сполна компенсируется знанием некоторых принципов...
        Можно ли с Вами побеседовать?

        Я, как то раз, в три часа ночи решил перейти на Indy 10? для того что бы отправлять письма через gmail.com ...
        Лучше бы пошел спать!

        У меня история такая: С темой у меня пока не получается еще - ...

        Но даже пока еще не поменял в исходниках:

        LANG_RUSSIAN: Result := idcsWINDOWS_1251;

        устанавливая CharSet := 'windows-1251';

        я отправлял письма на русском языке, потом просматривал в браузере - дошло по русски,
        затем в том же Thunderbird-e получаю - все в порядке.

        А на Indy 10-ом, хоть выспись - чего только не предпринимал.

        Причем, меняя CharSet при отправке - в браузере я вижу, что кодировка самого тела меняется,
        и я могу переключаться там и видеть, что совпадает с тем, что я отправил.

        Но получить с помощью Indy 10 не получается.

        Именно с такой ситуацией, Вы сталкивались?

        Буду очень благодарен, если поддержите беседу, хотя бы парой писем.
          У меня проблема другая.
          Отправляю письмо хоть в юникоде, хоть в виндовой кодировке.
          1. В теме указываю: Рассылка новых объектов
          В письме приходит в ящик: новых объектов

          2. Прикрепляю экселевский файл с русскоязычным названием. В ящик приходит с прикрплённым письмом, но имя Part1.2 или noname

          D2007. Indy 10.5.7 (r4154 2010-03-25).

          Добавлено
          Вот код. Раньше на старой версии инди работал отлично.
          ExpandedWrap disabled
            procedure TfmEmail.SendMail(aRecordIndex:integer);
            Var
             q: TpFibQuery;
             IdEMailAddressList2, IdEMailAddressListCopy: TIdEMailAddressList;
            begin
              sCharSet := dbgmail.DataController.Values[aRecordIndex, dbgMailCHARSET.Index];
             
              if dbgmail.DataController.Values[aRecordIndex, dbgMailLOCKED.Index] then
                begin
             
                  exit;
                end;
             
              Log('Отправка рассылки:' + dbgmail.DataController.Values[aRecordIndex, dbgMailname.Index]);
             
              IdSMTP1.DisConnect;
              IdMessage1.Clear;
              IdMessage1.From.Name    := '';
              SysLocale.PriLangID     := LANG_SYSTEM_DEFAULT;// LANG_RUSSIAN;// LANG_UKRAINIAN;
              IdMessage1.CharSet      := sCharSet;
              IdMessage1.ContentType  := 'multipart/related; type="multipart/alternative"';
            //  IdMessage1.ContentTransferEncoding := 'bit7';
              IdMessage1.ContentTransferEncoding := '8bit';
             
             
             
              IdSMTP1.ConnectTimeout  := 60*100;
             
              IdMessage1.From.Address := dbgmail.DataController.Values[aRecordIndex, dbgMailE_MAIL.Index];
              //от кого
              case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
            //    0: IdMessage1.From.Name    := AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailFROM_NAME.Index]);
                0: IdMessage1.From.Name    := dbgmail.DataController.Values[aRecordIndex, dbgMailFROM_NAME.Index];
                1: IdMessage1.From.Name    := dbgmail.DataController.Values[aRecordIndex, dbgMailFROM_NAME.Index];
              end;
             
             
              //кому
              IdEMailAddressList2 := TIdEMailAddressList.Create(IdMessage1);
             
              //получатели
              case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
            //    0: IdEMailAddressList2.EMailAddresses := AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailRECIPIENT.Index]);
                0: IdEMailAddressList2.EMailAddresses := dbgmail.DataController.Values[aRecordIndex, dbgMailRECIPIENT.Index];
                1: IdEMailAddressList2.EMailAddresses := dbgmail.DataController.Values[aRecordIndex, dbgMailRECIPIENT.Index];
              end;
             
              IdMessage1.Recipients.EMailAddresses := EncodeAddress(IdEMailAddressList2, 'B',  sCharSet);
             
             
              //копия
              if dbgMail.DataController.Values[aRecordIndex, dbgMailRECIPIENT_COPY.Index] <> null then
                begin
                    IdEMailAddressListCopy := TIdEMailAddressList.Create(IdMessage1);
             
                    //получатели
                    case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
            //          0: IdEMailAddressListCopy.EMailAddresses := AnsiToUtf8(dbgMail.DataController.Values[aRecordIndex, dbgMailRECIPIENT_COPY.Index]);
                      0: IdEMailAddressListCopy.EMailAddresses := dbgMail.DataController.Values[aRecordIndex, dbgMailRECIPIENT_COPY.Index];
                      1: IdEMailAddressListCopy.EMailAddresses := dbgmail.DataController.Values[aRecordIndex, dbgMailRECIPIENT_COPY.Index];
                    end;
                    IdMessage1.CCList.EMailAddresses := EncodeAddress(IdEMailAddressListCopy, 'B',  sCharSet);
                end;
             
             
              //от кого
              case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
            //    0: IdMessage1.ReplyTo.EMailAddresses := AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_FROM.Index]);
                0: IdMessage1.ReplyTo.EMailAddresses := dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_FROM.Index];
                1: IdMessage1.ReplyTo.EMailAddresses := dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_FROM.Index];
              end;
             
              //тема
              case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
            //    0: IdMessage1.Subject    := AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailSUBJECT.Index]);
                0: IdMessage1.Subject    := dbgmail.DataController.Values[aRecordIndex, dbgMailSUBJECT.Index];
                1: IdMessage1.Subject    := dbgmail.DataController.Values[aRecordIndex, dbgMailSUBJECT.Index];
              end;
             
             
                with TIdText.Create(IdMessage1.MessageParts, nil) do begin
                  CharSet := sCharSet;
                  case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
            //        0: Body.Add(AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailTITLE.Index]));
                    0: Body.Add(dbgmail.DataController.Values[aRecordIndex, dbgMailTITLE.Index]);
                    1: Body.Add(dbgmail.DataController.Values[aRecordIndex, dbgMailTITLE.Index]);
                  end;
             
                  case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
            //        0: Body.Add(AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailbody.Index]));
                    0: Body.Add(dbgmail.DataController.Values[aRecordIndex, dbgMailbody.Index]);
                    1: Body.Add(dbgmail.DataController.Values[aRecordIndex, dbgMailbody.Index]);
                  end;
             
                  case ansiindextext(sCharSet, ['UTF-8', 'windows-1251']) of
            //        0: Body.Add(AnsiToUtf8(dbgmail.DataController.Values[aRecordIndex, dbgMailFOOTER.Index]));
                    0: Body.Add(dbgmail.DataController.Values[aRecordIndex, dbgMailFOOTER.Index]);
                    1: Body.Add(dbgmail.DataController.Values[aRecordIndex, dbgMailFOOTER.Index]);
                  end;
             
                  ContentType := 'text/plain';
                end;
             
             
              IdMessage1.IsEncoded  := true;
             
              IdSMTP1.Host      := dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP.Index];
              IdSMTP1.Username  := dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_USER.Index];
              IdSMTP1.Password  := Decrypt(dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_PASSWORD.Index], k_sm);
             
              case ansiindextext(dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_TYPE_CRYPT.Index], ['нет', 'неявное', 'явное', 'принудительное']) of
                0: IdSMTP1.UseTLS    := utNoTLSSupport;
                1: IdSMTP1.UseTLS    := utUseImplicitTLS;
                2: IdSMTP1.UseTLS    := utUseExplicitTLS;
                3: IdSMTP1.UseTLS    := utUseRequireTLS;
              end;
             
              IdSMTP1.Port      := dbgmail.DataController.Values[aRecordIndex, dbgMailSMTP_PORT.Index];
              IdSMTP1.AuthType  := satDefault;
             
              IdSSLIOHandlerSocketOpenSSL1.Destination  := IdSMTP1.Host + ':' + IntToStr(IdSMTP1.Port);
              IdSSLIOHandlerSocketOpenSSL1.Host         := IdSMTP1.Host;
              IdSSLIOHandlerSocketOpenSSL1.MaxLineAction:= maException;
              IdSSLIOHandlerSocketOpenSSL1.Port         := IdSMTP1.Port;
              IdSSLIOHandlerSocketOpenSSL1.DefaultPort  := 0;
              IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Mode        := sslmUnassigned;
              IdSSLIOHandlerSocketOpenSSL1.SSLOptions.VerifyMode  := [];
              IdSSLIOHandlerSocketOpenSSL1.SSLOptions.VerifyDepth := 0;
             
              q := TpFibQuery.Create(nil);
              try
                q.Database := DM.fibDB;
                q.Transaction := trMailRead;
                q.SQL.Text    := 'SELECT NAME FROM MAIL_ATTACHMENTS where ID_MAIL = :m_ID';
                q.ParamByName('m_ID').AsInteger := dbgmail.DataController.Values[aRecordIndex, dbgMailID.Index];
                q.ExecQuery;
                q.GoToFirstRecordOnExecute := true;
                while not q.Eof do
                    if FileExists(q.FieldByName('name').AsString) then
                      begin
                        with TIdAttachmentFile.Create(IdMessage1.MessageParts, q.FieldByName('name').AsString) do begin
                          case AnsiIndexText(ExtractFileExt(AnsiUpperCase(q.FieldByName('name').AsString)), ['.XLS', '.XLSX', '.RAR', '.ZIP', '.DOC', '.DOCX', '.HTML', '.TXT']) of
                            0: ContentType := 'application/vnd.ms-excel';
                            1: ContentType := 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
                            2: ContentType := 'application/x-rar-compres';
                            3: ContentType := 'application/zip';
                            4: ContentType := 'application/msword';
                            5: ContentType := 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
                            6: begin ContentType := 'text/html; charset=WINDOWS-1251'; {ContentDisposition := 'inline'} end;
                            7: begin ContentType := 'text/plain; charset=WINDOWS-1251'; {ContentDisposition := 'inline'} end;
                            else
                            ContentType := 'application/octet-stream';
             
                          end;
             
                          //FileName    := AnsiToUtf8(q.FieldByName('name').AsString);
                          FileName    := q.FieldByName('name').AsString;
                        end;
                        q.next;
                      end;//if FileExists(q.FieldByName('name').AsString) then
              finally
                q.close;
                FreeAndNil(q);
              end;
             
              Log('Подключение к: ' + IdSMTP1.Host + ':'+IntToStr(IdSMTP1.Port));
              IdSMTP1.Connect;
             
              dxStatusBar1.Panels[1].Text := 'Отправка: ' + dbgmail.DataController.Values[aRecordIndex, dbgMailName.Index];
              Application.ProcessMessages;
             
              Log('Отправка.....');
              IdSMTP1.Send(IdMessage1);
             
              Log('Рассылка отправлена');
             
              Log('Отключение от сервера...');
              IdSMTP1.DisConnect;
             
              tMail.Edit;
              tMail.FBN('LAST_DATE').AsDateTime := now;
              tMail.FBN('SEND_COUNT').AsInteger := tMail.FBN('SEND_COUNT').AsInteger + 1;
              tMail.post;
              tMail.refresh;
             
              FreeAndNil(IdEMailAddressList2);
            end;
            Цитата mvdmvd @
            Можно ли с Вами побеседовать?

            Я, как то раз, в три часа ночи решил перейти на Indy 10? для того что бы отправлять письма через gmail.com ...
            Лучше бы пошел спать!

            У меня история такая: С темой у меня пока не получается еще - ...

            Но даже пока еще не поменял в исходниках:

            LANG_RUSSIAN: Result := idcsWINDOWS_1251;

            устанавливая CharSet := 'windows-1251';

            я отправлял письма на русском языке, потом просматривал в браузере - дошло по русски,
            затем в том же Thunderbird-e получаю - все в порядке.

            А на Indy 10-ом, хоть выспись - чего только не предпринимал.

            Причем, меняя CharSet при отправке - в браузере я вижу, что кодировка самого тела меняется,
            и я могу переключаться там и видеть, что совпадает с тем, что я отправил.

            Но получить с помощью Indy 10 не получается.

            Именно с такой ситуацией, Вы сталкивались?

            Буду очень благодарен, если поддержите беседу, хотя бы парой писем.

            Ну не знаю, тут все индивидуально...
            Какая версия Delphi и Indy?

            У меня к примеру Delphi 6.0 EE + Indy 10.1.5 и уменя прекрасно работает вот этот пример.
            ExpandedWrap disabled
              procedure TForm1.Button1Click(Sender: TObject);
              var
                SL: TStringList;
                id_ris: string;
              begin
                SL := TStringList.Create;
                id_ris := 'ris_'+IntToHex(Random(MaxInt), 4) + IntToHex(Random(MaxInt), 4); // генерим идентификатор
                try
                  SL.Add('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">');
                  SL.Add('<html><head>');
                  SL.Add('<title>Заголовок</title>'); //в принципи не нужен
                  SL.Add('</head><body>');
                  SL.Add('<div>Текст</div>');
                  SL.Add('<img src="cid:' + id_ris + '">');// вот тут используем
                  SL.Add('</body></html>');
                  with TIdText.Create(IdMessage1.MessageParts, SL) do // загружаем тело письма
                  begin
                    ContentType := 'text/html'; // выставляем тип контента
                    CharSet := 'windows-1251'; // выставляем тип кодировки
                  end;
                  with TIdAttachmentFile.Create(IdMessage1.MessageParts, 'C:\Копия Тестовое вложение Access.PNG') do
                  begin
                    ContentID := id_ris; // присваеваем идентификатор
                  end;
               
                  IdMessage1.Subject := 'Тестовое письмо'; // Тема письма
                  IdMessage1.Recipients.EMailAddresses := 'user@mail.ru'; // Кому
                  IdMessage1.From.Name := 'Президент России'; // От кого
                  IdMessage1.From.Address:='president@mail.ru'; // EMail-От кого
                  //*****************************************************
                  IdSMTP1.MailAgent := 'Microsoft Outlook Express 6.00.2900.2180';
                  IdSMTP1.Host := 'smtp.server.ru'; // Сервер SMTP
                  IdSMTP1.Port := 25; // Порт сервера
                  IdSMTP1.AuthType := satNone; // Тип аутенфикации \ без запроса логина и пароля
               
                  IdSMTP1.Connect;
                  IdSMTP1.Send(IdMessage1);
                  IdSMTP1.Disconnect;
               
                finally
                  SL.free;
                end;
              end;


            Но при условии что мы изменили функцию IdGetDefaultCharSet в модуле IdGlobalProtocols.PAS

            ExpandedWrap disabled
              function IdGetDefaultCharSet: TIdCharSet;
              {$IFDEF USEINLINE}inline;{$ENDIF}
              begin
                {$IFDEF UNIX}
                Result := GIdDefaultCharSet;
                {$ENDIF}
                {$IFDEF DOTNET}
                Result := idcsUNICODE_1_1;
                // not a particular Unicode encoding - just unicode in general
                // i.e. DotNet native string is 2 byte Unicode, we do not concern ourselves
                // with Byte order. (though we have to concern ourselves once we start
                // writing to some stream or Bytes
                {$ENDIF}
                {$IFDEF WIN32_OR_WIN64_OR_WINCE}
                // Many defaults are set here when the choice is ambiguous. However for
                // IdMessage OnInitializeISO can be used by user to choose other.
                case SysLocale.PriLangID of
                  LANG_CHINESE: begin
                    if SysLocale.SubLangID = SUBLANG_CHINESE_SIMPLIFIED then begin
                      Result := idcsGB2312;
                    end else begin
                      Result := idcsBig5;
                    end;
                  end;
                  LANG_JAPANESE: Result := idcsISO_2022_JP;
                  LANG_KOREAN: Result := idcscsEUCKR;
                  // Kudzu
                  // 1251 is the Windows standard for Russian but its not used in emails.
                  // KOI8-R is by far the most widely used and thus the default.
              (* Изменения начинаются тут *)
              //    LANG_RUSSIAN: Result := idcsKOI8_R; //Rem by User32!!!
                  LANG_RUSSIAN: Result := idcsWINDOWS_1251; //Add by User32!!!
              (* И заканчиваются тут *)
                  // Kudzu
                  // Ukranian is about 50/50 KOI8u and 1251, but 1251 is the newer one and
                  // the Windows one so we default to it.
                  LANG_UKRAINIAN: Result := idcswindows_1251;
                  else begin
                    Result := idcsISO_8859_1;
                  end;
                end;
                {$ENDIF}
              end;


            Добавлено
            Цитата X11 @
            У меня проблема другая.
            Отправляю письмо хоть в юникоде, хоть в виндовой кодировке.
            1. В теме указываю: Рассылка новых объектов
            В письме приходит в ящик: новых объектов

            2. Прикрепляю экселевский файл с русскоязычным названием. В ящик приходит с прикрплённым письмом, но имя Part1.2 или noname

            D2007. Indy 10.5.7 (r4154 2010-03-25).

            Я сейчас не работаю в Delphi 2007 - 2010, но вот эта статейка думаю может вам помочь.

            http://denov.ru/?tag=tidattachmentfile
            Сообщение отредактировано: User32 -
            Незнание некоторых фактов сполна компенсируется знанием некоторых принципов...
            1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script Execution time: 0,0970 ]   [ 15 queries used ]   [ Generated: 18.11.17, 12:19 GMT ]