Я создаю 64-битное приложение Delphi XE2 для обработки отправки MAPI-почты через Outlook. Это предназначено для 64-битных установок Outlook 2010, 2013 и т. Д., Потому что вы не можете вызывать 64-битный MAPI из 32-разрядного приложения.Вызов электронной почты MAPI из 64-разрядного приложения Delphi не работает, когда работает тот же код для 32-битного приложения Delphi?
У меня есть код Delphi, который отлично работает с 32-разрядными версиями клиентов Outlook при компиляции в виде 32-битного приложения. 32-разрядные приложения работают на Win7 64.
Код всегда с кодом ошибки MAPI_E_FAILURE равен 2, если тот же код перекомпилирован в 64-разрядное приложение. 64-разрядное приложение работает на Win 8 с установленным 64-битным клиентом Outlook 2013.
Любые идеи, почему 64-разрядное приложение не удается? Я делаю или не делаю что-то очевидное в отношении 64-битного кода?
Приветствия! TJ
Вот код:
function SendEMailByMAPI(SenderName, SenderAddress, Subject, Body: Ansistring; Recipients, Attachments: TStringList): Integer;
var i: Integer;
var EmailMessage: TMapiMessage;
var lpSender: TMapiRecipDesc;
var MAPI_Session : Cardinal;
var RecipientArray : array of TMapiRecipDesc;
var AttachmentsArray : array of TMapiFileDesc;
begin
FillChar(EmailMessage, SizeOf(EmailMessage), 0);
//add sender address if not blank.
if (SenderAddress <> '') then begin
lpSender.ulRecipClass := MAPI_ORIG;
if (SenderName <> '') then begin
lpSender.lpszName := PAnsiChar(SenderAddress);
end
else begin
lpSender.lpszName := PAnsiChar(SenderName);
end;
lpSender.lpszAddress := PAnsiChar(SenderAddress);
lpSender.ulReserved := 0;
lpSender.ulEIDSize := 0;
lpSender.lpEntryID := nil;
EmailMessage.lpOriginator := @lpSender;
end;
EmailMessage.lpszSubject := PAnsiChar(Subject);
EmailMessage.lpszNoteText := PAnsiChar(Body);
EmailMessage.nFileCount := Attachments.Count;
SetLength(AttachmentsArray, Attachments.Count);
//Loop and add file path and name
for i := 0 to Attachments.Count-1 do begin
AttachmentsArray[i].nPosition := Cardinal(-1);
AttachmentsArray[i].lpszPathName := PAnsiChar(AnsiString(Attachments[i]));
AttachmentsArray[i].lpszFileName := PAnsiChar(AnsiString(ExtractFileName(Attachments[i])));
end;
if EmailMessage.nFileCount > 0 then begin
EmailMessage.lpFiles := Pointer(AttachmentsArray);
end
else begin
EmailMessage.lpFiles := nil;
end;
SetLength(RecipientArray, Recipients.Count);
for i := 0 to Recipients.Count-1 do begin
RecipientArray[i].ulReserved := 0;
RecipientArray[i].ulRecipClass := MAPI_TO;
RecipientArray[i].lpszName := StrNew(PAnsiChar(AnsiString(Recipients[i])));
RecipientArray[i].lpszAddress := StrNew(PAnsiChar('SMTP:' + AnsiString(Recipients[i])));
RecipientArray[i].lpEntryID := nil;
RecipientArray[i].ulEIDSize := 0;
end;
EmailMessage.nRecipCount := Recipients.Count;
EmailMessage.lpRecips := Pointer(RecipientArray);
//Send the message
Result:= MapiLogon(Application.Handle, PAnsiChar(''), PAnsiChar(''), MAPI_LOGON_UI or MAPI_NEW_SESSION, 0, @MAPI_Session);
if (Result = SUCCESS_SUCCESS) then begin
ShowMessage('Before calling MAPISendMail');//used as a timing device to see how long it takes for Outlook to respond to request and show email dialog
Result := MAPISendMail(MAPI_Session, Application.Handle, EmailMessage, MAPI_DIALOG or MAPI_LOGON_UI , 0);
if Result <> 0 then begin
case result of
MAPI_E_AMBIGUOUS_RECIPIENT : ShowMessage('Receiver is not unique.');
MAPI_E_ATTACHMENT_NOT_FOUND : ShowMessage('File for appending not found');
MAPI_E_ATTACHMENT_OPEN_FAILURE : ShowMessage('File could not be opened for appending.');
MAPI_E_BAD_RECIPTYPE : ShowMessage('Type of receiver not MAPI_TO, MAPI_CC or MAPI_BCC.');
MAPI_E_FAILURE : ShowMessage('Unknown Error.');
MAPI_E_INSUFFICIENT_MEMORY : ShowMessage('Not enough memory.');
MAPI_E_LOGIN_FAILURE : ShowMessage('User Login failed.');
MAPI_E_TEXT_TOO_LARGE : ShowMessage('Text too large.');
MAPI_E_TOO_MANY_FILES : ShowMessage('Too many file attachments.');
MAPI_E_TOO_MANY_RECIPIENTS : ShowMessage('Too many recipients specified.');
MAPI_E_UNKNOWN_RECIPIENT : ShowMessage('Receiver not found in the address book.');
MAPI_E_USER_ABORT : ShowMessage('User canceled or MAPI Send not installed.');
else
ShowMessage('Error sending email. Error code: ' + inttostr(Result));
end;
end;
end
else begin
ShowMessage('Failure to get MAPI call handle: ' + inttostr(Result));
end;
end;
Эта функция вызывается таким образом:
procedure TForm1.ButtonClick(Sender: TObject);
var SenderName: Ansistring;
var SenderAddress: Ansistring;
var Subject: Ansistring;
var Body: Ansistring;
var Recipients: TStringList;
var Attachments: TStringList;
begin
Recipients := TStringList.Create;
Attachments := TStringList.Create;
Recipients.Add('[email protected]');
Attachments.Add('c:\temp\test.xlsx');
SenderName := 'TJ Asher';
SenderAddress := '[email protected]';
Subject := 'email test 64 bit subject';
Body := 'Email test 64 bit body';
SendEMailByMAPI(SenderName, SenderAddress, Subject, Body, Recipients, Attachments);
end;
Возможно, ваши записи неверно переведены. Мы не можем их видеть. Ваше использование 'StrNew' неверно. Он просачивается. Создайте 'TList' для хранения значений строк temp, которые вы можете использовать с помощью 'PAnsiChar'. Уничтожьте список в блоке finally, чтобы привести в порядок. –
Это код, который может быть хорошим или плохим, что зависит от кода, который мы не видим. Если у вас есть проблема, вы не можете опубликовать даже свою, возможно, рабочую оболочку MAPI, никто не сможет вам помочь. –
@ Дэвид Хеффернан - не знаете, что вы подразумеваете под неправильно переведенными записями? Нет записей. Я посмотрю бит 'StrNew', как вы предлагаете. –