![]() |
MAPI Mailversand mit TB und Delphi 7
Nabend zusammen,
ich arbeite noch mit Delphi 7 (ja, funzt noch) und habe bisher unter Win10 keine Probleme mit dem MAPI Mailversand mit folgender Proc gehabt. Unter Win11 gehts nicht mehr; ich kriege keine Fehlermeldung, aber die Mail geht nicht raus. Ich habe Thunderbird als MailTo Standard-Client gesetzt und mit
Delphi-Quellcode:
wird auch TB aufgerufen. Aber warum geht das verdammte MAPI nicht?
shellexecute(0, 'open', PChar(mmail), '', '', SW_NORMAL);
Schon mal Danke für Eure Mühe. BG Zongo
Delphi-Quellcode:
function SendFileMail(const FileName: TFileName; const Subject, BodyText,
RecipAdress: String; bccx:boolean ): String; (* die registry muss folgende Werte aufweisen: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Messaging Subsystem\MAPI="1" HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows Messaging Subsystem\MAPI="1" *) var mMessage: TMapiMessage; mlpFiles: TMapiFileDesc; mRecips: TMapiRecipDesc; begin if not FileExists(FileName) and (filename<>'') then begin Result := 'File "' + FileName + '" not found!'; Exit; end; with mRecips do begin if not bccx then ulRecipClass := MAPI_TO else ulRecipClass := MAPI_BCC; lpszName := PChar(RecipAdress); lpszAddress := PChar(RecipAdress); ulEIDSize := 0; lpEntryID := nil; end; with mlpFiles do begin flFlags := 0; nPosition := 0; lpszPathName := PChar(FileName); lpszFileName := nil; lpFileType := nil; end; with mMessage do begin lpszSubject := PChar(Subject); lpszNoteText := PChar(BodyText); lpszMessageType := nil; lpszDateReceived := nil; lpszConversationID := nil; flFlags := 0; lpOriginator := nil; nRecipCount := 1; lpRecips := @mRecips; nFileCount := 1; lpFiles := @mlpFiles; if filename='' then lpFiles:= nil; // if html then lpszNoteText:=nil; // dann wird der Anhang als HTML Message-Text benutzt end; case MapiSendMail(0, 0, mMessage, MAPI_LOGON_UI or MAPI_NEW_SESSION, 0) of MAPI_E_AMBIGUOUS_RECIPIENT: begin Result := 'A recipient matched more than one of the recipient descriptor structures and MAPI_DIALOG was not set!'; mmonitor('SendFileMail answer: A recipient matched more than one of the recipient descriptor structures and MAPI_DIALOG was not set!'); end; MAPI_E_ATTACHMENT_NOT_FOUND: begin Result := 'The specified attachment was not found!'; mmonitor('SendFileMail answer: The specified attachment was not found!'); end; MAPI_E_ATTACHMENT_OPEN_FAILURE: begin Result := 'The specified attachment could not be opened!'; mmonitor('SendFileMail answer: The specified attachment could not be opened!'); end; MAPI_E_BAD_RECIPTYPE: begin Result := 'The type of a recipient was not MAPI_TO, MAPI_CC, or MAPI_BCC!'; mmonitor('SendFileMail answer: The type of a recipient was not MAPI_TO, MAPI_CC, or MAPI_BCC!'); end; MAPI_E_FAILURE: begin Result := 'One or more unspecified errors occurred!'; mmonitor('SendFileMail answer: One or more unspecified errors occurred!'); end; MAPI_E_INSUFFICIENT_MEMORY: begin Result := 'There was insufficient memory to proceed!'; mmonitor('SendFileMail answer: There was insufficient memory to proceed!'); end; MAPI_E_LOGIN_FAILURE: begin Result := 'There was no default logon, and the user failed to log on successfully when the logon dialog box was displayed!'; mmonitor('SendFileMail answer: There was no default logon, and the user failed to log on successfully when the logon dialog box was displayed!'); end; MAPI_E_TEXT_TOO_LARGE: begin Result := 'The text in the message was too large to sent!'; mmonitor('SendFileMail answer: The text in the message was too large to sent!'); end; MAPI_E_TOO_MANY_FILES: begin Result := 'There were too many file attachments!'; mmonitor('SendFileMail answer: There were too many file attachments!'); end; MAPI_E_TOO_MANY_RECIPIENTS: begin Result := 'There were too many recipients!'; mmonitor('SendFileMail answer: There were too many recipients!'); end; MAPI_E_UNKNOWN_RECIPIENT: begin Result := 'A recipient did not appear in the address list!'; mmonitor('SendFileMail answer: A recipient did not appear in the address list!'); end; MAPI_E_USER_ABORT: begin Result := 'The user canceled one of the dialog boxes!'; mmonitor('SendFileMail answer: The user canceled one of the dialog boxes!'); end; end; end; // von sendfilemail |
AW: MAPI Mailversand mit TB und Delphi 7
Was liefert MapiSendMail denn zurück? Die Vermutung liegt nahe, dass es ein von dir nicht erwarteter Fehlercode ist. Leider ignorierst du den aber. Stattdessen solltest du dann diesen unbekannten Code auch ausgeben, wenn der Wert ungleich 0 (also Erfolg) ist. In deiner Liste fehlt z.B. noch MAPI_E_INVALID_RECIPS. GetLastError kannst du auch noch prüfen.
Da du noch Delphi 7 nutzt, nutzt du die Ansi-Variante. In der Doku steht aber eindeutig: Zitat:
|
AW: MAPI Mailversand mit TB und Delphi 7
Hallo Jaenicke,
erstmal vielen Dank, der Fehlercode ist 0 (also kein fehler IMHO)? Wie geht das denn MAPISendMailW (sorry für dumme Fragen).. Ich habe die mapi32.dll gefunden, ins Programmverzeichnis gestellt und mit
Delphi-Quellcode:
(mit mapidllname='mapi32.dll')
MapiSendMailW(0, 0, mMessage, MAPI_LOGON_UI or MAPI_NEW_SESSION, 0); external mapidllname; stdcall;
klappt das nicht (MapiSendMailW unbekannt). Bin darin offen gestanden nicht so firm. Gibts vllt noch ein andere Möglichkeit? BG Zongo |
AW: MAPI Mailversand mit TB und Delphi 7
Zitat:
Unter Windows 11 bekomme ich aber eine 1 zurück. Bist du sicher, dass das bei dir eine 0 ist? Das lag bei mir daran, dass Mapi dort standardmäßig nicht aktiviert ist. Du musst daher den Wert MAPI in der Registry als Zeichenfolge anlegen und auf 1 setzen:
Code:
Für 64-Bit Anwendungen muss der Wert entsprechend direkt unter Software statt unter WOW6432Node gesetzt werden. Daraufhin funktionierte es mit der normalen Ansiversion.
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows Messaging Subsystem
|
AW: MAPI Mailversand mit TB und Delphi 7
0:13 - WOW, vielen Dank !
also die Schlüssel HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Messaging Subsystem\MAPI="1" HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\ Windows Messaging Subsystem\MAPI="1" hatte ich schon gesetzt. Aber wie kann ich das für meine Software machen? Ich habe ja nur eine .exe die ich direkt ausführe, ohne dass eine Installation / Win-Registrierung erfolgt, wie eine portable GUI. Die hat ja keine Reg-Eintrag. Ich habe auch überöegt, ob es an der Firewall liegen kann, ich habe ja nur den normalen Windows-Defender und die Win11 Firewall, da habe ich aber nichts an Einstellungen gefunden. Dabnke & Grüße, Zongo |
AW: MAPI Mailversand mit TB und Delphi 7
Ich habe gerade mal geguckt, was ich in einem alten Delphi-7-Programm diesbezüglich drin habe, und bei mir sieht das so aus:
Ich habe folgende Variablen:
Code:
Der Aufruf sieht dann folgendermaßen aus:
SM: TFNMapiSendMail;
MAPIModule: HModule; Ergebnis : Cardinal; MapiMessage : TMapiMessage; ... ... ...
Code:
Ich kann keine Erklärungen zum Warum und Wieso abgeben, da das schon seit Ewigkeiten so ist und größtenteils ohne Probleme funktioniert hat.
MAPIModule := LoadLibrary(PChar(MAPIDLL));
if MAPIModule <> 0 then begin try @SM := GetProcAddress(MAPIModule, 'MAPISendMail'); if @SM<>nil then Ergebnis := SM(0, 0, MapiMessage, MAPI_DIALOG or MAPI_LOGON_UI, 0); ... ... ... |
AW: MAPI Mailversand mit TB und Delphi 7
Vielen Dank, aber damit wird nur eine Mail in Thunderbird geöffnet, die ich dann noch manuell abschicken muss. Könnte das an einer Einstellung im TB liegen?
Oder wisst Ihr noch eine andere Möglichkeit ausser MAPI? Ich habe jetzt das Standard-Maulprogramm in Win11 in MS-Mail geändert, aber beim MAPI Aufruf wird immer noch der TB geöffnet ... dann sollte doch MS Mail kommen? ich blicke hier echt nicht mehr durch. |
AW: MAPI Mailversand mit TB und Delphi 7
Zitat:
Ich habe dort "MAPI_DIALOG or MAPI_LOGON_UI" verwendet, weil ich an dieser Stelle eben genau will, dass der EMail-Client aufgeht und man die Mail selbst abschicken muss. Du willst die Mail direkt verschicken? Da kann ich im Bezug auf MAPI leider nicht viel zu sagen, da ich diesen Fall direkt über SMTP und IMAP umsetze. Das wäre übrigens auch eine alternative Möglichkeit. Ich bin mir nicht ganz sicher, wie das in Delphi 7 damit aussieht, aber die Indy SMTP und IMAP Komponenten kann man dafür wunderbar nehmen. |
AW: MAPI Mailversand mit TB und Delphi 7
Jetzt gehts !
Ich habe das Flag MAPI_DIALOG entfernt und er macht was er soll. Sowohl mit TB als Standard app als auch mitz Mail als Standard-APP. Keine Ahnung wieso, aber es klappt. Ich danke euch beiden ganz herzlich für eure Mühe! BG Zongo |
AW: MAPI Mailversand mit TB und Delphi 7
Zitat:
|
AW: MAPI Mailversand mit TB und Delphi 7
Zitat:
|
AW: MAPI Mailversand mit TB und Delphi 7
Per se kann IMAP empfangen, bearbeiten und auch senden.
(senden = in einen Ausgabeordner speichern, welcher anschließend vom MailServer behandelt wird) POP3 kann nur empfangen und SMTP nur senden. Wir sind inzwischen auf die Erstellung von *.eml mittels INDY umgestiegen, anschließend werden sie im StandardMail-Programm geöffnet und über ein Flag im Header (X-Unsent) wurde angegeben, dass diese Mail neu ist und somit versendet werden soll. |
AW: MAPI Mailversand mit TB und Delphi 7
Zitat:
|
AW: MAPI Mailversand mit TB und Delphi 7
Zitat:
Wir sind unter anderem auch weg von der MAPI, weil leider immer mehr Leute nicht nur den fatalen Fehler begehen, Outlook zu benutzen, sondern inzwischen auch noch dazu in diesem den Schalter des Schreckens umlegen, der auf den neuen webbasierten Outlook umschaltet, mit dem quasi nichts mehr zu machen ist. Wie macht ihr das Öffnen der EMLs? ShellExecute und Windows sich drum kümmern lassen? Mich würde nämlich mal interessieren, ob das auch mit dem neuen Outlook funktioniert, da das dann eventuell eine Option für die Leute wäre, die unbedingt ihre EMails in diesem unheiligen Programm und nirgendwo sonst erstellen wollen... |
AW: MAPI Mailversand mit TB und Delphi 7
Zitat:
![]() |
AW: MAPI Mailversand mit TB und Delphi 7
Wir hatten vor allem mit Mail-Anhängen Probleme, was in der MAPI eigentlich nicht vorgesehn ist.
Dann noch die Probleme mit MAPI-Client in 32 Bit oder 64 Bit, gegenüber Outlook in 32 oder 64 Bit. Dann halt Outlook365 oder andere Mail-Programme usw. Microsoft hat im .NET eine MAPI-Klasse für Outlook, welche super funktioniert, wofür wir uns eine .NET-Consolen-Anwendung gebastelt hatten, welche wir aufrufen, aber mit .EML läuft es aktuell am Besten. (auch wenn wir noch keinen Kontakt zum Web-Outlook hatten) |
AW: MAPI Mailversand mit TB und Delphi 7
Wie setzt man denn dieses Flag? Im Indy Quelltext und in den Beispielen habe ich das an keiner Stelle gefunden. Zudem ist die Indy Doku wirklich dünn.
|
AW: MAPI Mailversand mit TB und Delphi 7
Zitat:
Da Outlook mal wieder vor kurzem bissl was geändert hat, mußten wir bissl umbauen. Multipart-Mails mit Formatierung und Anhänge ... da hatten die was verändert und beim Laden der Mail wurden die Anhänge plötzlich ignoriert. Wir nutzen TIdMessage, um die Mail zu generieren. Als EML via ShellExecute lässt sich in der MailApp öffnen und dann senden oder sie ließe sich über TIdSMP direkt versenden.
Delphi-Quellcode:
function TCimSendMail.ExecuteWithEML: Boolean;
var _SL : TStringList; _IdMsg : TIdMessage; _Idx : Integer; _FileName : String; _Addresses : TStringList; _MsgPartBody : TIdText; _Matches : TMatchCollection; _Match : TMatch; _Group : TGroup; _IdxM : Integer; _AttLnk : TIdAttachmentFile; _Pair : TPair<String, TCimSendMail.TAttachmentLink>; _IdxRelated : Integer; _IdxAlternative : Integer; function ContentIdgenerate: String; begin Result := Format('%s%s', [IntToHex(Random(MaxInt), 4), IntToHex(Random(MaxInt), 4)]); end; procedure _LinkMsgPart(const AGroup: TGroup; const AMsgPart: TIdAttachmentFile; const ADisplayname: String); begin Self.BodyText := Copy(Self.BodyText, 1, AGroup.Index - 1) + AMsgPart.ContentID + Copy(Self.BodyText, AGroup.Index + AGroup.Length, System.MAXINT); if (not (ADisplayname = '')) then AMsgPart.Name := ADisplayname; end; begin // Compose Email mittels Indy _IdMsg := TIdMessage.Create(nil); _IdMsg.Subject := Subject; _Addresses := TStringList.Create; try ExtractList(MailTo, _Addresses, [',', ';'], False, False); for _Idx := 0 to _Addresses.Count - 1 do begin if Pos(' ', _Addresses[_Idx]) > 0 then raise Exception.Create(makeText(13207) // "EMail-Adresse darf keine Leerzeichen enthalten. Bitte prüfen Sie die Stammdaten der Adresse oder des Ansprechpartners." + slinebreak + 'Email: "' + _Addresses[_Idx] + '"'); _IdMsg.Recipients.Add.Address := Trim(_Addresses[_Idx]); end; // for linked message-parts (within the email) we need it set to mixed/related !!! // this will then clash with attachments, which are not related // https://redmine.prodat-sql.de/issues/22117 // https://borland.public.delphi.internet.winsock.narkive.com/26JN1s0l/tidmessage-nested-parts _IdMsg.ContentType := 'multipart/mixed; charset=UTF-8;'; _SL := TStringList.Create; try // this allows to prepare the linked attachments: TFormDokments._PrepareCimEmailLinkedAttachments if (Assigned(FOnBeforeEMLAddAttachments)) then FOnBeforeEMLAddAttachments(Self); with TIdText.Create(_IdMsg.MessageParts, NIL) do begin ContentType := 'multipart/alternative'; _IdxAlternative := Index; end; _SL.Add(BodyText); with TIdText.Create(_IdMsg.MessageParts, _SL) do begin ContentType := 'text/plain'; ParentPart := _IdxAlternative; end; _SL.Clear; // Zeilenumbrueche mit HTML Tags ersetzen BodyText := StringReplace(BodyText, sLineBreak, '<br />', [rfReplaceAll, rfIgnoreCase]); BodyText := StringReplace(BodyText, #$A, '<br />', [rfReplaceAll, rfIgnoreCase]); with TIdText.Create(_IdMsg.MessageParts, NIL) do begin ContentType := 'multipart/related; type="text/html"'; ParentPart := _IdxAlternative; _IdxRelated := Index; end; _MsgPartBody := TIdText.Create(_IdMsg.MessageParts, NIL); _MsgPartBody.ContentType := 'text/html'; _MsgPartBody.CharSet := 'UTF-8'; _MsgPartBody.ParentPart := _IdxRelated; // replace the src="cid:" with the correct cid's inside the emailbody of the lniked attachment for _Pair in AttachmentsLinked do begin _AttLnk := TIdAttachmentFile.Create(_IdMsg.MessageParts, _Pair.Value.SourceFilename); _AttLnk.ContentID := Format('%d_attlnk_%s', [_Idx, ContentIdgenerate]); _AttLnk.ParentPart := _IdxRelated; // we need to actually call it for each Pair !!! _Matches := TRegEx.Matches(BodyText, CATTLNK_REGEX, [roIgnoreCase]); try for _IdxM := _Matches.Count - 1 downto 0 do begin _Match := _Matches.Item[_IdxM]; _Group := _Match.Groups.Item[CATTLNK_LINK]; if ((_Match.Groups.Count = CATTLNK_GRPCNT) and _Group.Success and _Match.Groups.Item[CATTLNK_TYPE].Success) then begin // even if a MDS-Link and a File-Link are present, which point to the same sourcefile // there can be only one entry in Self.AttachmentsLinked for both // thats why we do a string check again instead of TAttachmentLinkSource // see TCimSendMail.AddAttachmentLinked if (SameText(CATTLNK_TYPE_DMS, _Match.Groups.Item[CATTLNK_TYPE].Value)) then begin if (SameText(_Pair.Value.ID, _Match.Groups.Item[CATTLNK_ID].Value)) then _LinkMsgPart(_Group, _AttLnk, _Pair.Value.DisplayFilename); end else if (SameText(CATTLNK_TYPE_FILE, _Match.Groups.Item[CATTLNK_TYPE].Value)) then begin if (SameText(_Pair.Value.SourceFilename, _Match.Groups.Item[CATTLNK_ID].Value)) then _LinkMsgPart(_Group, _AttLnk, _Pair.Value.DisplayFilename); end; end; end; finally Finalize(_Matches); end; end; CheckWarnLinkedAttachments(True); _SL.Add('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">'); _SL.Add('<meta http-equiv="Content-Type" content="text/html; charset="UTF-8" />'); _SL.Add('<html><head>'); _SL.Add(Format('<title>%s</title>', ['Title'])); _SL.Add('</head><body>'); _SL.Add(Format('<div>%s</div>', [BodyText])); _SL.Add('</body></html>'); // assign the message text _MsgPartBody.Body := _SL; for _Idx := 0 to Length(Attachments) - 1 do begin with TIdAttachmentFile.Create(_IdMsg.MessageParts, Attachments[_Idx]) do ContentID := Format('%d_attach_%s', [_Idx, ContentIdgenerate]); end; finally FreeAndNIL(_SL); end; // Wichtig ist dabei einzig und allein der X-Header (damit es als eine neue, zu sendende EMail verarbeitet wird): X-Unset _IdMsg.Headers.Add('X-Unsent: 1'); // Save to file _FileName := Format('%s\%s.eml', [CurrentSession_UConstants.Path_MailTemp, ContentIdgenerate]); ForceDirectories(ExtractFilePath(_FileName)); _IdMsg.SaveToFile(_FileName); // Mark file for delete on reboot/logout DeleteFileOnShutdown(_FileName); try // 'Open' file -> Default Email Client will open DoExecute(0, _FileName, '', 'open', False); Result := True; except on E: Exception do RaiseError(E.Message); end; finally _Addresses.Free; _IdMsg.Free; end end; |
AW: MAPI Mailversand mit TB und Delphi 7
Danke! Ich werds damit mal probieren. Ich mache das bislang auch per (Simple-)MAPI, und da gehen einige Dinge nicht mehr so gut.
Nachtrag: scheint gut zu funktionieren. Für den Text samt Anhängen verwende ich IdMessageBuilder, wie hier ( ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:33 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz