Как отправить письмо MAPI с приложением получателю факса? - PullRequest
2 голосов
/ 05 августа 2009

Я использую этот метод для отправки электронного письма MAPI с вложением в формате PDF из приложения Delphi.

Вызывается окно «Новое сообщение» в MS Outlook с уже прикрепленным документом в формате PDF и пустым получателем.

Если вы наберете обычный почтовый контакт, он пройдет нормально.

Однако, если вы выберете получателя факса, он появится в моей папке «Отправленные», но доставка не будет выполнена автоматически (без ошибок, нет сообщения «Не удалось доставить» в MS Outlook и нет доставки сообщения).

«Получатель факса» настроен в MS Outlook только с номером факса. Нет электронной почты или что-нибудь. Мы используем факс-сервер для маршрутизации этих «факсов» в папку «Входящие» Outlook.

Если вы посмотрите на это изображение , единственное поле, которое я заполнил для этого контакта, это поле с пометкой "Бизнес-факс".

Если я вручную (т.е. вне своего приложения) создаю стандартную электронную почту MS Outlook и выбираю того же получателя факса, а затем вручную присоединяю тот же PDF-файл, то все проходит нормально.

Похоже, что что-то в использовании MAPI для отправки на номер факса приводит к сбою. Это сообщение звучит похоже, за исключением того, что они получают сообщение "сообщение не доставлено", а я нет.

Кто-нибудь может дать мне несколько советов по этому поводу?

Спасибо

Обновление: Если я использую MAPI для создания электронного письма, но затем я вручную удаляю вложение, тогда оно работает . Таким образом, из перспективы я могу отправить вложение в приложение получателю факса, но с помощью MAPI это не удается.

Полный исходный код выглядит следующим образом:

unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    function SendEMailUsingMAPI(const Subject, Body, FileName, SenderName,
      SenderEMail, RecipientName, RecipientEMail: string): integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses
  Mapi;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //this will bring up an MS Outlook dialog.
  //inside that dialog, if i choose a normal email recipient, it works.
  //                    if i choose a fax recipient, it fails silently.
  //if i create the email from w/in outlook, it can go to *either* with success.

  SendEmailUsingMAPI(
    'Subject',  //subject of email
    'Body',  //body of email text
    'c:\my_doc.pdf',  //attachment file name
    'My name',  //sender email name
    'myemail@mydomain.com',  //sender email address
    '',  //recipient email name
    '');  //recipient email address
end;


function TForm1.SendEMailUsingMAPI(const Subject, Body, FileName, SenderName,
  SenderEMail, RecipientName, RecipientEMail: string): Integer;
var
  Message: TMapiMessage;
  lpSender, lpRecipient: TMapiRecipDesc;
  FileAttach: TMapiFileDesc;
  SM: TFNMapiSendMail;
  MAPIModule: HModule;
  FileType: TMapiFileTagExt;
begin
  FillChar(Message,SizeOf(Message),0);

  if (Subject <> '') then begin
    Message.lpszSubject := PChar(Subject);
  end;

  if (Body <> '') then begin
    Message.lpszNoteText := PChar(Body);
  end;

  if (SenderEmail <> '') then
  begin
    lpSender.ulRecipClass := MAPI_ORIG;
    if (SenderName = '') then begin
      lpSender.lpszName := PChar(SenderEMail);
    end
    else begin
      lpSender.lpszName := PChar(SenderName);
    end;
    lpSender.lpszAddress := PChar(SenderEmail);
    lpSender.ulReserved := 0;
    lpSender.ulEIDSize := 0;
    lpSender.lpEntryID := nil;
    Message.lpOriginator := @lpSender;
  end;

  if (RecipientEmail <> '') then begin
    lpRecipient.ulRecipClass := MAPI_TO;
    if (RecipientName = '') then begin
      lpRecipient.lpszName := PChar(RecipientEMail);
    end
    else begin
      lpRecipient.lpszName := PChar(RecipientName);
    end;
    lpRecipient.lpszAddress := PChar(RecipientEmail);
    lpRecipient.ulReserved := 0;
    lpRecipient.ulEIDSize := 0;
    lpRecipient.lpEntryID := nil;
    Message.nRecipCount := 1;
    Message.lpRecips := @lpRecipient;
  end
  else begin
    Message.lpRecips := nil;
  end;

  if (FileName = '') then begin
    Message.nFileCount := 0;
    Message.lpFiles := nil;
  end
  else begin
    FillChar(FileAttach,SizeOf(FileAttach),0);
    FileAttach.nPosition := Cardinal($FFFFFFFF);
    FileAttach.lpszPathName := PChar(FileName);

    FileType.ulReserved := 0;
    FileType.cbEncoding := 0;
    FileType.cbTag := 0;
    FileType.lpTag := nil;
    FileType.lpEncoding := nil;

    FileAttach.lpFileType := @FileType;
    Message.nFileCount := 1;
    Message.lpFiles := @FileAttach;
  end;

  MAPIModule := LoadLibrary(PChar(MAPIDLL));

  if MAPIModule = 0 then begin
    Result := -1;
  end
  else begin
    try
      @SM := GetProcAddress(MAPIModule,'MAPISendMail');
      if @SM <> nil then begin
        Result := SM(0,Application.Handle,Message,
          MAPI_DIALOG or MAPI_LOGON_UI,0);
      end
      else begin
        Result := 1;
      end;
    finally
      FreeLibrary(MAPIModule);
    end;
  end;

  if Result <> 0 then begin
    MessageDlg('Error sending mail ('+IntToStr(Result)+').',mtError,[mbOK],0);
  end;
end;

end.

Ответы [ 3 ]

2 голосов
/ 06 августа 2009

Хорошо, ваше обновление указывает на вложение, поэтому я собираюсь сформулировать еще одно предположение: попробуйте явно указать тип файла вложения «application / pdf» (ваш текущий код не устанавливает поле lpFileType). Обработка факсов может зависеть от этого. Вы можете просто оставить части кодирования MapiFileTagExt (на которые указывает тип lpFileType) пустыми, просто FillChar записи и установить поля cbTag и lpTag.

Если вам нужен код (структуры mapi иногда могут быть немного ослепительными), просто кричите, но мне понадобится некоторое время, чтобы найти момент, чтобы напечатать его ... И в любом случае, опять же, я просто догадываюсь , У меня нет настройки факса в моей домашней обстановке, в противном случае я бы провел некоторое правильное тестирование.

EDIT

Ниже приведен фрагмент кода. Однако с тех пор я проверил с помощью Outlook Spy, и ни с помощью метода, ни при присоединении файла вручную свойство PR_ATTACH_MIME_TAG, похоже, устанавливается для отправленного элемента, только для получающегося входящего сообщения.

  FillChar(FileAttach,SizeOf(FileAttach),0);
  FileAttach.nPosition := Cardinal($FFFFFFFF);
  FileAttach.lpszPathName := PChar(FileName);
  //
  MimeType := 'application/pdf'; 
  //
  FileType.ulReserved := 0;
  FileType.cbTag := Length( MimeType );
  FileType.lpTag := PByte(MimeType);
  FileType.cbEncoding := 0;
  FileType.lpEncoding := nil;
  //
  FileAttach.lpFileType := @FileType;
  Message.nFileCount := 1;
  Message.lpFiles := @FileAttach;

(средство форматирования кода не особо помогает).

1 голос
/ 06 августа 2009

Вы можете попробовать включить Ведение журнала транспорта Outlook , возможно, там появится какое-либо (любое) сообщение об ошибке. Обязательно сначала зарегистрируйте факс (рабочая ситуация) вручную, чтобы проверить, действительно ли что-либо связанное действительно отображается в этом журнале.

К сожалению, мой личный успех в решении проблем с помощью этого журнала - ноль, но попытки получить больше информации никогда не повреждают, верно?

1 голос
/ 06 августа 2009

Может быть, адреса факсов недоступны в 0 (временном) сеансе? Другими словами, выполняет ли вход в сеанс сначала MAPILogon, а затем предоставляет hSession в справке вызова MAPISendMail?

...