2011-11-22 19 views
5

Używam Delphi 2006 do tworzenia i wysyłania wiadomości e-mail z załącznikiem w aplikacji do użytku osobistego. Wysyłam wiadomość z instancją TIdSMTP, a następnie umieszczam kopię w określonym folderze IMAP z instancją TIdIMAP4. Wszystko to działa bardzo dobrze z wersją Indy 10, która była dystrybuowana z BDS2006, z jednym wyjątkiem: czas jest zawsze niepoprawny w nagłówku wiadomości e-mail.Nieprawidłowy ciąg znaków w wiadomości wieloczęściowej/mieszanej

Postanowiłem to naprawić, gdybym mógł, a po wyszukaniu rozwiązania wydawało się najbardziej sensowne, aby uzyskać najnowszą migawkę Indy 10 i użyć jej.

To umieszcza właściwy czas w nagłówku wiadomości e-mail, ale pojawia się nowy problem. Łańcuch granic jest teraz inny w nagłówku wiadomości dodawanej do folderu IMAP niż w treści wiadomości e-mail! (Należy pamiętać, że wiadomość, która została wysłana przez SMTP jest prawidłowa).

Jest to istotne informacje Główka starszej wersji Indy 10:

Content-Type: multipart/mixed; boundary="XNlC6OyS4QSiHY2U=_jsXyps6TR34pFNsh" 
MIME-Version: 1.0 
Date: Tue, 22 Nov 2011 09:11:58 +0000 

A test of the BDS2006-bundled version of Indy 

--XNlC6OyS4QSiHY2U=_jsXyps6TR34pFNsh 
Content-Type: application/octet-stream; 
     name="20111122.xls" 

I to jest ta sama informacja Główka Indy 10,5 0,8 (snapshot 10_4702 który zainstalowałem wczoraj):

Content-Type: multipart/mixed; boundary="CDbEncbFvL7RZdOJ3DOIRoRBs=_nBsbZms" 
MIME-Version: 1.0 
Date: Tue, 22 Nov 2011 07:33:46 -0600 

investigating more deeply, why does the boundary indicator change? 

--h=_WzGWJei29fng7SqdPpDh1nkJxJZhiGc 
Content-Type: application/octet-stream; 
    name="20111122.xls" 

Znacznik czasu jest stała, ale teraz ciąg granica jest nieprawidłowy. W rezultacie komunikat pojawia się w moim folderze IMAP.

Oto odpowiedni kod, który tworzy wiadomość e-mail i załączników, wysyła go i umieszcza kopię w folderze IMAP:

FTheMsg.Date := Now; // FTheMsg is a component dropped onto the form 
    FTheMsg.Recipients.EMailAddresses := edMailTo.Text; 
    FTheMsg.ClearBody; 
    FTheMsg.Subject := 'Glucose Readings ' + FormatDateTime('mm/dd/yy', FStartDate) + ' - ' + 
       FormatDateTime('mm/dd/yy', FEndDate); 
    FTheMsg.Body.Assign(FMemo.Lines); 

    // create the attachment 
    TIdAttachmentFile.Create(FTheMsg.MessageParts, fileName); 

    // send the mail! 
    FSmtp.Host := FSMTPHost; // values set up elsewhere, FSmtp is a component on the form 
    FImap.Host := FIMAPHost; // FImap is also a component on the form 

    FSmtp.Connect; 
    try 
    FSmtp.Send(FTheMsg); 
    FImap.Connect; 
    try 
     if (not FImap.AppendMsg('Sent Items', FTheMsg, FTheMsg.LastGeneratedHeaders, [mfSeen]))  then 
     StatusBar1.Panels[4].Text := 'Failed append msg'; 
    finally 
     FImap.Disconnect; 
    end; 
    finally 
    FSmtp.Disconnect; 
    end; 

Jak powiedziałem, e-mail, który zostanie wysłany jest w porządku i dobrze wyświetlany . Ale ten, który jest dodany do mojego folderu IMAP (w FImap.AppendMsg() powyżej) jest niepoprawny. Próbowałem prześledzić kod, aby zobaczyć, gdzie może być źle, ale, szczerze mówiąc, nie znam wystarczająco dobrze Indy i różnych protokołów e-mail/RFC, aby móc określić, co się dzieje. O wszystkim mogę powiedzieć, że starsza wersja zapisuje komunikat do pliku tymczasowego przed dołączeniem go do folderu, podczas gdy nowsza wersja zapisuje go w strumieniu pamięci. Oczywiście, jest w tym coś odmiennego, ale obecnie jestem zbyt nieświadomy, by ustalić, co.

Czy istnieje prosty sposób na naprawienie problemu z sygnaturą czasową w starej wersji? Jeśli tak, to byłoby w porządku dla mojego użytku, ponieważ wszystko inne wydaje się poprawne. Jeśli nie, to co jeszcze muszę zrobić, aby naprawić problem tutaj pokazany z niepoprawnym łańcuchem znaków?

(Ponieważ jest to aplikacja wyłącznie dla własnego użytku, mogę żyć z błędnej daty, jeśli muszę, ale nie z „pustym wyglądającej” kopia w moim folderze „Elementy wysłane”).

Jeśli potrzebnych jest więcej informacji, chętnie dostarczę, co w mojej mocy.

[Edytuj: Wprowadziłem coś z kludge do mojego kodu, używając starszej wersji Indy. Po prostu ustawiam datę/czas wiadomości na czas UTC/GMT przed wysłaniem, a to przynajmniej pozwala, aby wiadomość zawierała prawidłowy czas na końcu odbiorcy. Nie dbam szczególnie o tę poprawkę, ale to wystarczy.]

Odpowiedz

4

Nie używaj właściwości TIdMessage.Body do przechowywania tekstu, gdy załącznik jest obecny. Zamiast tego umieść tekst w obiekcie TIdText. Nawet lepiej, użyj klas TIdMessageBuilder..., takich jak TIdMessageBuilderPlain, aby przygotować ciało TIdMessage dla ciebie.

Spróbuj tego:

FTheMsg.Clear; 
FTheMsg.Date := Now; // FTheMsg is a component dropped onto the form 
FTheMsg.Recipients.EMailAddresses := edMailTo.Text; 
FTheMsg.Subject := 'Glucose Readings ' + FormatDateTime('mm/dd/yy', FStartDate) + ' - ' + FormatDateTime('mm/dd/yy', FEndDate); 
FTheMsg.ContentType := 'multipart/mixed'; 

TIdText.Create(FTheMsg.MessageParts, FMemo.Lines).ContentType := 'text/plain'; 
TIdAttachmentFile.Create(FTheMsg.MessageParts, fileName); 

FSmtp.Connect; 
try 
    FSmtp.Send(FTheMsg); 
    FImap.Connect; 
    try 
    if (not FImap.AppendMsg('Sent Items', FTheMsg, nil, [mfSeen])) then 
     StatusBar1.Panels[4].Text := 'Failed append msg'; 
    finally 
    FImap.Disconnect; 
    end; 
finally 
    FSmtp.Disconnect; 
end; 

czyli

FTheMsg.Clear; 
FTheMsg.Date := Now; // FTheMsg is a component dropped onto the form 
FTheMsg.Recipients.EMailAddresses := edMailTo.Text; 
FTheMsg.Subject := 'Glucose Readings ' + FormatDateTime('mm/dd/yy', FStartDate) + ' - ' + FormatDateTime('mm/dd/yy', FEndDate); 

with TIdMessageBuilderPlain.Create do 
try 
    PlainText.Assign(FMemo.Lines); 
    Attachments.Add(fileName); 
    FillMessage(FTheMsg); 
finally 
    Free; 
end; 

FSmtp.Connect; 
try 
    FSmtp.Send(FTheMsg); 
    FImap.Connect; 
    try 
    if (not FImap.AppendMsg('Sent Items', FTheMsg, nil, [mfSeen])) then 
     StatusBar1.Panels[4].Text := 'Failed append msg'; 
    finally 
    FImap.Disconnect; 
    end; 
finally 
    FSmtp.Disconnect; 
end; 

Teraz, z tym powiedział, to jest prawdopodobne, że będzie on nadal nie działa poprawnie w obu kierunkach. TIdIMAP4.AppendMsg() dzwoni TIdMessage.SaveToStream() wewnętrznie, który ponownie generuje zawartość wiadomości e-mail (i tym samym zmienia granicę używaną w treści). Niezależnie od tego, czy zostanie przekazany istniejący TIdMessage.LastGeneratedHeaders, czy też TIdIMAP4.AppendMsg(), pobierzesz bieżący numer TIdMessage.Headers, nie będą one zsynchronizowane z nową granicą, którą wygeneruje TIdMessage.SaveToStream().

Aby mieć pewność, że zarówno SMTP, jak i IMAP4 są zsynchronizowane, muszą otrzymać te same dane. Spróbuj zadzwonić TIdMessage.SaveToStream() ręcznie pierwszy z właściwością TIdMessage.NoEncode ustawiona na false, a następnie ustawić właściwość TIdMessage.NoDecode True i nazywają TIdMessage.LoadFromStream() przeładować zapisane dane jak jest do TIdMessage.Headers i TIdMessage.Body właściwości, a następnie zadzwonić TIdSMTP.Send() i TIdIMAP4.AppendMsg() z właściwością TIdMessage.NoEncode ustawiony na true więc TIdMessage.Headers i TIdMessage.Body są wysyłane tak jak jest.

Wiem, to jest sprzeczne z tym, co mówią komentarze/dokumenty do zrobienia. AppendMsg() aktualnie nie uwzględnia w ogóle MIME, więc nie zapewnia zgodności granicy MIME w nagłówku i treści. Spróbuję sprawdzić poprawkę. W przypadku Indy 11, cały system obsługi MIME Indy'ego zostanie przeprojektowany, więc upewnię się, że możliwe jest zachowanie granic i/lub określenie niestandardowych granic, dzięki czemu można lepiej dopasować granicę ciała do granicy nagłówka.

IMAP4 jest bardzo trudnym protokołem do pracy w ogóle.

+0

Cóż, to miało wpływ, ale nie dokładnie to, czego szukałem. Stworzyłem strumień pamięci, ustaw FTheMsg.NoEncode: = False, zapisałem wiadomość do strumienia, zresetowałem FTheMsg.NoEncode: = True i ponownie załadowałem wiadomość, a następnie wysłałem ją przy pomocy TIdSMTP.Send() i TIdIMAP4.AppendMsg(), NIL jako parametr "AdditionalHeaders". Powoduje to, że nie mam żadnego załącznika, a tekst nie jest widoczny w wiadomości! – pejurgenson

+0

To jest kompletna wiadomość po zapisaniu jej z NoEncode = False, a następnie ponownie załadowana NoEncode = True 'code' Temat: Odczyty glukozy 11/07/11 - 11/20/11 Do: [email protected] Typ treści: wieloczęściowy/mieszany; granica = "D9uTCLury1wVu8hlPEcf = _0afpyB9eNLrK" MIME-Version: 1.0 Data: Tue, 22 listopada 2011 15:00:10 -0600 To jest wiadomość wieloczęściowe w formacie MIME . Z NoEncode = False, zapisany komunikat jest wyświetlany jako ukończony. – pejurgenson

+0

Przepraszam, źle odczytałem bit o ustawieniu NoEncode - czytałem go jako NoDecode! Ups. Jeśli zrobię to poprawnie, tak jak w notatce, wiadomość przychodzi poprawnie, zarówno u odbiorcy, jak i w folderze "Elementy wysłane". Dziękuję bardzo za pomoc, jest to bardzo doceniane! Zdecydowanie przyjmuję tę odpowiedź. – pejurgenson

Powiązane problemy