2015-04-14 1 views
0

Я создаю 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; 
+0

Возможно, ваши записи неверно переведены. Мы не можем их видеть. Ваше использование 'StrNew' неверно. Он просачивается. Создайте 'TList ' для хранения значений строк temp, которые вы можете использовать с помощью 'PAnsiChar'. Уничтожьте список в блоке finally, чтобы привести в порядок. –

+1

Это код, который может быть хорошим или плохим, что зависит от кода, который мы не видим. Если у вас есть проблема, вы не можете опубликовать даже свою, возможно, рабочую оболочку MAPI, никто не сможет вам помочь. –

+0

@ Дэвид Хеффернан - не знаете, что вы подразумеваете под неправильно переведенными записями? Нет записей. Я посмотрю бит 'StrNew', как вы предлагаете. –

ответ

0

Вполне возможно, что MAPISendMail (A) не поддерживается интерфейс на Windows 8 64 бит:

https://msdn.microsoft.com/is-is/library/dd296721.aspx предлагает использовать интерфейс Wide Character.

Возможно также, что MAPISendMail не является поддерживаемым интерфейсом для 64-битной версии Outlook 2013: он некоторое время амортизируется. Я не могу использовать этот интерфейс в Outlook 2013/64, но есть (как всегда с MAPI) усложняющие факторы.